diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2014-06-23 14:34:28 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2014-06-23 14:34:28 (GMT) |
commit | 8237835c1942103074adae8c7ba5bde469bccf55 (patch) | |
tree | 545a5f6652114e08c5b00cdf2e27a32749b8ac7a | |
parent | 42787b3c1547996bca94a42346a2cf11dace888c (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.py | 61 |
1 files changed, 58 insertions, 3 deletions
@@ -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 |