Hey,
I’ve had a search and I couldn’t find another topic on this, but could be wrong.
I’ve seen quite a few examples of animation, for say a player sprite, and have achieved this in a project I’m working on.
However I cannot for the life of me figure out how to do this with larger then 8x8 sprites. I know how to get static ones, but no idea how to animate these larger sprites.
Thanks for any help, and sorry if that makes no sense, I’m awful at explaning!
I haven't actually tried anything like this, but what I would do is make a table (or add to the table) the 2 sprite indexes. For example:
player={
x=20,
y=126,
sp1=1, -- the top sprite
sp2=17 -- the bottom sprite
}
|
The player's x and y coordinate should be the top sprite's left corner, so you must add 8 to the y variable to draw the bottom part like this:
spr(player.sp1,player.x,player.y) spr(player.sp2,player.x,player.y+8) |
Hope that helps! ^^
Interesting! I will give this a go, see if I can figure out how to implement that. I’m not going to lie though, I struggle hardcore, so we’ll see haha
The simplest application of animations I've seen have been operations on the base sprite ID. For example, a 2x2 sprite at index 4 would need to increment its ID by 2 (the next slot of 2 sprites) to get the next frame. This happens inside a coroutine, which will keep track of when to advance and when to end. If you'd like, I can try hacking something together this evening to illustrate what I mean.
Sorry it took another day to get this done! It's a simple demo, not meant to be copy-pasted into your game. If you have any questions (and if others have improvements to suggest), please don't hesitate. I'm still learning how to do animation well, myself.
-- 16x16 animation test
-- by zlg
-- licensed under wtfpl
--[[
this demo illustrates the
basics of 16x16 sprite
animation. only left and right
buttons were implemented, to
encourage others to learn and
build on it for their own
games.
]]
-- the player class
player = {
x = 56, -- x pos
y = 64, -- y pos
bspr = 2, -- base sprite
w = 2, -- # of sprites wide
h = 2, -- # of sprites high
dx = 0, -- delta x
dy = 0, -- delta y
flip_x = false, -- obvious
tmr = 0 -- timer for animation
}
-- player constructor
function player:new(o)
self.__index = self
return setmetatable(o or {}, self)
end
--[[
a very naive function to
illustrate how sprite-based
animation can work. take this
idea and match it to your
game.
]]
function animate(o)
o.x += o.dx
o.tmr += 1
if o.tmr == 3 then
if o.bspr == 2 then
o.bspr = 4
else
o.bspr = 2
end
o.tmr = 0
end
end
function _init()
myplayer = player:new()
end
function _update60()
if btn(⬅️) then
--[[
some of this could be put
into the class itself, but
it's easier to see what's
going on this way
]]
myplayer.flip_x = false
myplayer.dx = -1.4
elseif btn(➡️) then
myplayer.flip_x = true
myplayer.dx = 1.4
else
myplayer.dx = 0
myplayer.bspr = 2
end
--[[
checking abs() means we can
act if the sprite is moving
at all.
]]
if abs(myplayer.dx) != 0 then
if not cor then
cor = cocreate(animate)
end
if cor and costatus(cor) != 'dead' then
coresume(cor, myplayer)
else
cor = nil
end
end
end
function _draw()
-- pretty standard stuff here
cls()
map(0,0)
palt(8, true)
palt(0, false)
spr(myplayer.bspr, flr(myplayer.x), myplayer.y, myplayer.w, myplayer.h, myplayer.flip_x)
pal()
print("16x16 sprite anim demo", 25, 0)
print("by zlg", 48, 8)
print("x: "..flr(myplayer.x), 0, 0)
print("y: "..myplayer.y, 0, 8)
print("the legend of zelda (c) nintendo", 0, 121)
end
|
Here's the cart itself:
I hope this helps!
EDIT: If you have animations that are more than 2 frames, you might want to store a "frame offset" that you can increment as the timer triggers, so you aren't manipulating the base sprite value itself. More advanced animations would likely depend on pre-made structures where you can pair up the timer value and the sprite offset, then run it in sequence until it does what you want it to.
This is great, Thankyou very much for doing this, I’ll take a proper look in the morning and see what I can learn from it!
[Please log in to post a comment]



