Importing Sprites from a Sprite Sheet Help

Hello Coders,

I am still very new to this and I have been reading up and studying LUA. I was messing with some spritesheets that I had made on my phone and I wanted to try and create sprites and animate them. I have seen and read numerous posts on sprites/meshes and I cannot seem to find anything that is just as simple as reading from a spritesheet. Any help would be great!

Here are the files I made:

Items: [https://dropbox.com/s/r8i4bt8b43o0hf3/items.png?dl=0[]()](https://www.dropbox.com/s/r8i4bt8b43o0hf3/items.png?dl=0[]())

Link Right 2: https://dropbox.com/s/lpq4sfj90fxvd7y/Link%20Right%202.png?dl=0

Spikey: https://dropbox.com/s/3jhbcwguhtoqox1/Spikey.png?dl=0

Currently I have the following:

displayMode(FULLSCREEN)

function setup()
  spriteMode(CORNER)
 img=readImage("Dropbox:Floor1")
  imgW=img.width
  imgH=img.height
   w=WIDTH/imgW
   h=HEIGHT/imgH
end

function draw()
 background(255,255,255)
for x=0,w do
for y=0,h do
  --   sprite(img,imgW*x,imgH*y)
end
sprite("Dropbox:items",150,150)
sprite("Dropbox:Spikey",WIDTH/2,HEIGHT/2)
sprite("Dropbox:Link Right 2",CurrentTouch.x,CurrentTouch.y)
end
end

I have taken out the background so it is easier to see.

The “items” page is a simple sprite sheet I am creating and I just want to know how to select just one image in the sheet and display it. Further more, If I have a number of tiles on the “spikey” image that I would like to animate in place.

If anyone knows of a good resource to learn these or ideas, that would be greatly appreciated!

Thanks for the help!

@jpwerner18 Do a forum search on “Sprite sheet” including the " " . There have been several discussions already, and I’m sure those might answer your questions.

@jpwerner18 Here’s an example where I create a Sprite sheet using the planet cute sprites. It then reads each Sprite from the sheet as you tap the screen.

http://codea.io/talk/discussion/3818/sprite-sheet-maker-reader

@jpwerner18 The above code is old and there was a Codea change. You need to change the line

    sl=spriteList(spritePack)

To

    sl=assetList(spritePack)

@jpwerner18 - the simplest way to use a spritesheet is to read it in, then cut it into individual images that you can then sprite normally.

For example, if your first image starts at pixel 1,1 and is 120 x 243, then you can write img1 = spriteImage:copy(1,1,120,243)

If you have trouble with animating, just let us know.

(There is an alternative using a mesh, but I’m guessing you are just using normal sprites).

Much appreciated guys. And @Ignatz, yes I am just using sprites for the moment as mesh is a lot more confusing for me. I would like to learn how to use meshes but I am starting from square one right now with no coding experience.

Then I would do it the way I suggested, reading in the spritesheet and using the image copy command to break it into individual sprites.

If you are animating, then put the series of images in a table and loop through them in draw

--in setup
spriteSheet=readImage("image name")
tbl={}
tbl[1]=spriteSheet:copy(1,1,200,234)
--and so on for the other images
counter=1 --the image number to draw
delay=0.5 --seconds between changing images
lastChange=0 --time when last image was changed

--in draw
sprite(tbl[counter],300,300)
--update image if necessary
if ElapsedTime>lastChange+delay then
    counter=counter+1
    --go back to beginning if you run out of images
    if counter>#tbl then counter=1 end 
    lastChange=ElapsedTime
end

@Ignatz - I tried what you said, but I believe I still have it incorrect as it is now just showing both the sprite on the screen but not animating the sprite. The entire spritesheet is 192x32 and the two sprites in the sheet are 32x32 each. I have the following:

-- Spritesheets

-- Use this function to perform your initial setup
displayMode(FULLSCREEN)
function setup()
    --in setup
spriteSheet=readImage("Dropbox:Linkwalk")
tbl={}
tbl[1]=spriteSheet:copy(1,1,192,32)
tbl[2]=spriteSheet:copy(32,32,192,32)
--and so on for the other images
counter=2 --the image number to draw
delay=0.5 --seconds between changing images
lastChange=0 --time when last image was changed
end

function draw()
sprite(tbl[counter],300,300)
--update image if necessary
if ElapsedTime>lastChange+delay then
    counter=counter+1
    --go back to beginning if you run out of images
    if counter>#tbl then counter=1 end 
    lastChange=ElapsedTime
end
    
end

Here is the spritesheet:

https://dropbox.com/s/2h0gtmvnd1tsas1/Linkwalk.png?dl=0

I copied the above Sprite sheet to my Dropbox:spr to use in the code below. Tap the screen to show a different Sprite from the sheet.

EDIT: The size of the sheet on my iPad Air is 96x16 which makes each image 16x16 instead of 32x32.

function setup()
    img1=readImage("Dropbox:spr")
    offset=-15
    select()
end

function draw()
    background(40, 40, 50)
    fill(255)
    text("tap screen to select a different sprite",WIDTH/2,HEIGHT-100)
    sprite(img1,WIDTH/2,HEIGHT/2)
    sprite(img2,WIDTH/2,HEIGHT/3,100)
end

function touched(t)
    if t.state==BEGAN then
        select()
    end
end

function select()
    offset=offset+16
    if offset>17 then
        offset=1
    end
    img2=img1:copy(offset,1,16,16)
end

@jpwerner18 - you aren’t extracting the images correctly, try this

tbl[1]=spriteSheet:copy(1,1,32,32)
tbl[2]=spriteSheet:copy(32,1,32,32)

And with due respect to dave’s approach, I would stick with what you have, so you aren’t continually having to copy bits of spritesheet into separate images. If the images were enormous, that approach might help by saving memory, but your images are tiny, so I would pull them all out in setup as you are doing now.

Later, if you use meshes, you don’t have to pull them out at all, but for now, this approach is pretty good.

@Ignatz If the image is 32x32, shouldn’t the second spriteSheet:copy start at 33,1 .

tbl[2]=spriteSheet:copy(33,1,32,32)

You would think so, but maybe the images aren’t spaced correctly, because what I wrote above works perfectly (and your correction doesn’t).

The sprite sheet probably wasn’t correct. If the sprites are 32x32, then their X values should be 1-32, 33-64, 65-96, 97-128, 129-160, 161-192. If it’s a 2 dimension sheet, the Y values would be the same.

copy this code into separate tab and use animation(spritesheet, width, height, [fps], [frames])

  • fps and frames are optional parameters
  • omitting fps means: it will play at 24 frames per socond
  • omitting frames means: all frames from spritesheet will be included
  • frames were passed as a vec2(column, row), where column is the image number horizontally and row the image number vertically

This will play the first two frames at 3fps:

function setup()
    walk = animation("Dropbox:spr", 32, 32, 3, {vec2(1, 1), vec2(2, 1)})
end

function draw()
    walk:play()
end

PS: I actually have updated this library to allow passing plain frame numbers (read from left to right and top to bottom), instead of vec2. Like animation("Dropbox:spr", 32, 32, {1, 3, 4, 5, ...}). But my iPad is broken, so can’t update.

An advantage to this library is also the usage of meshes, which could cooperate with shaders straight away.