kikito / anim8

An animation library for LÖVE
MIT License
730 stars 88 forks source link

Add support for SpriteBatches #15

Closed Bobbyjoness closed 8 years ago

Bobbyjoness commented 8 years ago

SpriteBatches is an object in love to help speed up the rendering of an image if used tons of times. The reason Anim8 could use this is because if I wanted to render 50 animated enenmies with anim8 it will be 50 separate draw calls. If Anim8 supported spritebatches this could be one draw call.

zorggn commented 8 years ago

The issue is, with multiple images to draw, anim8 can, at the moment, only work in one way, which is to draw them one-by-one in a loop. Since spritebatches can hold more than one (quad based sub-)image inside them, giving back an id number when defining one for the SB, and the fact that one draws all of the added sprites at once, hooking anim8 up with spritebatches would be a neat thing. With those id numbers saved, one can use the :set method of the spritebatch to modify the parameters for the sprites separately, and even "delete" them. Not sure whether this is implementable in a nice way or not.

kikito commented 8 years ago

Ok so let me see if I got this right.

Currently there is only one way to "draw" animations - with the "draw" function:

animation:draw(image, x,y, angle, sx, sy, ox, oy)

What is needed is some other function which, instead of drawing the animation in the current canvas, adds it to a spritebatch. I'm thinking about this:

id = animation:addToSpriteBatch(spriteBatch, x,y, angle, sx, sy, ox, oy, kx, ky)

This will basically call spriteBatch:add with the current animation frame (a quad) and the given parameters(x, y, angle, etc).

Have I understood this correctly?

If I have, then probably I can overload animation:draw so that it works with both images and spritebatches - if you pass it an image as the first parameter it will draw the quad in the current canvas. If you pass a spritebatch, it will add the current frame to it.

Sounds good?

zorggn commented 8 years ago

Sounds almost perfect, except that animation:draw's spritebatch overload should call spritebatch:set instead of spritebatch:add. Reason being is that we already added an instance of an animation to the batch, but we want to animate - or in other words, modify - the already existing sprite in the batch, not create another. (in other words, " it will add the current frame to it." -> "it will modify the sprite given by its id, to the animation's current frame.") Or something like that.

kikito commented 8 years ago

I have given this another thought. What about just giving the animation a getCurrentFrame() method? This way it's possible to add them, or set them on spritebatches. And the animation interface remains oblivious to them. But still supports them.

Would this be acceptable?

zorggn commented 8 years ago

I believe it to be so.

kikito commented 8 years ago

@zorggn @Bobbyjoness:

Thanks a lot for your feedback. I have almost everything set up, I just need a final confirmation, since I found a complication: animations can be flipped horizontally and vertically.

This means that when you draw them (and when you add/set them on a spritebatch) the parameters must change. For example, if the animation is flipped horizontally, sx must be -1 instead of 1. And so on.

sx and sy are straightforward, but ox,oy,kx & ky are a bit more complex to calculate correctly. I wanted anim8 to do this for you (so you could treat an animation just like a quad).

In order to solve this, I have implemented a function called animation:getFrameInfo. You pass it "the parameters what you would normally pass love.graphics.draw, or spritebatch:add, if you didn't know the animations could be flipped". And it does the transformations for you, and returns you the correct parameters. Here's how you use it with spritebatches:

local id = spriteBatch:add(animation:getFrameInfo(x,y,r,sx,sy,ox,oy,kx,ky))

...

spriteBatch:set(id, animation:getFrameInfo(x,y,r,sx,sy,ox,oy,kx,ky))

All this is visible in this pull request (I have added some minor features, like better support for shearing). It is not in master yet. I wanted to check with you guys before I did it.

Does this sound logical/appropriate to you, or am I missing anything?

kikito commented 8 years ago

Hi again,

I decided to just make a test example to see if spritebatches and the new shearing code worked correctly.

It does! It can be found in the spritebatch-demo branch.

Since it seems to work just fine, I have decided to merge into master and release a new version of anim8.

The library is now a bit better thanks to you - cheers!

For now, I will be closing this issue