Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to create a simple top-view 2D rpg, in the style of Zelda and Secret of Mana, using PyGame. I've managed to make the beginnings of a game, with an animated character walking around. However, when I start animating attacks, I'm running into problems because the sprite with the sword slash is bigger than the walking sprite. This makes the character appear to be jumping around when attacking.

I managed to handle the problem by defining a center of gravity, so to speak, for each image, and apply a suitable offset at each frame in the animation to make the center of the character stay at the same place throughout the animation. I defined a dictionary of lists of images (instances of pygame.Surface), where I pick out the correct list by the state of the character, so for example there is one list for walking left, and then I loop over the list to get the animation. To handle the offset, I similarly created a dictionary of lists of offsets, looping over those in the same way.

However, I'm not entirely pleased with this implementation, so I'm looking for a more elegant solution.

I tried to add an attribute called offset to each instance of the pygame.Surface class, to hold the offset for each image, but the Surface class doesn't allow new attributes to be set. I then thought about subclassing pygame.Surface, which would allow me to set any attribute I wanted, but then I couldn't load my images with pygame.image.load without a lot of extra code.

I imagine everyone who makes a game with animations where the size of the sprite changes between frames would have to deal with this problem, so if anyone could suggest an elegant implementation, that would be great. If example code with PyGame is available, that would be even greater.

share|improve this question
3  
One option would be to change all of the animation images to the same size as the biggest one and re-position every sprite to be in the centre in order to avoid a "jumping" effect. –  Savlon Jan 27 '13 at 22:52
    
@Savlon I thought about that, and it might be a good solution, but it would introduce some extra problems regarding rects and collision detection, I guess. –  Tor Jan 28 '13 at 7:08
3  
Yeh It would if you were using the dimensions of the actual image file... When I do animations I have them on a spritesheet of 32x32 size tiles. However, instead of using the image file dimensions, I create a custom bounding box for my NPC's etc if they are smaller than the actual image file size. Why dont you do that? Just create custom collision boxes after repositioning all of the sprites? –  Savlon Jan 28 '13 at 7:34
    
You already have the best possible solution for a flexible width. You could only simplify it by sacrificing flexibility, for example by saying "All walking frames will be this big and all fighting sprites that big" –  API-Beast Apr 14 at 21:39

1 Answer 1

up vote 1 down vote accepted

Imagine the worst case scenario, a fighting game where each moves' frames are different in size. Some kicks have an exceptionally far reach and some even further (think Dhalsim)

enter image description here

The bounding box may be very different in each frame and so are the frame's size and the relative position point. There is no mystic way to do it. Normally to handle complex sprites' animations, one of the teams' members uses a tool to define a bounding rectangle around each frame and place a relative positioning dot in each frame. This data is saved to an xml file often but is created with a specialized tool.

share|improve this answer
1  
TexturePacker is such a specialized Tool, free and very flexible in terms of packing algorithms used and output files –  ScrambledRK Apr 15 at 6:59
    
I like Tiled (mapeditor.org) for this kind of thing too. You can use an image-layer for the sprite-sheet an object-layers for collision polygons/rects/circles etc and another one to place handles indicating the center of the sprite. –  Jan Apr 15 at 9:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.