diff options
author | Justin Lewis <jtl1728@rit.edu> | 2010-02-13 19:11:59 (GMT) |
---|---|---|
committer | Justin Lewis <jtl1728@rit.edu> | 2010-02-13 19:11:59 (GMT) |
commit | e5db7e16d327df1edd67fbbd347b404c2b0517dd (patch) | |
tree | 76871fb2e7d8b3cc73b52968fe14307ba8ef3529 | |
parent | 57abaff26aa80fa8ff906e3ed947324a33859f02 (diff) |
Committing game engine concept.
-rw-r--r-- | MAFH2/Comic.py | 76 | ||||
-rw-r--r-- | MAFH2/GameEngine.py | 150 | ||||
-rw-r--r-- | MAFH2/MafhActivity.py | 34 | ||||
-rw-r--r-- | MAFH2/MafhGameMenu.py | 110 | ||||
l--------- | MAFH2/assets | 1 | ||||
l--------- | MAFH2/constants.py | 1 | ||||
-rw-r--r-- | MAFH2/ezmenu.py | 98 |
7 files changed, 470 insertions, 0 deletions
diff --git a/MAFH2/Comic.py b/MAFH2/Comic.py new file mode 100644 index 0000000..f6a5122 --- /dev/null +++ b/MAFH2/Comic.py @@ -0,0 +1,76 @@ +import pygame +import os + +###################################################################### +#Comic Class: stores an image list and possible BGM, traverses through list and tries to play BGM +###################################################################### +class Comic: + def __init__(self,ge,Folder,BGM,endcb): + self.currentIndex = 0 + self.images=[] + self.endcb = endcb + self.ge = ge + #load images into sprites + i=0 + for image in os.listdir(Folder): + spt=pygame.sprite.Sprite() + spt.image=pygame.image.load(Folder+image) + spt.rect=pygame.Rect(0,0,1200,900) + self.images.append(spt) + i+=1 + self.size=i + #try to load music + if BGM != None: + pygame.mixer.muxic.stop() + pygame.mixer.music.load(SOUND_PATH+BGM) + pygame.mixer.music.play(-1) + + self.__inEngine = False + self.add_to_engine() + + def add_to_engine(self): + if not self.__inEngine: + self.__inEngine = True + self.ge.add_draw_callback( self.draw ) + self.ge.add_event_callback( self.event_handler ) + + def remove_from_engine(self): + if self.__inEngine: + self.__inEngine = False + self.ge.remove_draw_callback( self.draw ) + self.ge.remove_event_callback( self.event_handler ) + + def end(self): + self.remove_from_engine() + self.ge.remove_object("comic") + self.endcb() + + def next(self): + if self.currentIndex < self.size - 1: + self.currentIndex+=1 + + def previous(self): + if self.currentIndex > 0: + self.currentIndex-=1 + + def has_next(self): + if self.currentIndex < self.size - 1: + return True + else: + return False + + def draw(self,screen): + screen.blit(self.images[self.currentIndex].image,(0,0,1200,900)) + + def event_handler(self,event,engine): + if event.type == pygame.KEYDOWN: + newKey=pygame.key.name(event.key) + + if newKey=='[1]' or newKey=='right': + if self.has_next(): + self.next() + else: + self.end() + + elif newKey=='[3]' or newKey=='left': + self.previous() diff --git a/MAFH2/GameEngine.py b/MAFH2/GameEngine.py new file mode 100644 index 0000000..dacb63e --- /dev/null +++ b/MAFH2/GameEngine.py @@ -0,0 +1,150 @@ +import pygame + +class GameEngine: + def __init__(self, width=1200, height=900): + pygame.init() + pygame.mouse.set_visible(False) + + self.width = width + self.height = height + size = width, height + + self.screen = pygame.display.set_mode(size) + + self.__event_cb = [] + self.__draw_lst = [] + self.__object_hold = {} + + def start_event_loop(self): + """ + Starts the pygame event loop. + """ + self.__run = True + pygame.event.set_blocked(pygame.MOUSEMOTION) + while self.__run: + event = pygame.event.wait() + + if event.type == pygame.QUIT: + self.__run = False + else: + # Send event to all event listeners + # Make a copy first so that adding events don't get fired right away + list_cp = self.__event_cb + + # Reverse list so that newest stuff is on top + list_cp.reverse() + + for cb in list_cp: + # Fire the event for all in cb and stop if return True + if cb(event, self) == True: + break + self.draw() + + #DEBUG PRINT + print "\n\n\nEvent Listeners:", self.__event_cb + for eventlst in self.__event_cb: + print "\t",eventlst + + print "\nDraw Callbacks:", self.__draw_lst + for eventlst in self.__draw_lst: + print "\t",eventlst + + print "\nObjects Registered:" + for eventlst in self.__object_hold: + print "\t",eventlst + + def stop_event_loop(self): + """ + Sends a pygame.QUIT event into the event queue which exits the event loop + """ + pygame.event.post(pygame.event.Event(pygame.QUIT)) + + def draw(self): + """ + Calls draw on the draw callback stack then calls the pygame flip command + """ + for fnc in self.__draw_lst: + fnc(self.screen) + pygame.display.flip() + + def add_event_callback(self, cb): + """ + Adds event callback to the event callback stack + + @param cb Callback to be added to the stack when events are fired + """ + self.__event_cb.append( cb ) + + def remove_event_callback(self, cb): + """ + Removes an event from the event callback stack + + @param cb The callback to remove from the event callback stack + @return Returns true if sucessful in removing callback + """ + try: + self.__event_cb.remove( cb ) + return True + except: + return False + + def add_draw_callback(self, fnc): + """ + Adds a callback to the draw list. Function will be passed the game screen + + @param fnc The funciton to call when system is drawing + """ + self.__draw_lst.append( fnc ) + + def pop_draw_callback(self): + """ + Removes top of draw stack and returns it + + @return Returns the top callback function that was removed + """ + return self.__draw_lst.pop() + + def clear_draw_callback(self): + """ + Empties draw callback stack + """ + self.__draw_lst = [] + + def remove_draw_callback(self, fnc): + """ + Removes a draw callback from the game engine draw function + + @param fnc The callback function to remove + @return Returns true if sucessful removal of the function + """ + try: + self.__draw_lst.remove(fnc) + return True + except: + return False + + def add_object(self, name, obj): + """ + Adds an object to the game engine datastore + + @param name The name used to store the object + @param obj The object to store + """ + self.__object_hold[name] = obj + + def get_object(self, name): + """ + Returns an object from the game engine datastore + + @param name The name of object to return + @return Returns the object + """ + return self.__object_hold[name] + + def remove_object(self, name): + """ + Removes an object from the game engine datastore + + @param name The name of the object to remove + """ + del self.__object_hold[name] diff --git a/MAFH2/MafhActivity.py b/MAFH2/MafhActivity.py new file mode 100644 index 0000000..955b45c --- /dev/null +++ b/MAFH2/MafhActivity.py @@ -0,0 +1,34 @@ +from GameEngine import GameEngine +from MafhGameMenu import GameMenuHolder + +from constants import MENU_PATH, FMC_PATH, TOUR_PATH + +from Comic import Comic + +ge = GameEngine() + +def start_game(): + print "START GAME NOW" + +def menu_screen(): + ge.add_object( 'menu', GameMenuHolder(ge, menu_called, MENU_PATH + "mafh_splash.gif")) + ge.get_object('menu').show_menu('title') + +def menu_called(id, menu): + if id == 'new': + menu.remove_from_engine() + ge.remove_object('menu') + ge.add_object('comic', Comic(ge, FMC_PATH+"FMC1/",None,start_game)) + if id == 'controls': + menu.remove_from_engine() + ge.remove_object('menu') + ge.add_object('comic', Comic(ge, TOUR_PATH+"setup/",None,menu_screen)) + else: + print "MENU CALLED %s" % id + +# Build menu and add to engine. Then show menu +menu_screen() + +# Draw and start event loop +ge.draw() +ge.start_event_loop() diff --git a/MAFH2/MafhGameMenu.py b/MAFH2/MafhGameMenu.py new file mode 100644 index 0000000..bc52e5c --- /dev/null +++ b/MAFH2/MafhGameMenu.py @@ -0,0 +1,110 @@ +import pygame, ezmenu + +class GameMenuHolder: + def __init__(self, game_engine, callback, background=None, width=1200, height=900): + self.ge = game_engine + self.menu = None + self.callback = callback + self.background = background + self.width = width + self.height = height + self._in_engine = False + + def draw(self, screen): + if self.background: + screen.blit(pygame.image.load(self.background),(0,0,self.width,self.height)) + else: + screen.fill((0, 0, 255)) + + def __del__(self): + self.remove_from_engine() + + def add_to_engine(self): + if not self._in_engine: + self._in_engine = True + self.ge.add_draw_callback( self.draw ) + + def remove_from_engine(self): + if self._in_engine: + self._in_engine = False + self._clear_menu() + self.ge.remove_draw_callback(self.draw) + + def _clear_menu(self): + if self.menu: + self.ge.remove_event_callback( self.menu.event_handler ) + self.ge.remove_draw_callback( self.menu.draw ) + self.menu = None + + def menu_called(self, id): + self.callback(id, self) + + def show_menu(self,id): + if self._in_engine: + self._clear_menu() + else: + self.add_to_engine() + + if id == "title": + menu_options = [ + ["Controls", lambda: self.menu_called("controls"), "View Controls"], + ["Adventure Play", lambda: self.show_menu("adventure"), "Play standard adventure mode"], + ['Creative Play', lambda: self.show_menu("creative"), "Play Custom Maps"], + ['Extras', lambda: self.show_menu("extras"), "View Extra Options"], + ['Options', lambda: self.menu_called("options"), "View Options Menu"], + ['Exit Game', lambda: self.ge.stop_event_loop(), "Exit Game"] + ] + + elif id == "adventure": + menu_options = [ + ["Continue", lambda: self.menu_called("continue"), "Continues Last Saved Game"], + ["Load Game", lambda: self.menu_called("load"), "Loads a saved game"], + ["New Game", lambda: self.menu_called("new"), "Creates a new game"], + ["Return to Title", lambda: self.show_menu("title"),"Return to title menu"] + ] + + elif id == "creative": + menu_options = [ + ["Play Custom Map", lambda: self.menu_called("playcustom"),"NOT IMPLEMENTED"], + ["New Custom Map", lambda: self.menu_called("newcustom"),"NOT IMPLEMENTED"], + ["Share Map", lambda: self.menu_called("sharecustom"),"NOT IMPLEMENTED"], + ["Return to Title", lambda: self.show_menu("title"), "Return to title menu"] + ] + + elif id == "network": + menu_options = [ + ["Local Cooperative Play", lambda: self.menu_called("networklocal"),"NOT IMPLEMENTED"], + ["Local Treasure Trekkers Play", lambda: self.menu_called("networktreasure"),"NOT IMPLEMENTED"], + ["View Scoreboards", lambda: self.menu_called("networkscore"),"NOT IMPLEMENTED"], + ["Return to Title", lambda: self.show_menu("title"), "Returns to title menu"] + ] + + elif id == "extras": + menu_options = [ + ["View Bestiary", lambda: self.menu_called("viewbestiary"),"NOT IMPLEMENTED"], + ["View Awards", lambda: self.menu_called("viewawards"),"NOT IMPLEMENTED"], + ["View Statistics", lambda: self.menu_called("viewstats"),"NOT IMPLEMENTED"], + ["Return to Title", lambda: self.show_menu("title"),"NOT IMPLEMENTED"] + ] + + else: + print "Invalid Menu", id + return + + self.menu = GameMenu(menu_options) + self.ge.add_event_callback( self.menu.event_handler ) + self.ge.add_draw_callback( self.menu.draw ) + +class GameMenu: + def __init__(self, game_menu, center_x=800, center_y=400): + self.menu = ezmenu.EzMenu(game_menu) + self.menu.center_at(center_x, center_y) + self.menu.set_font(pygame.font.SysFont("Arial", 32)) + self.menu.set_highlight_color((0, 255, 0)) + self.menu.set_normal_color((255, 255, 255)) + + def event_handler(self, event, engine): + self.menu.update([event]) + + def draw(self, screen): + self.menu.draw( screen ) diff --git a/MAFH2/assets b/MAFH2/assets new file mode 120000 index 0000000..2151e63 --- /dev/null +++ b/MAFH2/assets @@ -0,0 +1 @@ +/home/jlew/Code/xo/MAFH/mainline/MAFH.activity/assets/
\ No newline at end of file diff --git a/MAFH2/constants.py b/MAFH2/constants.py new file mode 120000 index 0000000..1639871 --- /dev/null +++ b/MAFH2/constants.py @@ -0,0 +1 @@ +/home/jlew/Code/xo/MAFH/mainline/MAFH.activity/constants.py
\ No newline at end of file diff --git a/MAFH2/ezmenu.py b/MAFH2/ezmenu.py new file mode 100644 index 0000000..c6c55c1 --- /dev/null +++ b/MAFH2/ezmenu.py @@ -0,0 +1,98 @@ +#! /usr/bin/env python + +############################################################ +#EzMeNu - A simple module to quickly make menus with PyGame# +############################################################ +#Licensed under the GNU Lesser General Public License # +#Created by PyMike <pymike93@gmail.com> # +#Some edits by Justin Lewis <jtl1728@rit.edu # +############################################################ + +import pygame + +class EzMenu: + + def __init__(self, options): + """Initialise the EzMenu! options should be a sequence of lists in the + format of [option_name, option_function]""" + + self.options = options + self.x = 0 + self.y = 0 + self.font = pygame.font.Font(None, 32) + self.option = 0 + self.width = 1 + self.color = [0, 0, 0] + self.hcolor = [255, 0, 0] + self.height = len(self.options)*self.font.get_height() + for o in self.options: + text = o[0] + ren = self.font.render(text, 1, (0, 0, 0)) + if ren.get_width() > self.width: + self.width = ren.get_width() + + def draw(self, surface): + """Draw the menu to the surface.""" + i=0 + help_txt = "" + for o in self.options: + if i==self.option: + clr = self.hcolor + help_txt = o[2] + else: + clr = self.color + text = o[0] + ren = self.font.render(text, 1, clr) + if ren.get_width() > self.width: + self.width = ren.get_width() + surface.blit(ren, (self.x, self.y + i*self.font.get_height())) + i+=1 + + # Help Test + self.font.set_italic( True ) + ren = self.font.render( help_txt, 1, self.color ) + self.font.set_italic( False ) + + surf1 = pygame.Surface((1050,self.font.get_height()+20), pygame.SRCALPHA) + + pygame.draw.rect(surf1, pygame.Color(255, 255, 255, 70), (0, 0, 1050, self.font.get_height()+20)) + + surface.blit( surf1, (50, 690) ) + surface.blit( ren, (55, 700) ) + + def update(self, events): + """Update the menu and get input for the menu.""" + for e in events: + if e.type == pygame.KEYDOWN: + if e.key == pygame.K_DOWN: + self.option += 1 + if e.key == pygame.K_UP: + self.option -= 1 + if e.key == pygame.K_RETURN: + self.options[self.option][1]() + if self.option > len(self.options)-1: + self.option = 0 + if self.option < 0: + self.option = len(self.options)-1 + + def set_pos(self, x, y): + """Set the topleft of the menu at x,y""" + self.x = x + self.y = y + + def set_font(self, font): + """Set the font used for the menu.""" + self.font = font + + def set_highlight_color(self, color): + """Set the highlight color""" + self.hcolor = color + + def set_normal_color(self, color): + """Set the normal color""" + self.color = color + + def center_at(self, x, y): + """Center the center of the menu at x,y""" + self.x = x-(self.width/2) + self.y = y-(self.height/2) |