Dirty Rectangles are useful in turn-based movement…

Using dirty rectangles to only update the portions of the screen that actively change between screen refreshings make it so that I can get a constant ~33 fps while changing the view. I think if I can iron this system out I can make this even faster. 😀

Alrighty. I guess you could say this is a tutorial–or more just a drawn out explanation and insight into how my brain is so screwed up.  For those that don’t know, this at point #6 describes how dirty rectangles work.  Mine is slightly different, however.

So I’ve got a 32×24 grid of “tile” objects that represent each visible tile on the screen.  On that grid, each tile has a property called Dirty, and each tile is inside of a group. The basic process previously focused on a function called GenerateView, which was pretty straightforward, in that every time the player moves, all of the tiles are re-drawn on the screen, a simple and effective brute force method.

What I have going now, is this, with the initial condition is that Tile defaults to not Dirty:
step1: GenerateView():
Find out what symbol the tile will become
is the symbol the same or different to what Tile currently is?
If same: change worldcoords, done, dirty status is correct (not Dirty)
if different: change world coords, assert tile’s Dirty, add it to tileGroup.

Step 2: each Tile calls its update():
if Dirty: make not Dirty
if not Dirty: remove from tileGroup.

-so in effect, tileGroup now only contains all tiles that are asserted to be Dirty.

Step 3: tileGroup.drawTiles:
any sprite that was previously not dirty is no longer in the group, so those guys are not blitted.

(Step 4): Draw Player/entities on screen

that handles changes in the underlaying map. What of the objects on top of the map? Simple, assert dirty on the current square something is before it moves!

Step 0: entity movement:
handle input(move):
assert current Tile = Dirty, add tile to Tilegroup
move the player etc

Step 1:

So I’m sort of half doing it. I need some way to pass a list of rects through to the main Play.py and call update(rects) to get full dirty-rect stuff going, but if I run into speed problems again I suppose I’ll do that. Currently my entire Scene class object gets pushed through Player, though, and my OCD makes me want to change that. I probably wont, though.

And I just realized something. For monsters, items, anything like that, every single time the player inputs something that tile automatically becomes dirty. That means that instead of handling it within the player movement code, I can probably bring it out to somewhere more sensible in Scene, and then from that, when I implement monsters and items, I can just have it so that every time the player moves, each monster and item tile it rests on is asserted dirty.

And now Scene has an assertDirty() function. How..appropriate. Replace step 0 above with a step 6. Once the screen is flipped, any tile the player is now standing on is asserted dirty there. Its also now in such a way that I can loop through monsters/items that may also happen to be standing on some tiles.

So, what’s the net result? A jump from 17 frames per second to around 33 on my machine when continuously scrolling. 🙂


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: