Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/usmpgames
diff options
context:
space:
mode:
authorMateu Batle <mateu.batle@collabora.co.uk>2010-10-27 17:40:28 (GMT)
committer Mateu Batle <mateu.batle@collabora.co.uk>2010-10-27 17:40:28 (GMT)
commit0018a9e211ebbe74d371339a70edc0d36c4fc99f (patch)
treeddfd93d0713c615ed70dbf869747b55b94791af8 /usmpgames
Initial import of game1 and game2 in math quwy
Diffstat (limited to 'usmpgames')
-rwxr-xr-xusmpgames/__init__.py4
-rwxr-xr-xusmpgames/application.py129
-rwxr-xr-xusmpgames/applicationstate.py72
-rwxr-xr-xusmpgames/infostate.py58
-rwxr-xr-xusmpgames/jmenu.py87
-rwxr-xr-xusmpgames/menustate.py45
-rwxr-xr-xusmpgames/txtlib.py291
7 files changed, 686 insertions, 0 deletions
diff --git a/usmpgames/__init__.py b/usmpgames/__init__.py
new file mode 100755
index 0000000..006d880
--- /dev/null
+++ b/usmpgames/__init__.py
@@ -0,0 +1,4 @@
+from application import *
+from applicationstate import *
+from menustate import *
+from infostate import *
diff --git a/usmpgames/application.py b/usmpgames/application.py
new file mode 100755
index 0000000..cd6b863
--- /dev/null
+++ b/usmpgames/application.py
@@ -0,0 +1,129 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
+import sys
+import pygame
+
+class Application():
+
+ _instance = None
+
+ @staticmethod
+ def instance():
+ return Application._instance
+
+ def __init__(self):
+ self._state_stack = []
+ self._current_state = None
+ self._running = True
+ self._fps = 25
+ if Application._instance is None:
+ Application._instance = self
+
+ def set_screen(self, screen):
+ self._screen = screen
+
+ def screen(self):
+ return self._screen
+
+ def push_state(self, new_state):
+ # exit from current state
+ if self._current_state is not None:
+ self._current_state.exiting_state( True )
+ if new_state is not None:
+ self._state_stack.append(self._current_state)
+
+ # process new state
+ fromStack = False
+ if new_state is None:
+ if len(self._state_stack) == 0 :
+ self.set_running( False )
+ return
+ else :
+ self._current_state = self.pop_state()
+ fromStack = True
+ else:
+ self._current_state = new_state
+
+ # entering new state
+ if self._current_state is None:
+ self.set_running(False)
+ else:
+ self._current_state.set_screen(self.screen())
+ self._current_state.entering_state(fromStack)
+
+ def change_state(self, new_state):
+ # exit from current state
+ if self._current_state is not None:
+ self._current_state.exiting_state(False)
+
+ # process current state
+ if new_state is None:
+ if len(self._state_stack) == 0 :
+ self.set_running( False )
+ return
+ else :
+ self.pop_state()
+ return
+ else:
+ self._current_state = new_state
+
+ # entering new state
+ if self._current_state is not None:
+ self._current_state.set_screen(self.screen())
+ self._current_state.entering_state( False )
+ else:
+ self.set_running(False)
+
+ # entering new state
+
+ def pop_state(self):
+ if self._current_state is not None:
+ self._current_state.exiting_state( False )
+ if len(self._state_stack) >= 1:
+ self._current_state = self._state_stack.pop()
+ else:
+ self._current_state = None
+ if self._current_state is not None:
+ self._current_state.set_screen(self.screen())
+ self._current_state.entering_state( True )
+
+ def current_state(self):
+ return self._current_state
+
+ def running(self):
+ if not self._running:
+ return False
+ if self.current_state() is None:
+ return False
+ state_running = self.current_state().running()
+ if not state_running:
+ self.pop_state()
+ return self.running()
+ return True
+
+ def set_running(self, new_value):
+ self._running = new_value
+
+ def set_fps(self, new_value):
+ self._fps = new_value
+
+ def fps(self):
+ return self._fps
+
+ def initialize(self):
+ pygame.init()
+
+ def shutdown(self):
+ pygame.quit()
+
+ def runLoop(self):
+ self.initialize()
+ clock = pygame.time.Clock()
+ while self.running() :
+ ms = clock.tick( self.fps() )
+ #try:
+ self.current_state().loop(ms)
+ #except:
+ # print "Unexpected error:", sys.exc_info()[0]
+ self.shutdown()
diff --git a/usmpgames/applicationstate.py b/usmpgames/applicationstate.py
new file mode 100755
index 0000000..fc5ca72
--- /dev/null
+++ b/usmpgames/applicationstate.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
+import pygame
+from application import *
+
+class ApplicationState():
+
+ def __init__(self, next_state = None, background = None):
+ self._running = True
+ self._screen = None
+ self._next_state = next_state
+ self._background = background
+
+ def input(self, ms):
+ pass
+
+ def simulation(self, ms):
+ pass
+
+ def pre_render(self, ms):
+ if self.background() is not None and self.screen() is not None :
+ self.screen().blit( self.background(), (0, 0) )
+
+ def render(self, ms):
+ pass
+
+ def post_render(self, ms):
+ pygame.display.flip()
+
+ def set_background(self, background):
+ self._background = background
+
+ def background(self):
+ if self._background is not None:
+ return self._background
+ return None
+
+ def set_running(self, newValue):
+ self._running = newValue
+
+ def running(self):
+ return self._running
+
+ def set_screen(self, screen):
+ self._screen = screen
+
+ def screen(self):
+ return self._screen
+
+ def loop(self, ms):
+ self.input(ms)
+ self.simulation(ms)
+ self.pre_render(ms)
+ self.render(ms)
+ self.post_render(ms)
+
+ def entering_state(self, fromStack):
+ print "Entering state ", self
+ self.set_running(True)
+ pass
+
+ def exiting_state(self, toStack):
+ print "Exiting state ", self
+ pass
+
+ def go_to_next_state(self):
+ Application.instance().change_state( self._next_state )
+
+ def next_state(self):
+ return self._next_state
+
diff --git a/usmpgames/infostate.py b/usmpgames/infostate.py
new file mode 100755
index 0000000..3edfc66
--- /dev/null
+++ b/usmpgames/infostate.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
+import pygame
+import jmenu
+import sys
+import txtlib
+from applicationstate import *
+from application import *
+
+class InfoState(ApplicationState):
+
+ def __init__(self, next_state, background = None):
+ ApplicationState.__init__(self, next_state, background)
+ self._images = []
+
+ def clear_all(self):
+ self._images = []
+
+ def add_text(self, text, color, pos, rectsize, fontsize, font = None):
+ textobj = txtlib.Text(rectsize, font, fontsize, text)
+ textobj.background_color = (255, 255, 255, 0)
+ textobj.update()
+ self.add_image( textobj.area, pos )
+
+ def add_htmltext(self, html_text, color, pos, rectsize, fontsize, font = None):
+ textobj = txtlib.Text(rectsize, font, fontsize)
+ textobj.background_color = (255, 255, 255, 0)
+ textobj.html(html_text)
+ textobj.update()
+ self.add_image( textobj.area, pos )
+
+ def add_image(self, surface, pos):
+ info = {}
+ info["surface"] = surface
+ info["pos"] = pos
+ self._images.append(info)
+
+ def input(self, ms):
+ events = pygame.event.get()
+ if events:
+ for event in events:
+ if event.type == pygame.QUIT:
+ self.set_running( False )
+ elif event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_ESCAPE:
+ self.set_running( False )
+ else:
+ self.go_to_next_state()
+
+ def render(self, ms):
+ for info in self._images:
+ self.screen().blit(info["surface"], info["pos"])
+
+ def entering_state(self, fromStack):
+ ApplicationState.entering_state(self, fromStack)
+ pygame.time.wait(500)
+ pygame.event.clear()
diff --git a/usmpgames/jmenu.py b/usmpgames/jmenu.py
new file mode 100755
index 0000000..873d472
--- /dev/null
+++ b/usmpgames/jmenu.py
@@ -0,0 +1,87 @@
+import pygame as pg
+pg.init()
+
+class jmenu:
+ ''
+ coef = 1.5
+ default_font = pg.font.get_default_font()
+ bip = pg.mixer.Sound('./data/sounds/KDE_TypeWriter_Key_1.ogg')
+ select = pg.mixer.Sound('./data/sounds/KDE_Dialog_Disappear.ogg')
+
+def run(menu,color,size,COLOR=None,font=None,interline=0,SIZE=None,light=5,justify=True,pos=('center','center')):
+ "jmenu.run(menu=list,color=(r,g,b),size=int[[[[[[[COLOR=(r,g,b)],font=font_path],interline=real],SIZE=int],light=int],justify=bool],pos]) : return str\n\
+ menu = liste de str, ex: ['choix1','choix2','choix3']\n\
+ light est un reel dans l'intreval -10/+10\n\
+ si COLOR est defini, light est ignore\n\
+ pos=('left'|'cenetr'|'right'|int,'top'|'center'|'bottom'|int)\n\
+ return str de menu"
+
+ screen = pg.display.get_surface()
+ bg = screen.copy()
+ mouse_rect = pg.Rect((0,0),(1,1))
+ if font==None : font = jmenu.default_font
+ font1 = pg.font.Font(font,size)
+ size = font1.get_height()
+ font2 = pg.font.Font(font,SIZE if SIZE!=None else int(size*jmenu.coef))
+ SIZE = font2.get_height()
+ scr_w,scr_h = screen.get_size()
+ H = font1.get_height()+interline
+ if COLOR==None : COLOR = map(lambda x:x+((255-x if light>0 else x)*light/10),color)
+ surfs = []
+ rects = []
+ RECTS = []
+ for c in range(len(menu)):
+ surfs.append((font1.render(menu[c],1,color),font2.render(menu[c],1,COLOR)))
+ (w0,h0),(w1,h1) = surfs[c][0].get_size(),surfs[c][1].get_size()
+ rects.append(surfs[c][0].get_rect().move(-w0/2 if justify else 0,c*H))
+ RECTS.append(rects[c].inflate(w1-w0,h1-h0)) if justify else RECTS.append(rects[c].inflate(w1-w0,h1-h0).move((w1-w0)/2,0))
+ menu_rect = RECTS[0].unionall(RECTS) if SIZE > size else rects[0].unionall(rects)
+ X = {'left':0,'center':(scr_w-menu_rect.width)/2,'right':scr_w-menu_rect.width}
+ Y = {'top':0,'center':(scr_h-menu_rect.height)/2,'bottom':scr_h-menu_rect.height}
+ x = (X[pos[0]] if type(pos[0])==str else pos[0])-menu_rect.x
+ y = (Y[pos[1]] if type(pos[1])==str else pos[1])-menu_rect.y
+ for c in rects+RECTS: c.move_ip(x,y)
+ item = 0
+
+ def update():
+ screen.blit(bg,(0,0))
+ for c in range(len(menu)):
+ if c!=item :
+ screen.blit(surfs[c][0],rects[c].topleft)
+ #pg.draw.rect(screen,(255,0,0),rects[c],1)#decommenter pour reglage
+ screen.blit(surfs[item][1],RECTS[item].topleft)
+ #pg.draw.rect(screen,(0,0,255),RECTS[item],1)#decommenter pour reglage
+ pg.display.flip()
+
+ update()
+ while True:
+ e = pg.event.wait()
+ mouse = mouse_rect.move(pg.mouse.get_pos())
+ key = pg.key.get_pressed()
+ xx = [RECTS[item]]+rects
+ if e.type == pg.MOUSEMOTION or (e.type == pg.MOUSEBUTTONDOWN and e.button == 1):
+ j = mouse.collidelist(xx)
+ if j>0:
+ item = j-1
+ jmenu.bip.play()
+ update()
+ elif e.type == pg.MOUSEBUTTONUP and e.button == 1 and mouse.collidelist(xx)==0: break
+ elif (key[pg.K_RETURN] or key[pg.K_KP_ENTER]) and item>-1 : break
+ elif key[pg.K_DOWN] or key[ord('s')] or key[ord('d')] or key[pg.K_RIGHT]:
+ item+=1;item=item%len(menu)
+ jmenu.bip.play()
+ update()
+ elif key[pg.K_UP] or key[ord('w')] or key[ord('a')] or key[pg.K_LEFT]:
+ item = len(menu)-1 if not item else item-1
+ jmenu.bip.play()
+ update()
+ elif e.type == pg.QUIT or key[pg.K_ESCAPE]:
+ pg.event.post(pg.event.Event(pg.QUIT,{}))
+ screen.blit(bg,(0,0))
+ pg.display.flip()
+ return None
+ screen.blit(bg,(0,0))
+ jmenu.select.play()
+ pg.display.flip()
+ return menu[item]
+
diff --git a/usmpgames/menustate.py b/usmpgames/menustate.py
new file mode 100755
index 0000000..325e4a4
--- /dev/null
+++ b/usmpgames/menustate.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+import pygame, jmenu, sys
+from applicationstate import *
+from application import *
+from infostate import *
+
+class MenuState(InfoState):
+
+ def __init__(self, background = None):
+ InfoState.__init__(self, None, background)
+ self._menu_options = []
+ self._menu_states = []
+ self.pos = ('center', 'center')
+ self.font = None
+ self.light = 10
+ self.fontSize = 32
+ self.color = (0, 0, 0)
+ self.justify = True
+
+ def add_menu_option(self, option, state):
+ self._menu_options.append( option )
+ self._menu_states.append( state )
+
+ def render(self, ms):
+ InfoState.render(self, ms)
+ selection = jmenu.run(
+ self._menu_options,
+ color = self.color,
+ size = self.fontSize,
+ font = self.font,
+ light = self.light,
+ justify = self.justify,
+ pos = self.pos)
+ try:
+ index = self._menu_options.index( selection )
+ Application.instance().push_state( self._menu_states[index] )
+ except:
+ Application.instance().pop_state()
+
+ def input(self, ms):
+ pass
+
+ def entering_state(self, fromStack):
+ ApplicationState.entering_state(self, fromStack)
diff --git a/usmpgames/txtlib.py b/usmpgames/txtlib.py
new file mode 100755
index 0000000..ffacb45
--- /dev/null
+++ b/usmpgames/txtlib.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import pygame
+
+BOLD = 'bold'
+ITALIC = 'italic'
+UNDERLINE = 'underline'
+SIZE = 'size'
+FONT = 'font'
+COLOR = 'color'
+
+BEGIN = 'begin'
+END = 'end'
+
+class Point:
+
+ def __init__(self, classe, pos, type, attr=None):
+ self.pos = pos
+ self.classe = classe
+ self.type = type
+ self.attr = attr
+
+
+class Text:
+
+ def __init__(self, size, font, font_size=16, text=''):
+ self.rect = pygame.Rect((0, 0), size)
+ self.area = pygame.Surface(size, pygame.SRCALPHA | pygame.HWSURFACE)
+ self.background_color = (255, 255, 255)
+
+ self.text = text
+ self.points = []
+
+ self.text_start = 0
+ self.line_numbers = False # XXX doesn't work yet
+ self.antialias = True
+ self.border = 5
+
+ self.default_size = font_size
+ self.default_font = font
+ self.default_color = (0, 0, 0)
+ self.fonts = {}
+ self.load_font(font, font_size)
+
+ def clear(self):
+ self.text = ''
+
+ # this transform markup text in html style in txtlib style
+ def html(self, code):
+ code = str(code)
+ processing = False
+ if code.find('<'):
+ text = ''
+ txt_id = 0
+ for id in range(len(code)):
+ if code[id] not in ('<', '>') and not processing:
+ text += code[id]
+ txt_id += 1
+ elif code[id] == '>':
+ processing = False
+ elif code[id] == '<':
+ processing = True
+ if code[id+1] != '/':
+ if code[id+1].lower() == 'b':
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, BOLD))
+ elif code[id+1].lower() == 'i':
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, ITALIC))
+ elif code[id+1].lower() == 'u':
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, UNDERLINE))
+ else:
+ end = code[id:].lower().find('>') + id
+ if code[id:end].find('color') != -1:
+ print code[id+8:end-1]
+ rgb = code[id+8:end-1].replace(' ', '')
+ r, g, b = rgb.split(',')
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, COLOR, (int(r), int(g), int(b))))
+ elif code[id:end].lower().find('size') != -1:
+ size = int(code[id+7:end-1])
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, SIZE, size))
+ elif code[id:end].lower().find('font') != -1:
+ font = code[id+7:end-1]
+ self.points.append(Point(BEGIN, len(self.text)+txt_id, FONT, font))
+ else:
+ if code[id+2].lower() == 'b':
+ self.points.append(Point(END, len(self.text)+txt_id, BOLD))
+ elif code[id+2].lower() == 'i':
+ self.points.append(Point(END, len(self.text)+txt_id, ITALIC))
+ elif code[id+2].lower() == 'u':
+ self.points.append(Point(END, len(self.text)+txt_id, UNDERLINE))
+ elif code[id+2].lower() == 'c':
+ self.points.append(Point(END, len(self.text)+txt_id, COLOR, None))
+ elif code[id+2].lower() == 's':
+ self.points.append(Point(END, len(self.text)+txt_id, SIZE, None))
+ elif code[id+2].lower() == 'f':
+ self.points.append(Point(END, len(self.text)+txt_id, FONT, None))
+
+ self.text += text
+ else:
+ self.text += code
+
+ # add a style
+ def add_style(self, start, end, type, attr=None):
+ self.points.append(Point(BEGIN, start, type, attr))
+ self.points.append(Point(END, end, type, attr))
+
+ self.points.sort(key=lambda x: x.pos)
+
+ def load_font(self, font, size):
+ if font in pygame.font.get_fonts():
+ f = pygame.font.SysFont(font, size)
+ if self.fonts.has_key(font):
+ self.fonts[font][size] = f
+ else:
+ self.fonts[font] = {size:f}
+ else:
+ try:
+ f = pygame.font.Font(font, size)
+ except:
+ f = pygame.font.Font(None, size)
+
+ if self.fonts.has_key(font):
+ self.fonts[font][size] = f
+ else:
+ self.fonts[font] = {size:f}
+
+ def check_fonts(self):
+ font = [self.default_font]
+ size = [self.default_size]
+ for point in self.points:
+ if point.classe == BEGIN:
+ if point.type == FONT:
+ font.append(point.attr)
+ elif point.type == SIZE:
+ size.append(point.attr)
+ else:
+ if point.type == FONT:
+ font.pop()
+ elif point.type == SIZE:
+ size.pop()
+
+ if not self.fonts.has_key(font[len(font)-1]):
+ self.load_font(font[len(font)-1], size[len(size)-1])
+
+ if not self.fonts[font[len(font)-1]].has_key(size[len(size)-1]):
+ self.load_font(font[len(font)-1], size[len(size)-1])
+
+ # check the line height
+ def line_height(self, font, char, line):
+ line_height = font
+ size = [self.default_size]
+ font = [self.default_font]
+ for point in self.points:
+ if point.classe == BEGIN:
+ if point.type == FONT:
+ font.append(point.attr)
+ elif point.type == SIZE:
+ size.append(point.attr)
+ else:
+ if point.type == FONT:
+ font.pop()
+ elif point.type == SIZE:
+ size.pop()
+
+ if char <= point.pos <= char+len(line) and point.type in (FONT, SIZE):
+ f = self.fonts[font[len(font)-1]][size[len(size)-1]].get_height()
+ if f > line_height:
+ line_height = f
+
+ return line_height
+
+ # replace some characters like tabs
+ def replace(self, text):
+ text = text.replace('\t', ' ')
+
+ return text
+
+ # redraw the text
+ def update(self):
+ # control if the needed fonts are loaded
+ self.check_fonts()
+
+ self.area.fill(self.background_color)
+
+ l = 0 # line number
+ dist_from_top = 0
+ char = 0 # char num from the beginning
+ bottom_border = -self.text_start + self.rect.height
+
+ bold = False
+ italic = False
+ underline = False
+ color = [self.default_color]
+ size = [self.default_size]
+ font = [self.default_font]
+ for line in self.text.split('\n'):
+ # check for line_height
+ h = self.fonts[font[len(font)-1]][size[len(size)-1]].get_height()
+ line_height = self.line_height(h, char, line)
+
+ id = 0
+ l_id = 0
+ x = self.border # need changes to support line numers
+ printed = False
+ for point in self.points:
+ if char <= point.pos <= char+len(line):
+ # don't draw text if it's over the top border
+ if -self.text_start <= dist_from_top <= bottom_border and l_id == 0:
+ f = self.fonts[font[len(font)-1]][size[len(size)-1]]
+ f.set_bold(bold)
+ f.set_italic(italic)
+ f.set_underline(underline)
+
+ text = self.replace(line[:point.pos-char])
+
+ render = f.render(text, self.antialias, color[len(color)-1])
+ line_pos = (line_height-f.get_height())/2
+ self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border))
+
+ x += render.get_width()
+ printed = True
+
+ if point.classe == BEGIN:
+ if point.type == BOLD:
+ bold = True
+ elif point.type == ITALIC:
+ italic = True
+ elif point.type == UNDERLINE:
+ underline = True
+ elif point.type == COLOR:
+ color.append(point.attr)
+ elif point.type == SIZE:
+ size.append(point.attr)
+ elif point.type == FONT:
+ font.append(point.attr)
+ elif point.classe == END:
+ if point.type == BOLD:
+ bold = False
+ elif point.type == ITALIC:
+ italic = False
+ elif point.type == UNDERLINE:
+ underline = False
+ elif point.type == COLOR:
+ color.pop()
+ elif point.type == SIZE:
+ size.pop()
+ elif point.type == FONT:
+ font.pop()
+
+ # don't draw text if it's over the top border
+ if -self.text_start <= dist_from_top <= bottom_border:
+ f = self.fonts[font[len(font)-1]][size[len(size)-1]]
+ f.set_bold(bold)
+ f.set_italic(italic)
+ f.set_underline(underline)
+
+ try:
+ text = self.replace(line[point.pos-char:self.points[id+1].pos-char])
+ except:
+ text = self.replace(line[point.pos-char:])
+
+ render = f.render(text, self.antialias, color[len(color)-1])
+ line_pos = (line_height-f.get_height())/2
+ self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border))
+
+ x += render.get_width()
+ printed = True
+
+ l_id += 1
+
+ id += 1
+
+ if not printed and -self.text_start <= dist_from_top <= bottom_border:
+ f = self.fonts[font[len(font)-1]][size[len(size)-1]]
+ f.set_bold(bold)
+ f.set_italic(italic)
+ f.set_underline(underline)
+
+ text = self.replace(line)
+
+ render = f.render(text, self.antialias, color[len(color)-1])
+ line_pos = (line_height-f.get_height())/2
+ self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border))
+
+ x += render.get_width()
+ printed = True
+
+
+ l += 1
+ char += len(line) + 1
+ dist_from_top += line_height