Note that there are some explanatory texts on larger screens.

plurals
  1. POHelp getting frame rate (fps) up in Python + Pygame
    primarykey
    data
    text
    <p>I am working on a little card-swapping world-travel game that I sort of envision as a cross between Bejeweled and the 10 Days geography board games. So far the coding has been going okay, but the frame rate is pretty bad... currently I'm getting low 20's on my Core 2 Duo. This is a problem since I'm creating the game for Intel's March developer competition, which is squarely aimed at netbooks packing underpowered Atom processors.</p> <p>Here's a <strong>screen from the game</strong>:</p> <p><a href="http://www.necessarygames.com/my_games/betraveled/betraveled-fps.png" rel="noreferrer">alt text http://www.necessarygames.com/my_games/betraveled/betraveled-fps.png</a></p> <p>I am very new to Python and Pygame (this is the first thing I've used them for), and am sadly lacking in formal CS training... which is to say that I think there are probably A LOT of bad practices going on in my code, and A LOT that could be optimized. If some of you older Python hands wouldn't mind taking a look at my code and seeing if you can't find any obvious areas for optimization, I would be extremely grateful. </p> <p>You can download the <strong>full source code</strong> here (Python 2.6 + Pygame 1.9): <a href="http://www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip" rel="noreferrer">http://www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip</a></p> <p><strong>Compiled exe</strong> here: www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip</p> <p>One thing I am concerned about is my event manager, which I feel may have some performance wholes in it, and another thing is my rendering... I'm pretty much just blitting everything to the screen all the time (see the render routines in my game_components.py below); I recently found out that you should only update the areas of the screen that have changed, but I'm still foggy on how that accomplished exactly... could this be a huge performance issue?</p> <p>Any thoughts are much appreciated! <strong>As usual, I'm happy to "tip" you for your time and energy via PayPal.</strong></p> <p>Jordan <br><br><br><br> <strong>EDIT:</strong> Thanks to the advice below, I ran cprofile on my code. It would be great if anyone would be willing to look at this output and let me know what is and what is not to be expected. <br><br><br><br></p> <p>Here is the output of <strong>p.strip_dirs().sort_stats('cumulative').print_stats()</strong>:</p> <pre><code>pydev debugger: starting Sun Mar 28 04:46:16 2010 cprofile 8383715 function calls (8264821 primitive calls) in 157.732 CPU seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 157.732 157.732 &lt;string&gt;:1(&lt;module&gt;) 1 0.000 0.000 157.732 157.732 main.py:47(main) 1 0.074 0.074 157.280 157.280 event_manager.py:101(run) 4911/2414 11.837 0.002 156.984 0.065 event_manager.py:32(post) 4786/4681 0.238 0.000 94.852 0.020 rooms.py:251(notify) 2187 0.523 0.000 51.136 0.023 rooms.py:329(render) 4911/2959 0.220 0.000 35.732 0.012 event_manager.py:54(notify) 2271 33.996 0.015 33.996 0.015 {pygame.display.update} 2271 0.060 0.000 23.664 0.010 app.py:178(paint) 37347/2271 1.580 0.000 23.587 0.010 container.py:83(paint) 70236/2271 3.609 0.000 23.448 0.010 theme.py:275(func) 1078950 16.926 0.000 16.926 0.000 {method 'blit' of 'pygame.Surface' objects} 2187 2.131 0.001 16.875 0.008 game_components.py:666(render) 19635/17756 0.187 0.000 13.852 0.001 game_components.py:641(notify) 733820 7.710 0.000 13.643 0.000 game_components.py:1151(notify) 2271 12.254 0.005 12.254 0.005 {pygame.time.wait} 64112 3.174 0.000 11.252 0.000 game_components.py:1186(render) 9 0.002 0.000 10.151 1.128 game_components.py:286(deal_new_board) 1934 0.095 0.000 8.489 0.004 app.py:144(event) 4359/2146 0.178 0.000 8.375 0.004 container.py:112(event) 2335/2146 0.056 0.000 8.251 0.004 widget.py:346(_event) 2335/2146 0.048 0.000 8.193 0.004 theme.py:320(func) 4883/4691 0.018 0.000 8.049 0.002 widget.py:313(send) 229 0.139 0.001 8.017 0.035 game_components.py:632(refresh_darkness) 7258 0.499 0.000 7.844 0.001 game_components.py:963(test_close_to_trip) 2271 7.378 0.003 7.378 0.003 {pygame.display.set_caption} 19347 3.313 0.000 6.687 0.000 game_components.py:928(get_next_to) 2187 1.529 0.001 6.629 0.003 game_components.py:130(render) 2011729 5.938 0.000 5.938 0.000 {isinstance} 3 0.000 0.000 5.906 1.969 my_gui.py:274(clicked) 219456 3.060 0.000 5.680 0.000 surface.py:5(subsurface) 1290 0.506 0.000 5.416 0.004 game_components.py:683(__init__) 8748 2.891 0.000 5.340 0.001 theme.py:400(render) 70236 2.232 0.000 4.945 0.000 theme.py:186(box) 1357 0.097 0.000 4.391 0.003 game_components.py:742(set_image) 9 0.054 0.006 3.450 0.383 game_components.py:209(deal_connection_matrix) 8748 0.325 0.000 3.318 0.000 theme.py:479(paint) 1051 0.015 0.000 3.262 0.003 game_components.py:1232(__init__) 386467 3.148 0.000 3.148 0.000 {method 'fill' of 'pygame.Surface' objects} 245332 2.470 0.000 3.117 0.000 game_components.py:495(get_card) 55761 3.068 0.000 3.068 0.000 {pygame.draw.aaline} 2271 2.968 0.001 2.968 0.001 {pygame.event.get} 9 0.007 0.001 2.946 0.327 game_components.py:416(clone) 2187 0.089 0.000 2.717 0.001 misc.py:28(paint) 803701 2.483 0.000 2.497 0.000 weakref.py:302(iterkeys) 2739 2.441 0.001 2.441 0.001 {pygame.imageext.load_extended} 1470 1.108 0.001 2.432 0.002 game_components.py:450(set_pos) 29 0.029 0.001 2.270 0.078 game_components.py:433(clear) 2 0.000 0.000 2.158 1.079 main.py:22(set_room) 4911/4862 0.027 0.000 2.141 0.000 main.py:37(notify) 1 0.000 0.000 2.099 2.099 my_gui.py:164(clicked) 1 0.001 0.001 2.099 2.099 rooms.py:117(__init__) 1120 0.039 0.000 1.978 0.002 game_components.py:484(place_card) 27 0.013 0.000 1.963 0.073 game_components.py:339(merge_board_stack) 311 0.018 0.000 1.939 0.006 game_components.py:443(remove) 125 0.007 0.000 1.848 0.015 rooms.py:18(notify) 224 0.003 0.000 1.806 0.008 game_components.py:721(clone) 219456 1.638 0.000 1.638 0.000 {method 'subsurface' of 'pygame.Surface' objects} 183 0.004 0.000 1.313 0.007 game_components.py:1240(__init__) 4374 0.106 0.000 1.224 0.000 button.py:97(paint) 46765 0.967 0.000 1.137 0.000 game_components.py:784(set_pos) 229 0.109 0.000 1.111 0.005 game_components.py:594(refresh_trip) 4076 1.076 0.000 1.076 0.000 {method 'convert_alpha' of 'pygame.Surface' objects} 9 0.015 0.002 1.018 0.113 game_components.py:542(displace_cards) 17496 0.360 0.000 0.953 0.000 basic.py:102(paint) 66299 0.948 0.000 0.948 0.000 {pygame.draw.rect} 1357 0.024 0.000 0.945 0.001 game_components.py:736(set_text) 1357 0.052 0.000 0.917 0.001 game_components.py:841(render_text_rec) 5815 0.455 0.000 0.881 0.000 game_components.py:1108(get_connections) 6610 0.869 0.000 0.869 0.000 {method 'replace' of 'pygame.PixelArray' objects} 56 0.001 0.000 0.861 0.015 game_components.py:1252(__init__) 10 0.001 0.000 0.857 0.086 game_components.py:377(__init__) 540 0.484 0.001 0.828 0.002 game_components.py:613(refresh_connections) 189431 0.730 0.000 0.730 0.000 game_components.py:500(test_index_on_board) 161329 0.632 0.000 0.727 0.000 matrix.py:33(__iter__) 309968 0.710 0.000 0.710 0.000 {method 'get_width' of 'pygame.Surface' objects} 308567 0.675 0.000 0.675 0.000 {method 'get_height' of 'pygame.Surface' objects} 109626 0.646 0.000 0.670 0.000 style.py:18(__getattr__) 241697 0.646 0.000 0.646 0.000 matrix.py:24(getitem) 21084 0.601 0.000 0.601 0.000 {method 'render' of 'pygame.font.Font' objects} 327 0.006 0.000 0.580 0.002 game_components.py:490(place_card_first_time) 26 0.001 0.000 0.561 0.022 game_components.py:1259(__init__) 166 0.002 0.000 0.536 0.003 game_components.py:608(get_longest_trip) 1491/166 0.075 0.000 0.534 0.003 game_components.py:989(get_longest_trip) 5702 0.533 0.000 0.533 0.000 {method 'size' of 'pygame.font.Font' objects} 1 0.000 0.000 0.478 0.478 game_components.py:141(__init__) 1 0.001 0.001 0.478 0.478 game_components.py:165(rebuild) 67 0.005 0.000 0.457 0.007 game_components.py:713(change_size) 1 0.001 0.001 0.420 0.420 game_components.py:347(change_card_size) 1210/166 0.044 0.000 0.412 0.002 game_components.py:982(add_to_trip) 7654 0.275 0.000 0.405 0.000 game_components.py:938(get_bounding_box) 14969 0.101 0.000 0.385 0.000 game_components.py:1305(render) 149709 0.341 0.000 0.341 0.000 {method 'append' of 'list' objects} 87958 0.341 0.000 0.341 0.000 {hasattr} 1362 0.068 0.000 0.336 0.000 textrect.py:12(render_textrect) 30 0.001 0.000 0.301 0.010 game_components.py:1282(__init__) 47795 0.257 0.000 0.257 0.000 game_components.py:1024(test_connection) 14849 0.098 0.000 0.251 0.000 my_gui.py:209(notify) 17498 0.158 0.000 0.242 0.000 basic.py:22(is_color) 87480 0.224 0.000 0.224 0.000 {method 'set_clip' of 'pygame.Surface' objects} 9 0.003 0.000 0.209 0.023 game_components.py:279(deal_to_blank_squares) 1 0.114 0.114 0.208 0.208 {pygame.display.set_mode} 56617 0.206 0.000 0.206 0.000 game_components.py:837(get_center) 84 0.005 0.000 0.206 0.002 rooms.py:110(render) </code></pre> <p>Here is the output of <strong>p.strip_dirs().sort_stats('time').print_stats()</strong>:</p> <pre><code>Sun Mar 28 04:46:16 2010 cprofile 8383715 function calls (8264821 primitive calls) in 157.732 CPU seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 2271 33.996 0.015 33.996 0.015 {pygame.display.update} 1078950 16.926 0.000 16.926 0.000 {method 'blit' of 'pygame.Surface' objects} 2271 12.254 0.005 12.254 0.005 {pygame.time.wait} 4911/2414 11.837 0.002 156.984 0.065 event_manager.py:32(post) 733820 7.710 0.000 13.643 0.000 game_components.py:1151(notify) 2271 7.378 0.003 7.378 0.003 {pygame.display.set_caption} 2011729 5.938 0.000 5.938 0.000 {isinstance} 70236/2271 3.609 0.000 23.448 0.010 theme.py:275(func) 19347 3.313 0.000 6.687 0.000 game_components.py:928(get_next_to) 64112 3.174 0.000 11.252 0.000 game_components.py:1186(render) 386467 3.148 0.000 3.148 0.000 {method 'fill' of 'pygame.Surface' objects} 55761 3.068 0.000 3.068 0.000 {pygame.draw.aaline} 219456 3.060 0.000 5.680 0.000 surface.py:5(subsurface) 2271 2.968 0.001 2.968 0.001 {pygame.event.get} 8748 2.891 0.000 5.340 0.001 theme.py:400(render) 803701 2.483 0.000 2.497 0.000 weakref.py:302(iterkeys) 245332 2.470 0.000 3.117 0.000 game_components.py:495(get_card) 2739 2.441 0.001 2.441 0.001 {pygame.imageext.load_extended} 70236 2.232 0.000 4.945 0.000 theme.py:186(box) 2187 2.131 0.001 16.875 0.008 game_components.py:666(render) 219456 1.638 0.000 1.638 0.000 {method 'subsurface' of 'pygame.Surface' objects} 37347/2271 1.580 0.000 23.587 0.010 container.py:83(paint) 2187 1.529 0.001 6.629 0.003 game_components.py:130(render) 1470 1.108 0.001 2.432 0.002 game_components.py:450(set_pos) 4076 1.076 0.000 1.076 0.000 {method 'convert_alpha' of 'pygame.Surface' objects} 46765 0.967 0.000 1.137 0.000 game_components.py:784(set_pos) 66299 0.948 0.000 0.948 0.000 {pygame.draw.rect} 6610 0.869 0.000 0.869 0.000 {method 'replace' of 'pygame.PixelArray' objects} 189431 0.730 0.000 0.730 0.000 game_components.py:500(test_index_on_board) 309968 0.710 0.000 0.710 0.000 {method 'get_width' of 'pygame.Surface' objects} 308567 0.675 0.000 0.675 0.000 {method 'get_height' of 'pygame.Surface' objects} 109626 0.646 0.000 0.670 0.000 style.py:18(__getattr__) 241697 0.646 0.000 0.646 0.000 matrix.py:24(getitem) 161329 0.632 0.000 0.727 0.000 matrix.py:33(__iter__) 21084 0.601 0.000 0.601 0.000 {method 'render' of 'pygame.font.Font' objects} 5702 0.533 0.000 0.533 0.000 {method 'size' of 'pygame.font.Font' objects} 2187 0.523 0.000 51.136 0.023 rooms.py:329(render) 1290 0.506 0.000 5.416 0.004 game_components.py:683(__init__) 7258 0.499 0.000 7.844 0.001 game_components.py:963(test_close_to_trip) 540 0.484 0.001 0.828 0.002 game_components.py:613(refresh_connections) 5815 0.455 0.000 0.881 0.000 game_components.py:1108(get_connections) 17496 0.360 0.000 0.953 0.000 basic.py:102(paint) 149709 0.341 0.000 0.341 0.000 {method 'append' of 'list' objects} 87958 0.341 0.000 0.341 0.000 {hasattr} 8748 0.325 0.000 3.318 0.000 theme.py:479(paint) 7654 0.275 0.000 0.405 0.000 game_components.py:938(get_bounding_box) 47795 0.257 0.000 0.257 0.000 game_components.py:1024(test_connection) 4786/4681 0.238 0.000 94.852 0.020 rooms.py:251(notify) 87480 0.224 0.000 0.224 0.000 {method 'set_clip' of 'pygame.Surface' objects} 4911/2959 0.220 0.000 35.732 0.012 event_manager.py:54(notify) 56617 0.206 0.000 0.206 0.000 game_components.py:837(get_center) 1 0.200 0.200 0.200 0.200 {pygame.base.quit} 19635/17756 0.187 0.000 13.852 0.001 game_components.py:641(notify) 1 0.184 0.184 0.184 0.184 {pygame.base.init} 4359/2146 0.178 0.000 8.375 0.004 container.py:112(event) 17498 0.158 0.000 0.242 0.000 basic.py:22(is_color) 1358 0.151 0.000 0.151 0.000 {pygame.transform.smoothscale} 229 0.139 0.001 8.017 0.035 game_components.py:632(refresh_darkness) 1 0.114 0.114 0.208 0.208 {pygame.display.set_mode} 37862 0.112 0.000 0.112 0.000 {method 'set_alpha' of 'pygame.Surface' objects} 6561 0.111 0.000 0.195 0.000 button.py:236(paint) 229 0.109 0.000 1.111 0.005 game_components.py:594(refresh_trip) 4374 0.106 0.000 1.224 0.000 button.py:97(paint) 14969 0.101 0.000 0.385 0.000 game_components.py:1305(render) 14849 0.098 0.000 0.251 0.000 my_gui.py:209(notify) 1357 0.097 0.000 4.391 0.003 game_components.py:742(set_image) 24072 0.096 0.000 0.096 0.000 game_components.py:913(test_pos_on_card) 4926 0.095 0.000 0.132 0.000 game_components.py:1292(__init__) 33286 0.095 0.000 0.095 0.000 {range} 1934 0.095 0.000 8.489 0.004 app.py:144(event) 2187 0.089 0.000 2.717 0.001 misc.py:28(paint) 2135 0.087 0.000 0.091 0.000 matrix.py:21(setitem) 4374 0.076 0.000 0.131 0.000 button.py:182(paint) 1491/166 0.075 0.000 0.534 0.003 game_components.py:989(get_longest_trip) 1 0.074 0.074 157.280 157.280 event_manager.py:101(run) 301 0.069 0.000 0.107 0.000 game_components.py:508(clear_selection) 1362 0.068 0.000 0.336 0.000 textrect.py:12(render_textrect) 2227 0.066 0.000 0.150 0.000 game_components.py:809(move) 5740 0.062 0.000 0.165 0.000 misc.py:34(__setattr__) 2271 0.060 0.000 23.664 0.010 app.py:178(paint) 2335/2146 0.056 0.000 8.251 0.004 widget.py:346(_event) 4786 0.055 0.000 0.099 0.000 game_components.py:97(notify) 9 0.054 0.006 3.450 0.383 game_components.py:209(deal_connection_matrix) 1357 0.052 0.000 0.917 0.001 game_components.py:841(render_text_rec) 5 0.052 0.010 0.052 0.010 {method 'convert' of 'pygame.Surface' objects} 2335/2146 0.048 0.000 8.193 0.004 theme.py:320(func) 1210/166 0.044 0.000 0.412 0.002 game_components.py:982(add_to_trip) 1120 0.039 0.000 1.978 0.002 game_components.py:484(place_card) 2871/465 0.037 0.000 0.070 0.000 container.py:77(reupdate) 11862 0.037 0.000 0.037 0.000 {method 'collidepoint' of 'pygame.Rect' objects} 13602/13558 0.035 0.000 0.035 0.000 {len} 4493 0.035 0.000 0.047 0.000 button.py:71(__setattr__) </code></pre> <p><br><br><br><br> Here are some bits of the source:</p> <p><strong>Main.py</strong></p> <pre><code>#Remote imports import pygame from pygame.locals import * #Local imports import config import rooms from event_manager import * from events import * class RoomController(object): """Controls which room is currently active (eg Title Screen)""" def __init__(self, screen, ev_manager): self.room = None self.screen = screen self.ev_manager = ev_manager self.ev_manager.register_listener(self) self.room = self.set_room(config.room) def set_room(self, room_const): #Unregister old room from ev_manager if self.room: self.room.ev_manager.unregister_listener(self.room) self.room = None #Set new room based on const if room_const == config.TITLE_SCREEN: return rooms.TitleScreen(self.screen, self.ev_manager) elif room_const == config.GAME_MODE_ROOM: return rooms.GameModeRoom(self.screen, self.ev_manager) elif room_const == config.GAME_ROOM: return rooms.GameRoom(self.screen, self.ev_manager) elif room_const == config.HIGH_SCORES_ROOM: return rooms.HighScoresRoom(self.screen, self.ev_manager) def notify(self, event): if isinstance(event, ChangeRoomRequest): if event.game_mode: config.game_mode = event.game_mode self.room = self.set_room(event.new_room) def render(self, surface): self.room.render(surface) #Run game def main(): pygame.init() screen = pygame.display.set_mode(config.screen_size) ev_manager = EventManager() spinner = CPUSpinnerController(ev_manager) room_controller = RoomController(screen, ev_manager) pygame_event_controller = PyGameEventController(ev_manager) spinner.run() # this runs the main function if this script is called to run. # If it is imported as a module, we don't run the main function. if __name__ == "__main__": main() </code></pre> <p><strong>event_manager.py</strong></p> <pre><code>#Remote imports import pygame from pygame.locals import * #Local imports import config from events import * def debug( msg ): print "Debug Message: " + str(msg) class EventManager: #This object is responsible for coordinating most communication #between the Model, View, and Controller. def __init__(self): from weakref import WeakKeyDictionary self.listeners = WeakKeyDictionary() self.eventQueue= [] self.gui_app = None #---------------------------------------------------------------------- def register_listener(self, listener): self.listeners[listener] = 1 #---------------------------------------------------------------------- def unregister_listener(self, listener): if listener in self.listeners: del self.listeners[listener] #---------------------------------------------------------------------- def post(self, event): if isinstance(event, MouseButtonLeftEvent): debug(event.name) #NOTE: copying the list like this before iterating over it, EVERY tick, is highly inefficient, #but currently has to be done because of how new listeners are added to the queue while it is running #(eg when popping cards from a deck). Should be changed. See: http://dr0id.homepage.bluewin.ch/pygame_tutorial08.html #and search for "Watch the iteration" for listener in list(self.listeners): #NOTE: If the weakref has died, it will be #automatically removed, so we don't have #to worry about it. listener.notify(event) #------------------------------------------------------------------------------ class PyGameEventController: """...""" def __init__(self, ev_manager): self.ev_manager = ev_manager self.ev_manager.register_listener(self) self.input_freeze = False #---------------------------------------------------------------------- def notify(self, incoming_event): if isinstance(incoming_event, UserInputFreeze): self.input_freeze = True elif isinstance(incoming_event, UserInputUnFreeze): self.input_freeze = False elif isinstance(incoming_event, TickEvent): #Share some time with other processes, so we don't hog the cpu pygame.time.wait(5) #Handle Pygame Events for event in pygame.event.get(): #If this event manager has an associated PGU GUI app, notify it of the event if self.ev_manager.gui_app: self.ev_manager.gui_app.event(event) #Standard event handling for everything else ev = None if event.type == QUIT: ev = QuitEvent() elif event.type == pygame.MOUSEBUTTONDOWN and not self.input_freeze: if event.button == 1: #Button 1 pos = pygame.mouse.get_pos() ev = MouseButtonLeftEvent(pos) elif event.type == pygame.MOUSEMOTION: pos = pygame.mouse.get_pos() ev = MouseMoveEvent(pos) #Post event to event manager if ev: self.ev_manager.post(ev) #------------------------------------------------------------------------------ class CPUSpinnerController: def __init__(self, ev_manager): self.ev_manager = ev_manager self.ev_manager.register_listener(self) self.clock = pygame.time.Clock() self.cumu_time = 0 self.keep_going = True #---------------------------------------------------------------------- def run(self): if not self.keep_going: raise Exception('dead spinner') while self.keep_going: time_passed = self.clock.tick() fps = self.clock.get_fps() self.cumu_time += time_passed self.ev_manager.post(TickEvent(time_passed, fps)) if self.cumu_time &gt;= 1000: self.cumu_time = 0 self.ev_manager.post(SecondEvent()) pygame.quit() #---------------------------------------------------------------------- def notify(self, event): if isinstance(event, QuitEvent): #this will stop the while loop from running self.keep_going = False </code></pre> <p><strong>rooms.py</strong></p> <pre><code>#Remote imports import pygame #Local imports import config import continents from game_components import * from my_gui import * from pgu import high class Room(object): def __init__(self, screen, ev_manager): self.screen = screen self.ev_manager = ev_manager self.ev_manager.register_listener(self) def notify(self, event): if isinstance(event, TickEvent): pygame.display.set_caption('FPS: ' + str(int(event.fps))) self.render(self.screen) pygame.display.update() def get_highs_table(self): fname = 'high_scores.txt' highs_table = None config.all_highs = high.Highs(fname) if config.game_mode == config.TIME_CHALLENGE: if config.difficulty == config.EASY: highs_table = config.all_highs['time_challenge_easy'] if config.difficulty == config.MED_DIF: highs_table = config.all_highs['time_challenge_med'] if config.difficulty == config.HARD: highs_table = config.all_highs['time_challenge_hard'] if config.difficulty == config.SUPER: highs_table = config.all_highs['time_challenge_super'] elif config.game_mode == config.PLAN_AHEAD: pass return highs_table class TitleScreen(Room): def __init__(self, screen, ev_manager): Room.__init__(self, screen, ev_manager) self.background = pygame.image.load('assets/images/interface/background.jpg').convert() #Initialize #--------------------------------------- self.gui_form = gui.Form() self.gui_app = gui.App(config.gui_theme) self.ev_manager.gui_app = self.gui_app c = gui.Container(align=0,valign=0) #Quit Button #--------------------------------------- b = StartGameButton(ev_manager=self.ev_manager) c.add(b, 0, 0) self.gui_app.init(c) def render(self, surface): surface.blit(self.background, (0, 0)) #GUI self.gui_app.paint(surface) class GameModeRoom(Room): def __init__(self, screen, ev_manager): Room.__init__(self, screen, ev_manager) self.background = pygame.image.load('assets/images/interface/background.jpg').convert() self.create_gui() #Create pgu gui elements def create_gui(self): #Setup #--------------------------------------- self.gui_form = gui.Form() self.gui_app = gui.App(config.gui_theme) self.ev_manager.gui_app = self.gui_app c = gui.Container(align=0,valign=-1) #Mode Relaxed Button #--------------------------------------- b = GameModeRelaxedButton(ev_manager=self.ev_manager) self.b = b print b.rect </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload