Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Cameron <quozl@laptop.org>2013-10-01 10:43:26 (GMT)
committer Laurent Bernabé <laurent.bernabe@gmail.com>2013-10-01 11:14:50 (GMT)
commit13abc847f7fd9cd9f4187864f88aeffc3717466f (patch)
tree78a2b93ac6c1910c0fc3fe3777048b04c5193f5f
parent4bf930688087731ff6089b12350a5fc9a87f9f82 (diff)
optimise drawing
Change to update only the parts of the screen that have been affected by drawin gin the preceeding frame. This cuts average CPU usage from 30% to 5% on OLPC XO-1.5 during the moving of the balls part of the game.
-rw-r--r--main_game.py45
1 files changed, 31 insertions, 14 deletions
diff --git a/main_game.py b/main_game.py
index d8ad3b0..54e696d 100644
--- a/main_game.py
+++ b/main_game.py
@@ -50,6 +50,7 @@ class Game:
Constructor.
"""
self._initialized = False
+ self.s = self.p = []
def _lazy_init(self):
"""
@@ -167,6 +168,19 @@ class Game:
y_good = point[1] >= rect[1] and point[1] <= rect[1] + rect[3]
return x_good and y_good
+ def _update(self):
+ """
+ Update the screen rectangles that have been changed by drawing
+ actions since the last update (self.s), including rectangles
+ that were cleared the previous update (self.p), then clear the
+ current rectangles (self.s) in preparation for the next cycle.
+ """
+ pygame.display.update(self.s + self.p)
+ self.p = self.s
+ for r in self.s:
+ self._screen.fill(self._GAME_BACKGROUND, r)
+ self.s = []
+
def _play_game(self, time_seconds, operations_config):
""" The main game routine
time_seconds : time limit in seconds => integer
@@ -175,7 +189,7 @@ class Game:
OperationConfig.
"""
self._screen.fill(self._MENU_BACKGROUND)
- pygame.display.update()
+ self._update()
game_state = GameState.NORMAL
@@ -210,13 +224,12 @@ class Game:
while True:
while Gtk.events_pending():
Gtk.main_iteration()
- pygame.display.update()
- self._screen.fill(self._GAME_BACKGROUND)
- paint_result_bar(result_bar, self._screen)
- paint_time_bar(time_bar, self._screen)
+ self._update()
+ self.s += paint_result_bar(result_bar, self._screen)
+ self.s += paint_time_bar(time_bar, self._screen)
if game_state == GameState.NORMAL:
for ball in the_balls:
- paint_ball(ball, self._screen)
+ self.s += paint_ball(ball, self._screen)
for event in pygame.event.get():
if event.type == QUIT:
@@ -245,7 +258,7 @@ class Game:
balls_collision.manage_colliding_balls(the_balls)
self._clock.tick(self._FPS)
else:
- paint_results(balls_area, the_balls, self._screen)
+ self.s += paint_results(balls_area, the_balls, self._screen)
# Blinks the status text.
if show_status:
if game_state == GameState.WON:
@@ -255,7 +268,7 @@ class Game:
end_txt_surface = self._end_font.render(end_txt, True,
self._BLUE,
self._RED)
- self._screen.blit(end_txt_surface, self._END_TXT_POS)
+ self.s.append(self._screen.blit(end_txt_surface, self._END_TXT_POS))
for event in pygame.event.get():
if event.type == QUIT:
@@ -273,25 +286,29 @@ class Game:
Manages the main menu.
"""
self._lazy_init()
+ self.s = []
+ self.s.append(self._screen.fill(self._MENU_BACKGROUND))
+ self._update()
while True:
- self._screen.fill(self._MENU_BACKGROUND)
+ while Gtk.events_pending():
+ Gtk.main_iteration()
+ self._update()
for box_index in range(len(self._levels)):
box_value = self._levels_rect[box_index]
- pygame.draw.rect(
+ s = pygame.draw.rect(
self._screen, self._MENU_LEVELS_RECTS_BG_COLOR,
box_value)
+ self.s.append(s)
txt = _("Level ") + str(box_index + 1)
txt_surface = self._menu_font.render(txt, True,
self._MENU_LEVELS_RECTS_TXT_COLOR)
- self._screen.blit(txt_surface,
+ s = self._screen.blit(txt_surface,
(self._levels_rect[box_index][0] +
self._MENU_LEVELS_RECTS_TXT_OFFSET[0],
self._levels_rect[box_index][1] +
self._MENU_LEVELS_RECTS_TXT_OFFSET[1]
))
- pygame.display.update()
- while Gtk.events_pending():
- Gtk.main_iteration()
+ self.s.append(s)
for event in pygame.event.get():
if event.type == QUIT: