On 01.06.2012 15:29, Sagie Maoz wrote:
Suggested improvements for sprite.py:
1. Easier positioning methods: Using tuples or arrays, instead of just
Rects.
2. Setting a sprite's anchor points for handling in movement,
animation, collision etc.
3. Aggregated sprite class (basically, a sprites group which
implements the sprite interface).
4. Automated dirty rendering (existing feature in Spyral [2]).
5. New visual attributes for sprites:
- Rotation angle
- Scale
- Crop rectangle
- Visible/hidden
- Collision parameters (smaller hitbox, etc.)
6. Alternative forms of collision detecting (not limited to circles
and rectangles).
Possibly using algorithms such as quadtrees and spatial hashing.
7. Improved layering system.
8. Respecting blendmode flags are handled in all types of sprites.
9. Animated sprites:
- Setting a group of images to cycle through in a time interval.
- Animating visual attributes, a-la Kivy [3] or CSS transitions [4].
10. Events dispatching from groups to sprites.
Hi
Here my thoughts about your list:
1. the position should be two floats (wrapped either in a tuple or
vector class or just x,y attributes), but since the render position is
anyway different than the position (because of the offset/anchor) I
would suggest to calculate the render position on each draw call
(another pro for this is if you want to add subpixel rendering one day
this can be done with floats, but not with integers of the rect)
2. the sprites anchor point should be just an offset, not limited to
'topleft', 'midtop', 'topright',... and the other rect attributes
3. what would be the use case for this? the only thing I see would be a
hierarchy of sprites, so if you move the root, then all children are
moved too
4. dirty rendering is only useful if you don't scroll and if the area
covered with dirty rects is small compared to the screen, otherwise the
overhead of the dirty handling might eat the performance you want to
gain by dirty rects
5. I don't see how collision parameters fit a sprite? I think the
collision should be done on the model.... (okay, the sprite and the
model might be the same)
6. what should a sprite system really do?
7. layers are important, ideally you would have a 'z' attribute you can
change anytime in the code and that sprite is rendered at the right layer
8. blendmode flags, but also the source area
9. animation is whole other story.... I would just prepare hooks to
integrate easily an animation system. About the attributes: this would
be something to use tweens? Maybe a tweening lib would be better for
that, but as said, not sure if a sprite system should bother with that...
10. why would you bother with events in sprites? (unless the sprites is
model and rendering in one thing, which is not so good)
I think you should limit yourself to sprites stuff, not adding things
like events, animation or collision detection, which are done by an
engine. Also I'm not sure if the current implementation with groups is
the way to go. Because grouping sprites is a simple thing to do (just
use a list, for comfort a class with some methods that apply that
function to all of its sprites), but the hard thing is to have a
renderer that does implement all features and has still some performance.
Here a short list I would want for a sprite rendering system:
a. float position (if using scrolling, then you need a world_to_screen
and screen_to_world conversion methods which should be exchangable)
b. offset (anchor)
c. independent parallax factor for each axis
d. independent z layering
e. easy scrolling (deciding which sprites to draw should be done by the
engine logic because you can use so many different approaches...)
f. multiple viewports/cameras for split screen games
g. simple picking of a sprite from screen (even using scrolling/parallax)
h. hud rendering (those sprites need to be rendered differently because
no coordinate conversion is needed)
i. visibility on/off -> on should add it to the render list / off should
maybe remove the sprite from the render list (so the millions offscreen
sprites are not even known by the renderer until they are turned visible)
j. interpolated rendering (if using a fixed step update loop you might
want to render at a interpolated position, see:
http://gafferongames.com/game-physics/fix-your-timestep/ )
k. special rendering paths for special sprites, maybe you want some
sprites to use its custom 'draw' method
l. the sprite rect attribute should be in screen coordinates so you can
use it for picking (I suggest this because the number of sprites that
are in the render list is somewhat limited which makes the rect
collision methods usable, for a large world with many more entities you
dont want to use those collision method that iterate over all entities,
there you want something more clever like a quadtree or spatial hashing
as you suggested, but this is no concern of the renderer nor sprite
system because only the game logic handling the world can possibly know
which entites are in the visible area... also the collision detection
between the entities should be done by the game logic)
m. maybe an easy text sprite
n. maybe a simply group to apply some function to all of its sprites at
once (those groups might differ from the renderlist or there might be
multiple groups with overlapping contents...)
o. push/pop sprites in the render list (building a stack, is convenient
if you want to have a scene in between, just push the new sprites and
when you are done, just pop it once and the scene is rendered as before)
I admit, that I have a working implementation for most of the points I
listed here. After last pyweek I thought I need somthing that can
already do those things out of the box. I could provide some ideas for
implementation or even code for the interested.
~DR0ID