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

Re: [pygame] Improved Sprites System - Call for Suggestions



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