Howdy, Stranger!

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

spritesheets (animation) in Codea

edited March 2014 in Code Sharing Posts: 505

A more advanced spritesheet animator. Will load spritesheets and let you define animations from a given set of frames.

--# Main
function setup()
    local spritesheet = readImage("Dropbox:runningcat_512x256")
    cat = {
        idle = animation(spritesheet, 512, 256, {vec2(2,2)}), -- freeze on frame[i]
        run  = animation(spritesheet, 512, 256),

function draw()

    background(28, 245, 156, 255)
    sprite("Dropbox:retrojungle", 0, 0, WIDTH, HEIGHT)

    translate(WIDTH/4, 100)

--# animation
animation = class()

function animation:init(spritesheet, width, height, ...)
    self.img    = type(spritesheet) == "string" and readImage(spritesheet) or spritesheet
    self.width  = width
    self.height = height
    self.cols   = math.ceil(self.img.width / self.width)
    self.rows   = math.ceil(self.img.height / self.height)
    self.fps    = type(arg[1]) == "number" and arg[1] or 24
    self.frames = type(arg[1]) == "table" and arg[1] or (type(arg[2]) == "table" and arg[2] or {})

    if #self.frames == 0 then
        for r = 1, self.rows do
            for c = 1, self.cols do
                table.insert(self.frames, vec2(c, r))

    self.mode = { -- spriteMode(...)
        [0] = { -- CORNER
            pos  = vec2(self.width/2, self.height/2),
            size = vec2(self.width, self.height)
        [1] = { -- CORNERS
            pos  = vec2(self.width/2, self.height/2),
            size = vec2(self.width, self.height)
        [2] = { -- CENTER
            pos  = vec2(0, 0),
            size = vec2(self.width, self.height)
        [3] = { -- RADIUS
            pos  = vec2(0, 0),
            size = vec2(self.width*2, self.height*2)

    self.atlas = mesh()
    self.mask  = self.atlas:addRect(0, 0, 0, 0)
    self.atlas.texture = self.img

function animation:play()
    self.timer = self.timer or ElapsedTime
    local n = spriteMode()
    i = i or 1

    if (ElapsedTime-self.timer) > (1/self.fps) then
        self.timer = nil
        i = self.frames[i+1] and (i+1) or 1

    self.atlas:setRect(self.mask, self.mode[n].pos.x, self.mode[n].pos.y, self.mode[n].size.x, self.mode[n].size.y)
    self.atlas:setRectTex(self.mask, 1/self.cols*(self.frames[i].x-1), (1/self.rows*(self.rows-self.frames[i].y)), 1/self.cols, 1/self.rows)

image image


  • BriarfoxBriarfox Mod
    Posts: 1,542

    @se24vad Looking good! So much smaller then my animation class that I wrote when I first learned Codea. Thanks!

  • Posts: 199
    Can anyone one tell me where I could download this sprite sheet from ?...
    The error mgs'sare telling me I dont have the file...
    I took freeze frames so anyone could take a peek..
  • Posts: 680

    @se24vad nice!!

  • Posts: 199
    I tried to get the sprite sheet PGM going, as of yet I haven't succeeded...l would like to get this horse running....Can anyone help and tell me what I'm doing wrong ?......I've uploaded a spite sheet example, for anyone to take a peek...
    Horse.jpeg 5.1K
  • Posts: 1,768
    @kendog400 - the cat sprite sheet is available on the net, post the link later when I can find it.

    The horse sprites look like a solid sprite sheet, by that I mean is fully coloured - which would be fine against a 'white' background but would be better with transparency for the sprite sheet background.
  • dave1707dave1707 Mod
    edited July 9 Posts: 8,493

    Here’s the sprite sheet. I think it’s the correct one used above. You can use the program I gave you awhile ago to extract and show the animation of the cat running.

  • edited July 9 Posts: 1,768

    @kendog400 - looks like @dave1707 found the spritesheet too - dimensions not 512x256 though. The one I found is 840 x 85 and is 2 by 4 rather than 4 x 2. Link below if you want to compare.


  • Posts: 199
    I only get the whole sprite sheet, not a tiger running.....

    I'm getting error msg's..... : Error MSG.... Main29 : attempt to index a nil value (Global ‘arg’) stack traceback : Main : 29: : in field ‘init’....false end Set metatable (c, mt) return c end : 24 : in global animation Main : 6 : in function ‘setup’ Main 18 : attempt to index a nil value (Global cat) stack traceback : Main 18 : in function ‘draw’ ....

    I uploaded two freeze frames if any can understand what went wrong the 2nd pic shows what lines the errors are at...
    Error msg.png 280.6K
    PGM view.png 168.8K
  • dave1707dave1707 Mod
    Posts: 8,493

    To fix the arg error, add arg={...} at the start of the animation:init function. Then in setup, change the 512,256 to 256,128. You’ll get an asset warning on the retro jungle sprite in draw, comment that out or find a sprite to replace it. This still doesn’t work right, because the cat sprite sheet being used doesn’t have a transparent background.

  • Posts: 199
    I fixed the setup, the line 7, run was the size...and I put in the arg=(...) in line 24..., it works a lot better, I’m going to fiddle with the controls and see if I can get this in corner mode....Thanks for all the help
  • Posts: 199
    I tried to fiddle with the controls, but the sprite didn’t show evenly, in 1 frame I get a tail, another I get a foot and in another I get a head....I suspect the problem to be in the class section, pic 1b, the Last pic
    01a.png 145.6K
    11.png 65.4K
    04.png 60K
    07.png 77.4K
    02.png 62.1K
    01b.png 117.6K
  • Posts: 1,768
    @kendog400 - it is important to use the same sprite sheet as was used to produce the video above. Both I and @dave1707 posted images/links to spritesheets but the dimensions and orientation may differ. Also the empty space in the image may differ.

    So - you either have to find the original spritesheet or use the one you have got and change the capture coordinates for the sprites taken from the image.

    I'll take a look at the code/image that I have and report back later.
  • Posts: 199
    Ok, thanks...I thought it was something simple
Sign In or Register to comment.