Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

New lua update

edited July 2013 in General Posts: 14

Now lua set up a way to animate sprite sheet set up...
Did codea get the update or is there a easy way to animate a sprite using a sprite sheet...

Comments

  • edited July 2013 Posts: 391

    You could check out my code at


    http://twolivesleft.com/Codea/Talk/discussion/3058/



    I have a character that uses a sprite sheet to animate his movements. Check out the characters tab and the main tab, specifically the code referencing the joypad inside the draw() function.

  • Posts: 14

    I'm looking at your code but its not getting it....

  • Posts: 14

    Just show me the set up for a fake sprite sheet...
    How would I set it up in codea...

  • Posts: 391

    I have done many updates since I last posted here. I now have my project split into 2 projects, so it may be hard to reference the code where my sprites are animated.

    I am not sure if Codea utilizes any sprite auto-animation when it comes to sprite sheets. I know Codea can tween a single sprite to animate it, but I don't think that's what you're looking for. Below I explain how I animate my sprites, using no tween functions. All of my animations use counter variables I have created specifically for the movements.

    First, you need Codea to read the sprite sheet. I accomplished this by storing the image, #rows, and #cols into a table. Rows and cols are the number of sprites across the x axis and the y axis. These variables are used later to split the image into the 16 pieces I use to animate the sprites.

    Second, we designate a rate at which the images change. I used a variable called speed, which determines how fast the character moves from one tile to another. I make one full cycle, between the 4 sprites necessary for the move, every time the character moves from one tile to another.

    Third, we need to know which direction the character is moving to determine which 4 sprites are needed to animate the move. The direction also lets us know whether to tweak the x coordinate or the y coordinate. Once I know the direction, I first offset the characters location by the width/height of each tile on my tile-based grid map. This offset variable (I use moveX and moveY) will become -32 or +32, depending on the direction, and then increment or decrement back towards 0 over time based off of the speed variable.

    Last, now that we have each move changing either moveX or moveY and those variables slowly recover back to 0, I can use them to change the sprite image over time as well. Since I am using 4 images to animate each move, I divide the total length the character needs to move to get to the next tile by 4. If the absolute value of moveX or moveY (need to do absolute value since each variable could be positive or negative) is equal to or less than the values acquired by taking moveLength/4 (multiplied by 0, 1, 2, and 3 since we use 4 images) and the current animation image matches the correct image, then we change to the next image in the order. When our current image is the last image in the order, then that one will change back to the first image.

    Here is my code for animating the move:

    function animateMove(character)
        local speed = character.speed*maps[currentMap].tileWidth/32
        local mw = maps[currentMap].tileWidth/4
        local a,b,c,d = 0,mw,mw*2,mw*3
        if character.moveX ~= 0 then
            if (math.abs(character.moveX)-speed <= d and character.imgX == 0) or
                (math.abs(character.moveX)-speed <= c and character.imgX == 1) or
                (math.abs(character.moveX)-speed <= b and character.imgX == 2) or
                (math.abs(character.moveX)-speed <= a and character.imgX == 3) then
                if character.imgX < 3 then
                    character.imgX = character.imgX + 1
                else
                    character.imgX = 0
                end
            end
        elseif character.moveY ~= 0 then
            if (math.abs(character.moveY)-speed <= d and character.imgX == 0) or
                (math.abs(character.moveY)-speed <= c and character.imgX == 1) or
                (math.abs(character.moveY)-speed <= b and character.imgX == 2) or
                (math.abs(character.moveY)-speed <= a and character.imgX == 3) then
                if character.imgX < 3 then
                    character.imgX = character.imgX + 1
                else
                    character.imgX = 0
                end
            end
        end
        if character.moveX == 0 and character.moveY == 0 then
            character.imgX = 0
        end
        if character.moveX < 0 then
            character.moveX = character.moveX + speed
            if character.moveX > 0 then
                character.moveX = 0
            end
        elseif character.moveX > 0 then
            character.moveX = character.moveX - speed
            if character.moveX < 0 then
                character.moveX = 0
            end
        end
        if character.moveY < 0 then
            character.moveY = character.moveY + speed
            if character.moveY > 0 then
                character.moveY = 0
            end
        elseif character.moveY > 0 then
            character.moveY = character.moveY - speed
            if character.moveY < 0 then
                character.moveY = 0
            end
        end
    end
    
  • Posts: 14

    I understand your code.... it's just does have what I'm looking for....
    I need a(1) sprite sheet ... -- of an man
    On the sprite sheet (6) drawings...--- of the man walking
    -- that's what makes a sprite sheet..... a sprite sheet
    How do I get codea to look at each shoot of the man spite..??.??..
    How do Change speed to make him walk or run.?.?...?
    How do I get codea to get the image out of my pic roll..?...?..
    Lua just add this update to let you do this...

  • edited July 2013 Posts: 391

    To get the images, try this:

        local charasets = {
            { sheet = readImage("Dropbox:Character-001"), x = 4, y = 4 },
            { sheet = readImage("Dropbox:Character-002"), x = 4, y = 4 },
            { sheet = readImage("Dropbox:Character-003"), x = 4, y = 4 },
            { sheet = readImage("Dropbox:Character-004"), x = 4, y = 4 }
        }
    

    sheet is the full sprite sheet. x is the number of sprites in a row. y is the number of columns. I'm using 4x4 sprite charasets in my project.

    function getCharasetImage(p,tw,th,moveX,moveY)
        local m
        local cs = characters[p.character].sheet
        if gCharacters[p.character][p.id] == nil then
            m = mesh()
            m.texture = charasets[cs].sheet
            gCharacters[p.character][p.id] = m
        else
            m = gCharacters[p.character][p.id]
        end
        local w,h = charasets[cs].sheet.width,charasets[cs].sheet.height
        w = w / charasets[cs].x
        h = h / charasets[cs].y
        if h ~= th then -- resize the object to fit the current map
            w,h = (th/h)*w,(th/h)*h
        end
        local pObj
        if p.position.x == player.position.x and p.position.y == player.position.y then
            pObj = m:addRect(WIDTH/2,HEIGHT/2+math.floor(th/5),w,h)
        else
            pObj = m:addRect(((p.position.x-1)*tw)+((tw/32)*8)+moveX,-((p.position.y-1)*th)+((th/32)*12)+moveY,w,h)
        end
        m:setRectTex(pObj,(1/charasets[cs].x)*p.imgX,(1/charasets[cs].y)*p.imgY,1/charasets[cs].x,1/charasets[cs].y)
        return m
    end
    

    Then the above code will return the individual images in the sprite sheet. You can ignore the variables tw, th, moveX, and moveY. tw and th are the tile width and height, which are used to scale the sprite according to map size. moveX and moveY are used to help animate the character in my project.

    It first takes the full sprite sheet and stores it into a mesh. Then, using imgX and imgY (which are stored in each individual character (p)) it determines the location of the individual sprite on the sheet. x and y in the previous code snippet allow us to figure out the width and height of each sprite in the sheet.

    With meshes, it is all done in fractions of the full sprite sheet.

    m:setRectTex(pObj,(1/charasets[cs].x)*p.imgX,(1/charasets[cs].y)*p.imgY,1/charasets[cs].x,1/charasets[cs].y)
    

    (1/charasets[cs].x)p.imgX = the x coord of the sprite


    (1/charasets[cs].y)
    p.imgY = the y coord


    These coords represent the lower left corner of the individual sprite, so then to pull the full sprite out, we need the width and height which are calculated by the following:


    1/charasets[cs].x and 1/charasets[cs].y

    Let me know if this makes sense. You could go the readImage(spritesheet):copy(x,y,width,height) route, but that tends to make projects crash, so the mesh route is more efficient.

  • Posts: 14

    I'm not getting it... I tweak'd the code you had....

  • edited July 2013 Posts: 14
    local charasets = {
            { sheet = readImage("Dropbox:greenman"), x = 4, y = 3 }
            }
    
    
    function getCharasetImage(p,50,100,moveX,moveY)
        local m
        local cs = characters[p.character].sheet
        if gCharacters[p.character][p.id] == nil then
            m = mesh()
            m.texture = charasets[cs].sheet
            gCharacters[p.character][p.id] = m
        else
            m = gCharacters[p.character][p.id]
        end
            local pObj
        if p.position.x == player.position.x and p.position.y == player.position.y then
            pObj = m:addRect(WIDTH/2,HEIGHT/2+math.floor(100/5),w,h)
        else
            pObj = m:addRect(((p.position.x-1)*50)+((50/32)*8)+moveX,-((p.position.y-1)*100)+((100/32)*12moveY,w,h)
        end
        m:setRectTex(pObj,(1/charasets[cs].x)*p.imgX,(1/charasets[cs].y)*p.imgY,1/charasets[cs].x,1/charasets[cs].y)
        return m
    end
    
  • Posts: 14

    i did something wrong... Or I don't understand it.... And it maybe both...

  • Posts: 14

    I just want to see my green man run....

  • Posts: 14

    Lol...

  • edited July 2013 Posts: 391

    I think it might be best if you install both my projects from the link in my first post above. Then make the following changes:

    See post below.

  • edited July 2013 Posts: 391

    I just updated both my projects to support 3x4 sprite charasets. Install both and verify you have RPG v0.3.15 and RPGenerator v0.7.2, then make the following change:

    In the Images tab of the RPG project:


    Change

        local charasets = {
            { sheet = readImage("Dropbox:Character-001"), x = 4, y = 4, m = {0,1,2,3} }, -- player
            { sheet = readImage("Dropbox:Character-002"), x = 4, y = 4, m = {0,1,2,3} }, -- male dwarf
            { sheet = readImage("Dropbox:Character-003"), x = 4, y = 4, m = {0,1,2,3} }, -- male guard
            { sheet = readImage("Dropbox:Character-004"), x = 4, y = 4, m = {0,1,2,3} }, -- frog from Chrono Trigger
            { sheet = readImage("Dropbox:Character-005"), x = 3, y = 4, m = {1,2,1,0} } -- blonde female
        }
    

    To

    local charasets = {
            { sheet = readImage("Dropbox:Character-001"), x = 4, y = 4, m = {0,1,2,3} }, -- player
            { sheet = readImage("Dropbox:Character-002"), x = 4, y = 4, m = {0,1,2,3} }, -- male dwarf
            { sheet = readImage("Dropbox:Character-003"), x = 4, y = 4, m = {0,1,2,3} }, -- male guard
            { sheet = readImage("Dropbox:Character-004"), x = 4, y = 4, m = {0,1,2,3} }, -- frog from Chrono Trigger
            { sheet = readImage("Dropbox:greenman"), x = 3, y = 4, m = {1,2,1,0} } -- greenman
        }
    
Sign In or Register to comment.