From 0018a9e211ebbe74d371339a70edc0d36c4fc99f Mon Sep 17 00:00:00 2001 From: Mateu Batle Date: Wed, 27 Oct 2010 17:40:28 +0000 Subject: Initial import of game1 and game2 in math quwy --- (limited to 'usmpgames') 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 -- cgit v0.9.1