[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] sprite engine



Brian Fisher schrieb:
On 4/28/06, Kamilche <klachemin@xxxxxxxxxxx> wrote:
Uh, not so! If I have a background, then a tree, then a ghost in front
of the tree that's translucent, and something about the tree changes...
i dirty only the tree. The 'go through sprites in zorder and draw if it
intersects the dirty rectangle' bit in the main render loop is what
draws the background, tree, AND ghost, though only the tree got 'dirty.'

The method of only drawing sprites where they are dirty (i.e. they
animated or move) you can save quite a lot of time with the right
game, but if you have moving objects behind your static ones, you need
to worry about marking places dirty both before and after you draw if
you want to get things drawn right, in all cases...

For example, what happens when the ghost moves behind the tree? In
that case, the ghost didn't dirty any part of the tree
Huh? When the Gohst moves or changes layer (!) it procudes a dirty screen area and after that all sprites are checked for collision with that area and if they do then redraw them (natrurally in the right order). So the tree gets repainted right. ( and no flickering occures and tree has not to be flaged dirty)

perhaps it helps to see thing from another point of view:

any dirty rect will produce a dirty screen update area. so after a frame was calculated (moving object, ...) and befor one goes to redraw the sprites, the screen is like a mask: imagine the screen as when the dirty screen areas had been cut out off the screen ( or fill the dirty screen areas with a color (e.g. like pink(255,0,255) or white or what ever)) . Now it should be clear that everything that has a part (even it is only 1 pixel) overlaping has to be redrawen (I dont have to mention in the right order). So why should the tree not redraw? (the tree must not be make dirty to redraw it!! just the fact he overlap with a dirty screen area is enough to redraw it) So why should that flicker?

when he drew
the last frame, so next frame the tree won't redraw (even though he
should draw on top of the ghost) If the ghost then draws himself
(either because he knew he's animating, or because he overlapped his
last dirty rect) he'll draw on top of the tree. While it will likely
be fixed next frame, and for a 60 fps game the layer won't likely have
the slightest idea what happened, the human eye is usually very good
at detecting flicker because we are wired to detect motion that we
aren't directly focusing on, so it can end up being a quite odd little
distracting thing.

Basically, my opinion on the more sophisticated dirty rect stuff
(where you avoid drawing your sprites when they are the same from
frame to frame) is that they can be very hard to be flicker free and
bug free in all cases. Even though those approaches can get rather
incredible frame rates with software-only rendering,  I perfer to
avoid using approaches like that in favor of figuring out what simple
game-specific constraints you can exploit in a simple and provably
reliable way (like maybe you can preflatten a bunch of static objects
in a layer and erase to that, etc.) because I really dislike having to
fix graphical bugs and flicker (it's quite hard to write unit tests
for them, for instance)

I have appended two images: the mask mentioned abouve. the pink area has to be redrawen
and the other image: the different colors of the rect has this meanings (its from my debug modus):

orange = oldrect (old  position)
green = new position
red = dirty screen area ( efective area that is updated on screen)
blue = sprites that a redrawn ( better blittet again on screen)

~DR0ID

PNG image

PNG image