Animations and Jumper

Hi all. I am new to corona and game coding in general . I have managed to implement Jumper into my game and I am now trying to set up character animation based on the character moving. The following 2 functions are what handle this. However I can not seem to get the sequence to change, any help would be appreciated.

function setPlayerAnimationSequence(sx, sy, x, y) player.asset:pause() if x \> sx then player.asset:setSequence( "move\_left" ) print("move\_left") elseif x \< sx then player.asset:setSequence( "move\_right" ) print("move\_right") elseif y \> sy then player.asset:setSequence( "move\_down" ) print("move\_down") elseif y \< sy then player.asset:setSequence( "move\_up" ) print("move\_up") end player.asset:play() end -- "movePlayer()" function movePlayer() local function movePlayerEnded() isCurrentlyMoving = false startX, startY = endX, endY player.asset:pause() end isCurrentlyMoving = true -- Calculate using Jumper Pathfinding local path = myFinder:getPath(startX, startY, endX, endY) local delay = 0 local time = 300 local pathcount = 0 if path then for node, count in path:nodes() do pathcount = pathcount + 1 transition.to( player.asset, {delay = delay, time = time, x = (node.x \* gridAssetSize) - 32 , y = (node.y \* gridAssetSize) - 32} ) --setPlayerAnimationSequence(startX, startY, node.x, node.y) timer.performWithDelay( delay, setPlayerAnimationSequence(startX, startY, node.x, node.y) ) delay = delay + time end timer.performWithDelay( pathcount \* time, movePlayerEnded ) end end

Hi @aaron.rackley9,

Can you please post the code where you set up the animation sequences and the sprite for the player, so we can relate the two aspects of this game?

Thanks,

Brent

I hope this helps. 

