Page 1 of 1

Animation out of sync?

Posted: Tue Nov 13, 2018 7:02 pm
by xpali2
Hello again..

I am making an animation for a simple game character, of whom the arms are a separate quad from the body and I have encountered a glitch I don't seem to be able to solve by looking at my code. GIF of the glitch: https://ibb.co/hJwBh0 -- Note that the glitch doesn't happen when the character moves laterally.

The code I have is shown below. I have already tried to update the frameArmTime and currentArmQuad to fit the one that the body animation has once if you walk up or down(since these animations do not have animated arms) But this did not resolve the issue. The only thing I could think about doing is to reset the currentQuad number when the character goes back to "idle" status but I wouldn't know how to go about doing that.

Thanks for having a look

Xpali2

Code: Select all

local frameTime = 0
local frameArmTime = 0

function player_load()
  idle = love.graphics.newImage("Player/KnightlyIdle.png")
  unarmedRun = love.graphics.newImage("Player/Knightlyunarmedrunningcycle.png")
  armedRun = love.graphics.newImage("Player/Knightlyarmedruncycle.png")
  verticalRun = love.graphics.newImage("Player/KnightlyFrontandBackRunAnimation.png")
  attackblockArms = love.graphics.newImage("Player/Knightlyattackandblockarms.png")
  player = {
    Animations = {
  idleQuads = {
    love.graphics.newQuad(0, 0, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(32, 0, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(64, 0, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(96, 0, 32, 32, idle:getDimensions())
  },
  idleArmQuads = {
    love.graphics.newQuad(0, 64, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(32, 64, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(64, 64, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(96, 64, 32, 32, idle:getDimensions())
  },
  idleArmedQuads = {
    love.graphics.newQuad(0, 32, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(32, 32, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(64, 32, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(96, 32, 32, 32, idle:getDimensions())
  },
  idleArmedArmQuads= {
    love.graphics.newQuad(0, 96, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(32, 96, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(64, 96, 32, 32, idle:getDimensions()),
    love.graphics.newQuad(96, 96, 32, 32, idle:getDimensions())
  },
  runQuads = {
    love.graphics.newQuad(0, 0, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(32, 0, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(64, 0, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(96, 0, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(0, 32, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(32, 32, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(64, 32, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(96, 32, 32, 32, unarmedRun:getDimensions())
  },
  runQuadsArms = {
    love.graphics.newQuad(0, 64, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(32, 64, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(64, 64, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(96, 64, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(0, 96, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(32, 96, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(64, 96, 32, 32, unarmedRun:getDimensions()),
    love.graphics.newQuad(96, 96, 32, 32, unarmedRun:getDimensions())
  },
  armedRunQuads = {
    love.graphics.newQuad(0, 0, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(32, 0, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(64, 0, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(96, 0, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(0, 32, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(32, 32, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(64, 32, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(96, 32, 32, 32, armedRun:getDimensions())
  },
  armedRunQuadsArms = {
    love.graphics.newQuad(0, 64, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(32, 64, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(64, 64, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(96, 64, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(0, 96, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(32, 96, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(64, 96, 32, 32, armedRun:getDimensions()),
    love.graphics.newQuad(96, 96, 32, 32, armedRun:getDimensions())
  },
  vRunQuadsDown = {
    love.graphics.newQuad(0, 0, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(32, 0, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(64, 0, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(96, 0, 32, 32, verticalRun:getDimensions())
  },
  vRunQuadsUp = {
    love.graphics.newQuad(0, 64, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(32, 64, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(64, 64, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(96, 64, 32, 32, verticalRun:getDimensions())
  },
  vArmedRunQuadsDown = {
    love.graphics.newQuad(0, 32, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(32, 32, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(64, 32, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(96, 32, 32, 32, verticalRun:getDimensions())  
  },
  vArmedRunQuadsUp = {
    love.graphics.newQuad(0, 96, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(32, 96, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(64, 96, 32, 32, verticalRun:getDimensions()),
    love.graphics.newQuad(96, 96, 32, 32, verticalRun:getDimensions())
  },
  blockArms = {
    love.graphics.newQuad(0, 32, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(32, 32, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(64, 32, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(96, 32, 32, 32, attackblockArms:getDimensions())
  },
  attackArms = {
    love.graphics.newQuad(0, 0, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(32, 0, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(64, 0, 32, 32, attackblockArms:getDimensions()),
    love.graphics.newQuad(96, 0, 32, 32, attackblockArms:getDimensions())
  },
 },
currentQuad = 1,
currentArmQuad = 1,
x = 400,
y = 300,
xoffset = 16,
yoffset = 16,
hp = 100,
dmg = 25,
status = "idle",
armStatus = "idle",
isArmed = false,
lateralMovement = false,
yscale = 1,
xscale = 1,
speed = 80
}
end

function player_draw()
  if player.status == "idle" then
  love.graphics.draw(idle, player.Animations.idleQuads[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  love.graphics.draw(idle, player.Animations.idleArmQuads[player.currentArmQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  
elseif player.status == "runleft" then
  love.graphics.draw(unarmedRun, player.Animations.runQuads[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  love.graphics.draw(unarmedRun, player.Animations.runQuadsArms[player.currentArmQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  
elseif player.status == "runright" then
  love.graphics.draw(unarmedRun, player.Animations.runQuads[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  love.graphics.draw(unarmedRun, player.Animations.runQuadsArms[player.currentArmQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  
elseif player.status == "runup" then
  love.graphics.draw(verticalRun, player.Animations.vRunQuadsUp[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
  
elseif player.status == "rundown" then
  love.graphics.draw(verticalRun, player.Animations.vRunQuadsDown[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
elseif player.status == "idlearmed" then
  love.graphics.draw(idle, player.Animations.idleArmedQuads[player.currentQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
end
if player.armStatus == "idlearmedarms" then
  love.graphics.draw(idle, player.Animations.idleArmedArmQuads[player.currentArmQuad], player.x - player.xoffset, player.y - player.yoffset, 0, player.xscale, player.yscale)
end
end

function player_update(dt)
  
  if love.keyboard.isScancodeDown("a") then
    player.x = player.x - player.speed * dt
  end
  if love.keyboard.isScancodeDown("d") then
    player.x = player.x + player.speed * dt
  end
  if love.keyboard.isScancodeDown("w") then
    player.y = player.y - player.speed * dt
  end
  if  love.keyboard.isScancodeDown("s") then
    player.y = player.y + player.speed * dt
  end
  
  
if love.keyboard.isScancodeDown("a") then
  lateralMovement = true
   if player.isArmed == false then
    player.status = "runleft"
    player.xscale = -1
    player.xoffset = -16
   elseif player.isArmed == true then
    player.status = "runleftarmed"
    player.xscale = -1
    player.xoffset = -16
  end
  else lateralMovement = false
  end

if love.keyboard.isScancodeDown("w") then
  if player.isArmed == false and lateralMovement == false then
    player.status = "runup"
    player.xscale = 1
    player.xoffset = 16
  elseif player.isArmed == true then
    player.status = "runuparmed"
    player.xscale = 1
    player.xoffset = 16
    end
end
  
if love.keyboard.isScancodeDown("s") then
  if player.isArmed == false and lateralMovement == false then
    player.status = "rundown"
    player.xscale = 1
    player.xoffset = 16
  elseif player.isArmed == true then
    player.status = "rundownarmed"
    player.xscale = 1
    player.xoffset = 16
    end
end

if love.keyboard.isScancodeDown("d") then
  lateralMovement = true
   if player.isArmed == false then
    player.status = "runright"
    player.xscale = 1
    player.xoffset = 16
   elseif player.isArmed == true then
    player.status = "runrightarmed"
    player.xscale = 1
    player.xoffset = 16
   end
   else lateralMovement = false
end

if not love.keyboard.isScancodeDown("a") and not love.keyboard.isScancodeDown("w") and not love.keyboard.isScancodeDown("d") and not love.keyboard.isScancodeDown("s") then
  if player.isArmed == false then
    player.status = "idle"
    player.armStatus = "idle"
  elseif player.isArmed == true then
    player.status = "idlearmed"
    player.armStatus = "idlearmedarms"
  end
end

if love.keyboard.isScancodeDown("a") and love.keyboard.isScancodeDown("d") then
    if player.isArmed == false then
    player.status = "idle"
    player.armStatus = "idle"
  elseif player.isArmed == true then
    player.status = "idlearmed"
    player.armStatus = "idlearmedarms"
  end
end

if love.keyboard.isScancodeDown("w") and love.keyboard.isScancodeDown("s") then
    if player.isArmed == false then
    player.status = "idle"
    player.armStatus = "idle"
  elseif player.isArmed == true then
    player.status = "idlearmed"
    player.armStatus = "idlearmedarms"
  end
end

if love.keyboard.isScancodeDown("a") and love.keyboard.isScancodeDown("d") and love.keyboard.isScancodeDown("w") then
  if player.isArmed == false then
    player.status = "runup"
    player.armStatus = "runup"
  elseif player.isArmed == true then
    player.status = "runuparmed"
    player.armStatus = "runuparmedarms"
  end
end

if love.keyboard.isScancodeDown("a") and love.keyboard.isScancodeDown("d") and love.keyboard.isScancodeDown("s") then
  if player.isArmed == false then
    player.status = "rundown"
    player.armStatus = "rundown"
  elseif player.isArmed == true then
    player.status = "rundownarmed"
    player.armStatus = "rundownarmedarms"
  end
end
  
  
  if player.status == "runleft" then
     frameTime = frameTime + dt
  for i, v in pairs(player.Animations.runQuads) do
    if frameTime > 0.1 then
      player.currentQuad = player.currentQuad + 1
      frameTime = 0
    elseif player.currentQuad > 8 then
      player.currentQuad = 1
      end
    end
  end
  
  if player.status == "runleft" then
    frameArmTime = frameArmTime + dt
    for i, v in pairs(player.Animations.runQuadsArms) do
      if frameArmTime > 0.1 then
      player.currentArmQuad = player.currentArmQuad + 1
      frameArmTime = 0
    elseif player.currentArmQuad > 8 then
     player.currentArmQuad = 1
    end
  end
end

if player.status == "runright" then
  frameTime = frameTime + dt
  for i, v in pairs(player.Animations.runQuads) do
    if frameTime > 0.1 then
      player.currentQuad = player.currentQuad + 1
      frameTime = 0
    elseif player.currentQuad > 8 then
      player.currentQuad = 1
    end
  end
end

if player.status == "runright" then
  frameArmTime = frameArmTime + dt
  for i, v in pairs(player.Animations.runQuadsArms) do
      if frameArmTime > 0.1 then
        player.currentArmQuad = player.currentArmQuad + 1
        frameArmTime = 0
      elseif player.currentArmQuad > 8 then
        player.currentArmQuad = 1
      end
    end
  end
  
  if player.status == "runup" then
    frameTime = frameTime + dt
    for i, v in pairs(player.Animations.vRunQuadsUp) do
      if frameTime > 0.2 then
        player.currentQuad = player.currentQuad + 1
        frameTime = 0
      elseif player.currentQuad > 4 then
        player.currentQuad = 1
      end
    end
  end
  
    if player.status == "rundown" then
    frameTime = frameTime + dt
    for i, v in pairs(player.Animations.vRunQuadsDown) do
      if frameTime > 0.2 then
        player.currentQuad = player.currentQuad + 1
        frameTime = 0
      elseif player.currentQuad > 4 then
        player.currentQuad = 1
      end
    end
  end
  
  if player.status == "idlearmed" then
    frameTime = frameTime + dt
    lateralMovement = false
  for i, v in pairs(player.Animations.idleArmedQuads) do
    if frameTime > 0.5 then
      player.currentQuad = player.currentQuad + 1
      frameTime = 0
    elseif player.currentQuad > 4 then
      player.currentQuad = 1
    end
  end
end

if player.armStatus == "idlearmedarms" then
  frameArmTime = frameArmTime + dt
  for i, v in pairs(player.Animations.idleArmedArmQuads) do
    if frameArmTime > 0.5 then
      player.currentArmQuad = player.currentArmQuad + 1
      frameArmTime = 0
    elseif player.currentArmQuad > 4 then
      player.currentArmQuad = 1
    end
  end
end
  
  if player.status == "idle" then
     frameTime = frameTime + dt
     lateralMovement = false
  for i, v in pairs(player.Animations.idleQuads) do
  if frameTime > 0.5 then
    player.currentQuad = player.currentQuad + 1
    frameTime = 0
  elseif player.currentQuad > 4 then
    player.currentQuad = 1
   end
  end
end

  if player.status == "idle" then
     frameArmTime = frameArmTime + dt
  for i, v in pairs(player.Animations.idleArmQuads) do
    if frameArmTime > 0.5 then
     player.currentArmQuad = player.currentArmQuad + 1
    frameArmTime = 0
  elseif player.currentArmQuad > 4 then
    player.currentArmQuad = 1
    end
   end
  end
end

function player_keypressed(key)
  if key == "f" and player.isArmed == true then
    player.isArmed = false
  elseif key == "f" and player.isArmed == false then 
    player.isArmed = true
  end
end

function player_mousepressed(x, y, button)
  if button == 1 then 
    print("Clicked LMB")
    player.armStatus = "attack"
  elseif button == 2 then
    print("Clicked RMB")
    player.armStatus = "block"
    end
end

Re: Animation out of sync?

Posted: Mon Dec 03, 2018 7:20 pm
by xpali2
So if nobody has the answer to this issue. Can somebody tell me how to use the debugger and breakpoints to find out the problem myself?

Re: Animation out of sync?

Posted: Wed Dec 05, 2018 7:51 am
by Nikki
Its hard to help you without a love file and/or a clear description of what goes wrong.

Ive peeked at the code and the first thing that sticks out are the many copy pasted blocks ( if player.statuts == etc)
Whenever you find yourself writing (almost) the same lines of code twice or more shortly after each other you usually want to look for a way of extracting it out.
(The scancodes checks and the newQuads calls code also have this issue)

Another thing are the loops inside the copypasted blocks
for i, v in pairs(player.Animations
Neither i or v is used...

After these things are cleaned up its probably a whole lot easier spotting what is wrong.

Edit: btw breakpoints and debugging arent part of love2d perse, thats what your IDE probably does, i am guessing reading https://studio.zerobrane.com/doc-lua-debugging might help.

Re: Animation out of sync?

Posted: Wed Dec 05, 2018 7:14 pm
by xpali2
Nikki wrote: Wed Dec 05, 2018 7:51 am Its hard to help you without a love file and/or a clear description of what goes wrong.

Ive peeked at the code and the first thing that sticks out are the many copy pasted blocks ( if player.statuts == etc)
Whenever you find yourself writing (almost) the same lines of code twice or more shortly after each other you usually want to look for a way of extracting it out.
(The scancodes checks and the newQuads calls code also have this issue)

Another thing are the loops inside the copypasted blocks
for i, v in pairs(player.Animations
Neither i or v is used...

After these things are cleaned up its probably a whole lot easier spotting what is wrong.

Edit: btw breakpoints and debugging arent part of love2d perse, thats what your IDE probably does, i am guessing reading https://studio.zerobrane.com/doc-lua-debugging might help.
I know they aren't but I can't find the code stepping in zerobrane studio, if you can help me find it I can try to check some variable indexes over animation time to find out where the problem is.

As for the i,v loops. It's just good practice to always write them down anyway. I tried to make the quads and loops more orderly but this resulted in many errors and I didn't feel like fixing it, so I just separated them with spaces which works for me. I checked all copied loops and there is no reason in the logic why they wouldn't work so trying to clean them up isn't going to solve the issue. I can give you the .love file, I'd like to hear why the GIF isn't clear enough though.

Re: Animation out of sync?

Posted: Thu Dec 06, 2018 2:11 am
by pgimeno
To me the gif is static, single frame.
Animation-Glitch.gif
Animation-Glitch.gif (7.92 KiB) Viewed 6598 times

Re: Animation out of sync?

Posted: Thu Dec 06, 2018 4:55 am
by zorg
pgimeno wrote: Thu Dec 06, 2018 2:11 am To me the gif is static, single frame.
The image hoster site is pretty bad; chrome didn't play it back for me either, but firefox did.

i'm honestly not sure if this is the issue or not, but i'm seeing that the character, when idle, has a different "delay" per the bodyparts/groups defined to animate; the arms move up while the torso goes down and such.

usually, people would want this kind of animation to not have all bodyparts move unnaturally in the same direction.

Anyway, it may be solvable with resetting the current frame of all those groups on entering the idle animations again (from any other).

Re: Animation out of sync?

Posted: Sun Dec 09, 2018 12:19 am
by paulclinger
> I know they aren't but I can't find the code stepping in zerobrane studio, if you can help me find it I can try to check some variable indexes over animation time to find out where the problem is.

It's available in `Project | Step Into/Over` menu (F10/Shift-F10). You can also use the icons on the toolbar that trigger the same action. You can set a breakpoint and execute the code until it hits the breakpoint and then step through your code to explore what happens there.

Re: Animation out of sync?

Posted: Mon Dec 24, 2018 4:39 pm
by xpali2
paulclinger wrote: Sun Dec 09, 2018 12:19 am > I know they aren't but I can't find the code stepping in zerobrane studio, if you can help me find it I can try to check some variable indexes over animation time to find out where the problem is.

It's available in `Project | Step Into/Over` menu (F10/Shift-F10). You can also use the icons on the toolbar that trigger the same action. You can set a breakpoint and execute the code until it hits the breakpoint and then step through your code to explore what happens there.
Thank you,

I've seen the problem in my clocks and am currently trying to fix it. I think I will try to reset the clock some other way.