Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2014-06-23 14:34:28 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2014-06-23 14:34:28 (GMT)
commit8237835c1942103074adae8c7ba5bde469bccf55 (patch)
tree545a5f6652114e08c5b00cdf2e27a32749b8ac7a
parent42787b3c1547996bca94a42346a2cf11dace888c (diff)
Revert "Removed all the code used to calculate dirty regions"
This reverts commit dba0488ae9ab21c87bc840eab6bb3b79223c3cd7. With really big mazes, the performance is not good.
-rw-r--r--game.py61
1 files changed, 58 insertions, 3 deletions
diff --git a/game.py b/game.py
index 96e3d1d..5222e82 100644
--- a/game.py
+++ b/game.py
@@ -171,9 +171,14 @@ class MazeGame(Gtk.DrawingArea):
self.finish_time = None
for player in self.allplayers:
player.reset()
+ self.dirtyRect = self.maze.bounds
+ self.dirtyPoints = []
self.maze.map[self.maze.width - 2][self.maze.height - 2] = \
self.maze.GOAL
+ # clear and mark the whole screen as dirty
+ # TODO
+ # self.screen.fill((0, 0, 0))
self.queue_draw()
self.mouse_in_use = 0
if self._ebook_mode_detector.get_ebook_mode():
@@ -181,6 +186,12 @@ class MazeGame(Gtk.DrawingArea):
self.close_finish_window()
def __draw_cb(self, widget, ctx):
+ """Draw the current state of the game.
+ This makes use of the dirty rectangle to reduce CPU load."""
+ # TODO
+ # if self.dirtyRect is None and len(self.dirtyPoints) == 0:
+ # return
+
# compute the size of the tiles given the screen size, etc.
allocation = self.get_allocation()
@@ -225,9 +236,24 @@ class MazeGame(Gtk.DrawingArea):
ctx.fill()
ctx.restore()
- for x in range(0, self.maze.width):
- for y in range(0, self.maze.height):
- drawPoint(x, y)
+ # re-draw the dirty rectangle
+ if self.dirtyRect is not None:
+ # compute the area that needs to be redrawn
+ left = max(0, self.dirtyRect.x)
+ right = min(self.maze.width,
+ self.dirtyRect.x + self.dirtyRect.width)
+ top = max(0, self.dirtyRect.y)
+ bottom = min(self.maze.height,
+ self.dirtyRect.y + self.dirtyRect.height)
+
+ # loop over the dirty rect and draw
+ for x in range(left, right):
+ for y in range(top, bottom):
+ drawPoint(x, y)
+
+ # re-draw the dirty points
+ # for x, y in self.dirtyPoints:
+ # drawPoint(x, y)
main_player = self.localplayers[0]
# draw all players
@@ -237,6 +263,11 @@ class MazeGame(Gtk.DrawingArea):
# draw last the main player
main_player.draw(ctx, self.bounds, self.tileSize)
+ # clear the dirty rect so nothing will be drawn until there is a change
+ # TODO
+ # self.dirtyRect = None
+ # self.dirtyPoints = []
+
def set_show_trail(self, show_trail):
if self._show_trail != show_trail:
self._show_trail = show_trail
@@ -245,6 +276,19 @@ class MazeGame(Gtk.DrawingArea):
else:
return False
+ def markRectDirty(self, rect):
+ """Mark an area that needs to be redrawn. This lets us
+ play really big mazes without needing to re-draw the whole
+ thing each frame."""
+ if self.dirtyRect is None:
+ self.dirtyRect = rect
+ else:
+ self.dirtyRect.union_ip(rect)
+
+ def markPointDirty(self, pt):
+ """Mark a single point that needs to be redrawn."""
+ self.dirtyPoints.append(pt)
+
def _ebook_mode_changed_cb(self, detector, ebook_mode):
if ebook_mode:
self._activity.show_accelerator_alert()
@@ -385,6 +429,8 @@ class MazeGame(Gtk.DrawingArea):
oldposition = player.position
newposition = player.animate(self.maze, change_direction)
if oldposition != newposition:
+ self.markPointDirty(oldposition)
+ self.markPointDirty(newposition)
if player in self.localplayers:
self.maze.map[player.previous[0]][player.previous[1]] = \
self.maze.SEEN
@@ -412,6 +458,7 @@ class MazeGame(Gtk.DrawingArea):
self.remoteplayers[buddy.get_key()] = player
self.allplayers.append(player)
self.allplayers.extend(player.bonusPlayers())
+ self.markPointDirty(player.position)
def _send_maze(self, player):
# tell them which maze we are playing, so they can sync up
@@ -431,8 +478,10 @@ class MazeGame(Gtk.DrawingArea):
if buddy.get_key() in self.remoteplayers:
player = self.remoteplayers[buddy.get_key()]
logging.debug("Leave: %s", player.nick)
+ self.markPointDirty(player.position)
self.allplayers.remove(player)
for bonusplayer in player.bonusPlayers():
+ self.markPointDirty(bonusplayer.position)
self.allplayers.remove(bonusplayer)
del self.remoteplayers[buddy.get_key()]
@@ -492,14 +541,20 @@ class MazeGame(Gtk.DrawingArea):
elif message.startswith("move:"):
# a player has moved
x, y, dx, dy = message[5:].split(",")[:5]
+
+ self.markPointDirty(player.position)
player.position = (int(x), int(y))
player.direction = (int(dx), int(dy))
+ self.markPointDirty(player.position)
self.player_walk(player)
elif message.startswith("step:"):
# a player has moved using the accelerometer
x, y, dx, dy = message[5:].split(",")[:5]
+
+ self.markPointDirty(player.position)
player.position = (int(x), int(y))
player.direction = (int(dx), int(dy))
+ self.markPointDirty(player.position)
self.player_walk(player, False)
elif message.startswith("maze:"):
# someone has a different maze than us