Page 1 of 2

Need help on animations

Posted: Sun Jan 08, 2023 6:25 am
by ketthos
Hello everyone,

i'm not an active poster here, but i need your help about animation i want to do based on a strange sprite sheet.
Image

I want to create Game Over animation like this
https://youtu.be/aAQAlP3GPmE?t=8

right now, i can make animation only for G.. If i want to write the A, the G go away!
Does i need library like Anima8 to make this kind of animation?

Does i need to make a sprite sheet on a single row or i can use the sheet image i've posted?

Thanks for your help and advice!!

Re: Need help on animations

Posted: Sun Jan 08, 2023 6:39 am
by Andlac028
ketthos wrote: Sun Jan 08, 2023 6:25 am Does i need to make a sprite sheet on a single row or i can use the sheet image i've posted?
You need only one image, which you can “crop” to multiple smaller with Quad
ketthos wrote: Sun Jan 08, 2023 6:25 am right now, i can make animation only for G.. If i want to write the A, the G go away!
Does i need library like Anima8 to make this kind of animation?
Can you post your code, so we can help you to make it work for all letters?

Re: Need help on animations

Posted: Sun Jan 08, 2023 6:42 am
by ketthos
Thanks for your reply,

Here is my code, like you see, i've tryed a lot of thing! :)

Currently i've tested with table.insert.. but same problem!

Code: Select all

if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
    require("lldebugger").start()
end


love.graphics.setDefaultFilter("nearest")

local ttfont
local gameoverAnimation
local gameoverloop = true
--local frameRate

function FnGameOver()
    local gameOver = {}
    gameOver.spriteSheet = love.graphics.newImage('images/gameover.png')
    gameOver.quads = {}
    table.insert(gameOver.quads, love.graphics.newQuad(0,0, 35, 35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(35,0, 35, 35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(70,0,35,35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(0, 40, 17, 27, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    gameOver.duration = 1
    gameOver.currentTime = 0

    return gameOver
end


function love.load()
    --img_gameover = love.graphics.newImage('images/gameover.png')
    ttfont = love.graphics.newFont('fonts/retro_gaming.ttf', 15)
    gameoverAnimation = FnGameOver()

    --[[
    
    quad.x = 0
    quad.y = 145
    -- G
    quad[1] = love.graphics.newQuad(0,0, 35, 35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[2] = love.graphics.newQuad(35,0, 35, 35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[3] = love.graphics.newQuad(70,0,35,35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[4] = love.graphics.newQuad(0, 40, 17, 27, img_gameover:getWidth(), img_gameover:getHeight())
    quad[5] = love.graphics.newQuad(0, 73, 17, 27, img_gameover:getWidth(), img_gameover:getHeight())    
    quad[6] = love.graphics.newQuad(0, 106, 18, 26, img_gameover:getWidth(), img_gameover:getHeight())
    
    -- A    
    quad.x = 35
    quad.y = 145
    quad[7] = love.graphics.newQuad(0,0, 35, 35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[8] = love.graphics.newQuad(35,0, 35, 35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[9] = love.graphics.newQuad(70,0,35,35, img_gameover:getWidth(), img_gameover:getHeight())
    quad[10] = love.graphics.newQuad(40, 80, 17, 27, img_gameover:getWidth(), img_gameover:getHeight())
    quad[11] = love.graphics.newQuad(0, 73, 17, 27, img_gameover:getWidth(), img_gameover:getHeight())    
    quad[12] = love.graphics.newQuad(0, 106, 18, 26, img_gameover:getWidth(), img_gameover:getHeight())
    --]]
end

function love.draw()
    local frameRate = math.floor(gameoverAnimation.currentTime / gameoverAnimation.duration * #gameoverAnimation.quads) + 1
    love.graphics.print("FrameRate: "..frameRate)
    love.graphics.draw(gameoverAnimation.spriteSheet, gameoverAnimation.quads[frameRate], 0, 145,0,1.5)
    --[[love.graphics.setFont(ttfont)

    local frameArrondie = math.floor(frameRate)

    
    
    love.graphics.draw(img_gameover, quad[frameArrondie], quad.x, quad.y, 0, 2,2)

    --]]
end

function love.update(dt)
    if gameoverloop == true then
        gameoverAnimation.currentTime = gameoverAnimation.currentTime + dt
        if gameoverAnimation.currentTime >= gameoverAnimation.duration then
            gameoverloop = false
            gameoverAnimation.currentTime = gameoverAnimation.currentTime -1--- - gameoverAnimation.duration            
        end
    end

    --[[frameRate = frameRate + 6*dt
    if frameRate >= #quad+1 then
        frameRate = #quad
    end
    --]]
end

Thanks again for your help.

Re: Need help on animations

Posted: Sun Jan 08, 2023 7:04 am
by Andlac028
So your problem seems to be that you draw only one quad, so if you animated G, you are drawing only A. First, you have to save positions and quads animations for all letters like this:

Code: Select all

-- we can reuse repeating quads like
local repeating_quad_1 = love.graphics.newQuad(0, 0, 5, 5, img_gameover), -- also note that you can pass only texture to it instead of width and height
animation = {
    -- G
    {
        x = 0,
        y = 145,
        quads = {
            repeating_quad_1,
            -- and then we create letter-specific quads 
            love.graphics.newQuad(0, 0, 35, 35, img_gameover),
            love.graphics.newQuad(35, 0, 35, 35, img_gameover),
            -- your quads here 
        }
    },
    -- A
    {
        x = 0,
        y = 145,
        quads = {
            repeating_quad_1,
            love.graphics.newQuad(0, 0, 35, 35, img_gameover),
            love.graphics.newQuad(35, 0, 35, 35, img_gameover),
            -- your quads here 
        }
    },
}
And then, you can draw all finished and then the current animating

Code: Select all

function love.draw()
    -- draw already animated
    for i = 1, math.floor(animationFrame / animationQuadsInLetter) do -- highest complete letter (if exists)
        local anim = animation[i]
        love.graphics.draw(img_gameover, anim.quads[#anim.quads] anim.x, anim.y)
    end

    -- draw current animation
    local anim = animation[math.floor(animationFrame / animationQuadsInLetter)]
    love.graphics.draw(img_gameover, anim.quads[animationFrame % (animationQuadsInLetter + 1)], anim.x, anim.y)
end

local time = 0
local duration = .2
local animationFrame = 1

function love.update(dt)
    -- update animation frame based on time
    time = time + dt

    if time > duration then
        animationFrame = animationFrame + 1
        time = time - duration
    end
end
(code not tested)

Re: Need help on animations

Posted: Sun Jan 08, 2023 4:47 pm
by ketthos
ohhh!! nice! Thanks a lot for your help, i will check that! I will let you know if everything works fine! :)

Re: Need help on animations

Posted: Fri Jan 13, 2023 3:11 am
by ketthos
Andlac028 wrote: Sun Jan 08, 2023 7:04 am So your problem seems to be that you draw only one quad, so if you animated G, you are drawing only A. First, you have to save positions and quads animations for all letters like this:

Code: Select all

-- we can reuse repeating quads like
local repeating_quad_1 = love.graphics.newQuad(0, 0, 5, 5, img_gameover), -- also note that you can pass only texture to it instead of width and height
animation = {
    -- G
    {
        x = 0,
        y = 145,
        quads = {
            repeating_quad_1,
            -- and then we create letter-specific quads 
            love.graphics.newQuad(0, 0, 35, 35, img_gameover),
            love.graphics.newQuad(35, 0, 35, 35, img_gameover),
            -- your quads here 
        }
    },
    -- A
    {
        x = 0,
        y = 145,
        quads = {
            repeating_quad_1,
            love.graphics.newQuad(0, 0, 35, 35, img_gameover),
            love.graphics.newQuad(35, 0, 35, 35, img_gameover),
            -- your quads here 
        }
    },
}
And then, you can draw all finished and then the current animating

Code: Select all

function love.draw()
    -- draw already animated
    for i = 1, math.floor(animationFrame / animationQuadsInLetter) do -- highest complete letter (if exists)
        local anim = animation[i]
        love.graphics.draw(img_gameover, anim.quads[#anim.quads] anim.x, anim.y)
    end

    -- draw current animation
    local anim = animation[math.floor(animationFrame / animationQuadsInLetter)]
    love.graphics.draw(img_gameover, anim.quads[animationFrame % (animationQuadsInLetter + 1)], anim.x, anim.y)
end

local time = 0
local duration = .2
local animationFrame = 1

function love.update(dt)
    -- update animation frame based on time
    time = time + dt

    if time > duration then
        animationFrame = animationFrame + 1
        time = time - duration
    end
end
(code not tested)
sorry for the noob question, what is the animationQuadsInLetter variable? the number of letter? is it a float or an integer?

Thanks for your help it's working except i get a nil value on anim at the end of the animation.

Re: Need help on animations

Posted: Fri Jan 13, 2023 5:26 am
by Andlac028
ketthos wrote: Fri Jan 13, 2023 3:11 am sorry for the noob question, what is the animationQuadsInLetter variable? the number of letter? is it a float or an integer?
It is number of elements in quads table for letter - number of images you use to animate for each letter

Re: Need help on animations

Posted: Sat Jan 14, 2023 5:55 am
by ketthos
Andlac028 wrote: Fri Jan 13, 2023 5:26 am
ketthos wrote: Fri Jan 13, 2023 3:11 am sorry for the noob question, what is the animationQuadsInLetter variable? the number of letter? is it a float or an integer?
It is number of elements in quads table for letter - number of images you use to animate for each letter
Thanks, but do you have an idea why i get a nil after the last animation?
here is the code.

Code: Select all

if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
    require("lldebugger").start()
end


love.graphics.setDefaultFilter("nearest")

local ttfont
local gameoverAnimation
local gameoverloop = true
local img_gameover
local repeating_quad_1

local time = 0
local duration = .2
local animationFrame = 2

function FnGameOver()
    local gameOver = {}
    gameOver.spriteSheet = love.graphics.newImage('images/gameover.png')
    gameOver.quads = {}
    table.insert(gameOver.quads, love.graphics.newQuad(0,0, 35, 35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(35,0, 35, 35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(70,0,35,35, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    table.insert(gameOver.quads, love.graphics.newQuad(0, 40, 17, 27, gameOver.spriteSheet:getWidth(), gameOver.spriteSheet:getHeight()))
    gameOver.duration = 1
    gameOver.currentTime = 0

    return gameOver
end


function love.load()
    img_gameover = love.graphics.newImage('images/gameover.png')
    ttfont = love.graphics.newFont('fonts/retro_gaming.ttf', 15)
    --gameoverAnimation = FnGameOver()

    repeating_quad_1 = love.graphics.newQuad(0,0,35,35, img_gameover)

    gameoverAnimation = {
        -- G
        {
            x = 0,
            y = 145,
            quads = {
                repeating_quad_1,
                love.graphics.newQuad(0,0, 35, 35, img_gameover),
                love.graphics.newQuad(35,0, 35, 35, img_gameover),
                love.graphics.newQuad(70,0,35,35, img_gameover),
                love.graphics.newQuad(0, 40, 17, 27, img_gameover),
                love.graphics.newQuad(0, 73, 17, 27, img_gameover),
                love.graphics.newQuad(0, 106, 18, 26, img_gameover)
            }
        },
        -- A
        {
            x = 35,
            y = 145,
            quads = {
                repeating_quad_1,
                love.graphics.newQuad(0,0, 35, 35, img_gameover),
                love.graphics.newQuad(35,0, 35, 35, img_gameover),
                love.graphics.newQuad(70,0,35,35, img_gameover),
                love.graphics.newQuad(40, 80, 17, 27, img_gameover),
                love.graphics.newQuad(0, 73, 17, 27, img_gameover),
                love.graphics.newQuad(0, 106, 18, 26, img_gameover)
            }
        }
    }
end

function love.draw()

    for i = 1, math.floor(animationFrame / 6) do -- highest complete letter (if exists)
        local anim = gameoverAnimation[i]
        love.graphics.draw(img_gameover, anim.quads[#anim.quads], anim.x, anim.y)

    end

    --local anim = gameoverAnimation[math.floor(animationFrame / 6)]
    --love.graphics.draw(img_gameover, anim.quads[animationFrame % (1 + 1)], anim.x, anim.y)

    
end

function love.update(dt)

    time = time + dt
    if time > duration then
        animationFrame = animationFrame + 1
        time = time - duration
    end
    
end
if i uncomment the local anim .... i get a nil value at the start.
I'm unable to figure out why. Maybe it's a bit too much level for me! hehe
Thanks.

Re: Need help on animations

Posted: Sat Jan 14, 2023 8:46 am
by Andlac028
ketthos wrote: Sat Jan 14, 2023 5:55 am if i uncomment the local anim .... i get a nil value at the start.
I'm unable to figure out why. Maybe it's a bit too much level for me! hehe
Thanks.
Oh, my bad, Lua is starting indexing from 1, not from 0 (that's why you have nil value, as expression to compute index returns 0 for first element(s)), so it should be something like this instead:

Code: Select all

local anim = gameoverAnimation[math.floor((animationFrame - 1) / 6) + 1]
love.graphics.draw(img_gameover, anim.quads[(animationFrame - 1) % 6 + 1], anim.x, anim.y)

Re: Need help on animations

Posted: Sun Jan 15, 2023 3:19 am
by ketthos
thanks, i still get nil on anim after the animation, but i will try to solve it by myself, i'm totally noob.. hehe thanks again for your help.