Animation out of sync?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
xpali2
Prole
Posts: 38
Joined: Thu Apr 05, 2018 4:47 pm

Animation out of sync?

Post 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
xpali2
Prole
Posts: 38
Joined: Thu Apr 05, 2018 4:47 pm

Re: Animation out of sync?

Post 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?
User avatar
Nikki
Citizen
Posts: 87
Joined: Wed Jan 25, 2017 5:42 pm

Re: Animation out of sync?

Post 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.
xpali2
Prole
Posts: 38
Joined: Thu Apr 05, 2018 4:47 pm

Re: Animation out of sync?

Post 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.
User avatar
pgimeno
Party member
Posts: 3673
Joined: Sun Oct 18, 2015 2:58 pm

Re: Animation out of sync?

Post by pgimeno »

To me the gif is static, single frame.
Animation-Glitch.gif
Animation-Glitch.gif (7.92 KiB) Viewed 6596 times
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Animation out of sync?

Post 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).
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
paulclinger
Party member
Posts: 227
Joined: Thu Jun 28, 2012 8:46 pm

Re: Animation out of sync?

Post 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.
xpali2
Prole
Posts: 38
Joined: Thu Apr 05, 2018 4:47 pm

Re: Animation out of sync?

Post 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.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests