Is there any way to reverse animation?
Wonder if there is way to play sprite animation in "reverse" mode?
Wonder if there is way to play sprite animation in "reverse" mode?
I want to play animation normal way first and then wait a second or two and play it in reverse way
No native way that I could find in microScript.
This is my way, though:
https://microstudio.io/Martellus/llfcspritemutations/ZPNNNXDR/
(Ignore the walking mutated wobbles... they are part of other code in the project not included in the code below).
Full code:
init = function()
s = createGameSprite("animtest")
end
update = function()
// update the frame number depending on the direction
if s.animSpeedCounter < 0 then
s.animSpeedCounter = s.animSpeed
s.onFrame += s.frameDir
if s.onFrame < 0 then
s.frameDir *= -1 // reverse the direction
s.onFrame = 0
end
if s.onFrame > s.numFrames-1 then // dont forget that -1 cause array ia zero based.
s.frameDir *= -1 // reverse the direction
s.onFrame = s.numFrames-1 // dont forget that -1 cause array ia zero based.
end
else
s.animSpeedCounter -= 1 // count down until next frame change
end
end
draw = function()
screen.clear("#000")
// draw the sprite at 0/0
s.oSprite.setFrame(s.onFrame)
screen.drawSprite(s.name,s.x,s.y,s.w,s.h)
local t = ""
if s.frameDir > 0 then t = "Forwards"else t = "Backwards" end
screen.drawText(t,0,30,10,"#FF0")
screen.drawText("All sprite frames:",0,-20,10,"#FF0")
for i = 0 to s.numFrames-1
s.oSprite.setFrame(i)
screen.drawSprite(s.name,(((s.numFrames-1)*s.w)/2)*-1+(i*s.w),-40,s.w,s.h)
end
end
// createGameSprite() :: create our own sprite wrapper
createGameSprite = function(sName)
local newS = object
oType = "sprite"
name = sName
// x,y: where to draw the sprite
x = 0
y = 0
// oSprite:: this will hold the reference to our sprite GFX
oSprite = sprites[sName]
// h,w: dimensions of the sprite
w = sprites[sName].width
h = sprites[sName].height
// animSpeed/animSpeedCounter:: how long to wait before changing the frame
animSpeed = floor(60 /sprites[sName].fps) // roughly calculated based on how often update() is called, which is normally around 60/second.
animSpeedCounter = 20 // used to track wshen we can change the frame number.
// numFrames:: number of frames - remeber, starts with 0 (zero)
numFrames = sprites[sName].frames.length
// onFrame:: which frame to show
onFrame = 0
// frameDir:: the direction the animation should run: 1 forwards, -1 backwards, and 0 (zero) for pause on the current frame!
frameDir = 1
end
return newS
end
Second method - clone the sprite into a new sprite object, and reverse the animation.
That way you can just flip between the sprites shown, and less complex code.
In the demo app, click on "2" to see the example live. https://microstudio.io/Martellus/llfcspritemutations/ZPNNNXDR/
init = function()
s = createGameSprite("animtest")
s2 = createGameSprite("animtest")
s2.hid = 1
cloneSprite(s2)
reverseAnim(s2)
end
update = function()
// nothing here
end
draw = function()
screen.clear("#000")
screen.drawText("Method 2 to reverse animation with cloned sprite",0,75,8,"#FFF")
screen.drawText("Original Sprite",-50,0,10,"#FF0")
screen.drawSprite(s.name,-50,-20,s.w,s.h)
screen.drawText("Revered Clone",50,0,10,"#FF0")
screen.drawSprite(s2.name,50,-20,s.w,s.h)
for i = 0 to s.numFrames-1
screen.drawImage(sprites[s.name].frames[i],-100,-80+i*s.h,s.w,s.h)
screen.drawSprite(sprites[s2.name].frames[i],100,-80+i*s.h,s.w,s.h)
end
end
// make a new sprite based of an existing sprite: ie a clone!
cloneSprite = function(w)
local s = sprites[w.name]
local numFrames = s.frames.length
//print(s.name+"::nf["+numFrames+"]")
local s2 = new Sprite(s.width,s.height)
if s2 then
//s2.name = s.name+"_"+w.hid
w.name = s.name+"_"+w.hid
s2.name = w.name
s2.fps = s.fps
w.oSprite = s2
sprites[w.name] = s2
//print("New>"+w.name+"<")
hue = random.nextInt(360)
for i = 0 to numFrames-1
local bf = s.frames[i]
local buffer = new Image(s.width,s.height)
buffer.drawImage(bf,0,0,s.width,s.height)
if i < s2.frames.length then
//print(s2.name+"["+i+"] ==== use existing")
local bf2 = s2.frames[i]
// bf2.drawRect(0,0,s.width,s.height,"rgb(1,1,1)")
bf2.setBlending("destination-out")
bf2.fillRect(0,0,s.width,s.height,"rgba(0,0,0,1)")
bf2.setBlending("source-over")
bf2.drawImage(buffer,0,0,s.width,s.height)
else
//print("---> push")
s2.frames.push( buffer )
end
end
end
end
// Reverse the frames
reverseAnim = function(w)
local s = sprites[w.name]
local numFrames = s.frames.length
local midPoint = floor(numFrames/2)
//print(s.name+"::nf["+numFrames+"];mix["+mix+"]")
for i = 0 to midPoint-1
local ff = s.frames[i]
s.frames[i] = s.frames[numFrames-1-i]
s.frames[numFrames-1-i] = ff
end
end
I like your second example, wonder if there is any way to clone animation in "reverse order". In this case, I imagine we can just play cloned animation normally to get "reverse" effect.
Yarko
Sure there are many ways to clone a sprite and reverse it.
Here is one quick tinker:
init = function()
tmpSpr = sprites["right"]
sprites["left"] = new Sprite(tmpSpr.width, tmpSpr.height)
newSpr = sprites["left"]
count = tmpSpr.frames.length-1
for i=0 to count
newSpr.frames[i] = tmpSpr.frames[count-i]
end
newSpr.fps = tmpSpr.fps
end
draw = function()
screen.clear()
screen.drawSprite("right",-35,0,40)
screen.drawSprite("left" , 35,0,40)
end
"right" is the sprite with the original animation. "left" will be created from that.
For sure it should be nicely wrapped up in a function :)
Live Long and Tinker
This is nice and and clear approach ! Like it, thank you for your time and code example.
Yarko