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:
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:
assert current Tile = Dirty, add tile to Tilegroup
move the player etc
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. 🙂