function CharacterClass:loadAsset(imagesheet\_name, frameIndex) local sheetName = imagesheet\_name local sheetInfo = require(sheetName) local myImageSheet = graphics.newImageSheet( sheetName .. ".png", sheetInfo:getSheet() ) local sequenceData = { {name="move\_up", start=1, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_right", start=4, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_down", start=7, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_left", start=10, count=3, loopCount = 0} -- Optional ; default is 0 (loop indefinitely) } self.asset = display.newSprite( myImageSheet , sequenceData) end

I seem to be getting the animation to change only once. It does not seem to change each time the setPlayerAnimationSequence function is called.

Do you have this code/project set up under a Composer or Storyboard structure?

The project is currently using the Composer structure.

Hi Aaron,

So when you say the change happens only once, does that mean, it only happens when the scene first loads or something similar? If so, it may be that you’ve nested the function inside one of the core Composer scene handler functions, and so later it’s out of scope from wherever you’re trying to call it. Or, the set sequence function doesn’t know what “player” is for a similar reason (out of scope from where you’ve declared it).

Brent

Ok. I have been messing around with my code for the last few days and I have got to a stage that almost works. I am using the two following functions to move my player and animate it.

The problem is as follows. You can see that I am queueing up animation changes using delays. However it seems that the code only executes the last one in the chain and not all of them. :frowning: any ideas. 

- "setPlayerAnimationSequence()" function setPlayerAnimationSequence(pathcount) player.asset:pause() local direction = endVector:copy() direction:sub(startVector) direction:normalize() if direction.x \> direction.y then if direction.x \> 0 then player.asset:setSequence( "move\_right" ) else player.asset:setSequence( "move\_up" ) end else if direction.y \> 0 then player.asset:setSequence( "move\_down" ) else player.asset:setSequence( "move\_left" ) end end player.asset:play() end -- "movePlayer()" function movePlayer() isCurrentlyMoving = true local path = myFinder:getPath(startVector.x, startVector.y, endVector.x, endVector.y) local delay = 0 local time = 300 local pathcount = 0 local function movePlayerEnded() isCurrentlyMoving = false player.asset:pause() end local timers = {} if path then for node, count in path:nodes() do pathcount = pathcount + 1 endVector:set(node.x, node.y) transition.to( player.asset, {delay = delay, time = time, x = (endVector.x \* gridAssetSize) - 32 , y = (endVector.y \* gridAssetSize) - 32} ) timers[pathcount] = timer.performWithDelay( delay, setPlayerAnimationSequence(pathcount) ) delay = delay + time startVector:set(endVector.x, endVector.y) end timer.performWithDelay( pathcount \* time, movePlayerEnded ) else isCurrentlyMoving = false end end

Hi Aaron,

I don’t see anything wrong with how you’re setting sequences, so the issue must be in those “vector” things you’re doing, and since they’re coming from Jumper, I don’t know what those functions do. Whatever is happening there, it’s somehow not getting the correct cases, and it’s defaulting to the last case, or if it doesn’t even find that, Corona will default to the first sequence that was set up.

I suggest you use print() statements to see exactly what’s happening and what values are being set before your conditional checks.

Brent

I forked the Jumper library that Ronald Yonaba put out (https://github.com/pancsoftware/Jumper) and it includes path-tracking, moving a character (actor) and identifying movement direction. It might help out in this project. I am going to put together a tutorial shortly.

I have still been unsuccessful in getting it to work properly here is a video showing what is happening when I move the player. 

https://www.youtube.com/watch?v=NRHdLnHXczM&list=UU_lolywqfxR1IFKE-8GdnBw

As you can see when it queues the animations up for some reason it only plays the last one in the list and not all of them… 

I went ahead and created that tutorial for Jumper that I was talking about before. I strongly suggest you check it out for more info about the Jumper tech.

Specific to your problem, the pathfinding function doesn’t step through every step in the path. It just calculates the pathfinding needed and then executes it. You need to separate the animation function/movement function from the pathfinding function itself. My github fork has everything working the way you are attempted to have it run, so check it out and let me know if you have any questions.

EDIT: Here’s the gist explaining the movement logic:

 local function movePlayer() -- moving actor with this function. It is called on a repeated timer and stops after the end is reached, as defined by the timer with the Lua closure below. print("BEING CALLED NOW") if movingHere then print("number of values in setX is "..#setX) print("number of values in setY is "..#setY) print("aMX value is "..aMX) print("aMY value is "..aMY) print("setX = "..setX[aMX]) print("setY = "..setY[aMY]) print("-------------------") hero.x = cellb[setY[aMX]][setX[aMY]].x hero.y = cellb[setY[aMX]][setX[aMY]].y cellb[setY[aMX]][setX[aMY]]:setFillColor(.5,0,.25) flipSize(cellb[setY[aMX]][setX[aMY]]) aMX = aMX+1 aMY = aMY+1 if setX[aMX-2] and (setX[aMX-1] \> setX[aMX-2]) then hero:setFillColor(1,1,0) end if setX[aMX+2] and (setX[aMX+1] \> setX[aMX+2]) then hero:setFillColor(1,0,1) end if setY[aMY-2] and (setY[aMY-1] \> setY[aMY-2]) then hero:setFillColor(.5,0,.5) end if setY[aMY+2] and (setY[aMY+1] \> setY[aMY+2]) then hero:setFillColor(0,.5,1) end --return true end end

Hi @aaron.rackley9,

Can you please post the code where you set up the animation sequences and the sprite for the player, so we can relate the two aspects of this game?

Thanks,

Brent

I hope this helps. 

function CharacterClass:loadAsset(imagesheet\_name, frameIndex) local sheetName = imagesheet\_name local sheetInfo = require(sheetName) local myImageSheet = graphics.newImageSheet( sheetName .. ".png", sheetInfo:getSheet() ) local sequenceData = { {name="move\_up", start=1, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_right", start=4, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_down", start=7, count=3, loopCount = 0}, -- Optional ; default is 0 (loop indefinitely) {name="move\_left", start=10, count=3, loopCount = 0} -- Optional ; default is 0 (loop indefinitely) } self.asset = display.newSprite( myImageSheet , sequenceData) end

I seem to be getting the animation to change only once. It does not seem to change each time the setPlayerAnimationSequence function is called.

Do you have this code/project set up under a Composer or Storyboard structure?

The project is currently using the Composer structure.

Hi Aaron,

So when you say the change happens only once, does that mean, it only happens when the scene first loads or something similar? If so, it may be that you’ve nested the function inside one of the core Composer scene handler functions, and so later it’s out of scope from wherever you’re trying to call it. Or, the set sequence function doesn’t know what “player” is for a similar reason (out of scope from where you’ve declared it).

Brent

Ok. I have been messing around with my code for the last few days and I have got to a stage that almost works. I am using the two following functions to move my player and animate it.

The problem is as follows. You can see that I am queueing up animation changes using delays. However it seems that the code only executes the last one in the chain and not all of them. :frowning: any ideas. 

- "setPlayerAnimationSequence()" function setPlayerAnimationSequence(pathcount) player.asset:pause() local direction = endVector:copy() direction:sub(startVector) direction:normalize() if direction.x \> direction.y then if direction.x \> 0 then player.asset:setSequence( "move\_right" ) else player.asset:setSequence( "move\_up" ) end else if direction.y \> 0 then player.asset:setSequence( "move\_down" ) else player.asset:setSequence( "move\_left" ) end end player.asset:play() end -- "movePlayer()" function movePlayer() isCurrentlyMoving = true local path = myFinder:getPath(startVector.x, startVector.y, endVector.x, endVector.y) local delay = 0 local time = 300 local pathcount = 0 local function movePlayerEnded() isCurrentlyMoving = false player.asset:pause() end local timers = {} if path then for node, count in path:nodes() do pathcount = pathcount + 1 endVector:set(node.x, node.y) transition.to( player.asset, {delay = delay, time = time, x = (endVector.x \* gridAssetSize) - 32 , y = (endVector.y \* gridAssetSize) - 32} ) timers[pathcount] = timer.performWithDelay( delay, setPlayerAnimationSequence(pathcount) ) delay = delay + time startVector:set(endVector.x, endVector.y) end timer.performWithDelay( pathcount \* time, movePlayerEnded ) else isCurrentlyMoving = false end end

Hi Aaron,

I don’t see anything wrong with how you’re setting sequences, so the issue must be in those “vector” things you’re doing, and since they’re coming from Jumper, I don’t know what those functions do. Whatever is happening there, it’s somehow not getting the correct cases, and it’s defaulting to the last case, or if it doesn’t even find that, Corona will default to the first sequence that was set up.

I suggest you use print() statements to see exactly what’s happening and what values are being set before your conditional checks.

Brent

I forked the Jumper library that Ronald Yonaba put out (https://github.com/pancsoftware/Jumper) and it includes path-tracking, moving a character (actor) and identifying movement direction. It might help out in this project. I am going to put together a tutorial shortly.

I have still been unsuccessful in getting it to work properly here is a video showing what is happening when I move the player. 

https://www.youtube.com/watch?v=NRHdLnHXczM&list=UU_lolywqfxR1IFKE-8GdnBw

As you can see when it queues the animations up for some reason it only plays the last one in the list and not all of them…