Sprite Sheet maker/reader

Here’s some code that will create a sprite sheet and read the sprites from the sheet. I have no use for or used a sprite sheet, so this code doesn’t go into much detail for creating or reading sprite sheets. This is set up to read the sprites from “Planet Cute” and create a sprite sheet in “Documents” called “xxx”. Almost all of the sprites in “Planet Cute” have a size of 101x171, so I used that pack as an example. Only sprites with a size of 101x171 are put in the sheet. If you want to use this to create other sprite sheets, you’ll have to modify some of the variable to fit your needs. Some things that need to change are the sprite sizes you want to save, the size of the sprite sheet ( multiples of the sprites plus a little more ), and the number of sprites in the sheet when you read them back. If you want to use this and have any questions, let me know. When this program starts, tap on “pack” to create a sprite sheet. Once created, you can move the sprite sheet around to view all of the sprites in it, or flip the “create” slider at the top of the parameters to “off”, then each time you tap the screen it will display another sprite from the sheet. Since I don’t use sprite sheets, I didn’t put much effort into writing this code, so there may be easier ways of doing this. I just wanted to see what was involved in doing this.


function setup()
    parameter.boolean("create",true,choose)
end

function choose()
    if create then
        setupCreateSheet()
    else
        setupReadSheet()
    end
end

function setupCreateSheet()
    output.clear()
    spriteMode(CORNER)
    print("Create sprite sheet.")
    print("\
Tap   pack   to start.")
    print("\
You can move the sprite sheet")
    print("to view all of the sprites on it.")
    parameter.text("spritePack","Planet Cute")
    parameter.text("saveName","Documents:xxx")
    parameter.action("pack",function() pack=true end)
    sl=spriteList(spritePack)
    spw=101    -- sprite size to pack in sprite list
    sph=171
    xx=0
    yy=0
    count=0
    tx=20    -- display offset for sprite sheet
    ty=20
    rd=false
    w=925    -- sprite sheet size, > multiples of width, height
    h=1200
    img=image(w,h)  -- sprite sheet image
    pack=false
end

function setupReadSheet()
    output.clear()
    sp=readImage("Documents:xxx")    -- get the sprite sheet
    if sp then
        spw=sp.width
        sph=sp.height
    end
    count=0
    tx=0
    ty=0
    xx=1
    yy=1
    -- sprite width and height
    sw=101
    sh=171
    img1=image(sw,sh)    -- image area for sprite
    print("Read sprite sheet.")
    print("\
Tap the screen to read each")
    print("sprite from the sprite list.")
end

function draw()
    if create then
        background(37, 125, 102, 73) 
        noFill() 
        stroke(255, 0, 0, 255)
        strokeWidth(10)
        rect(tx-16,ty-16,w+16,h+16)
        sprite(img,tx,ty)
        readSprites()
    else
        background(208, 208, 208, 52)
        sprite(img1,WIDTH/2,HEIGHT/2)
    end
end

function readSprites()    -- read each sprite and pack it
    if pack then
        count=count+1
        if count>#sl then    -- all sprites read
            readComplete()
            return
        end
        sp=readImage(spritePack..":"..sl[count])
        -- only pack sprites with this width and height
        if sp.width==spw and sp.height==sph then
            copySprite()
            xx=xx+spw
            if xx+spw>w then
                xx=0
                yy=yy+sph
                if yy+sph>h then
                    packComplete()
                end
            end  
        end
   end     
end

function readComplete()    -- sprite sheet complete
    pack=false
    saveImage(saveName,img)
    print("\
Sprite sheet complete")
    print(saveName," saved")
end

function copySprite()    -- copy sprite to sprite sheet
    local r,g,b,a,x,y
    for x=1,sp.width do
        for y=1,sp.height do
            r,g,b,a=sp:get(x,y)
            img:set(x+xx,y+yy,r,g,b,a)
        end
    end
end

function touched(t)
    if create then -- creating sprite sheet
        -- move sprite sheet around  
        if t.state==MOVING then
            tx=tx+t.deltaX
            ty=ty+t.deltaY
        end
    elseif t.state==BEGAN then
        -- check for sprite sheet
        if sp==nil then
            output.clear()
            print("No sprite sheet found.")
            return
        end
        count=count+1
        -- check for end of sprite sheet
        if count>55 then
            print("\
End of sprite sheet reached, starting over.")
            count=1
            xx=1
            yy=1
        end
        -- get next sprite
        img1=sp:copy(xx,yy,sw,sh)
        xx=xx+sw
        if xx+sw>spw then
            xx=1
            yy=yy+sh
       end  
    end
end

@dave1707 Very cool!

I might take this idea and add to it if you do not mind. It would be nice to have a project where you can place sprites on the sheet and export the sheet with each sprites location. This would allow for various sized sprites on the same page. Add in an animation creator using all the locs and bam!

@Briarfox That’s why I posted it, add away. As far as I’m concerned, anything posted in this forum is fair game. If you don’t want someone to use it, don’t post it.

Trying to figure what I need to do to get a sprite into PGM…

PGM says :
Sprite sheet reader Only sprites with a size of 101x171 are put in the sheet,
(as of line 44 & 45…)

I’ve uploaded a copy of the sprite sheet, take a peek…

Deck of cards sprite is : 568 x 672…

Width : 568 / 8 = 71 pixels (1 sprite)

Height : 672 / 7 = 96 pixels pixels (1 sprite)

This looks like the variables that need to be adjusted :…

spw=101 – sprite size to pack in sprite list sph=171
tx=20 – display offset for sprite sheet ty=20

I tried to change variables, I still see only a red rect and a black background. I changed the sprite but it still doesn’t show…

@kendog400 I’ll look into this later and see what need to be changed.

Ok, thanks…

@kendog400 The program above creates a sprite sheet. Try this program to extract images from a sheet. I tried it on you card sheet. I used the name card1 in Dropbox. Change the name for yours.

displayMode(STANDARD)

function setup()
    tab={}
    delay=0
    img=readImage(asset.documents.Dropbox.card1)
    iw=img.width
    ih=img.height
    dx,dy=0,0
    sizeX=iw
    sizeY=ih    
    spriteMode(CORNER)
    parameter.text("wide")
    parameter.text("high")
    parameter.action("extract",extract)
    parameter.integer("scale",1,100,60)
    parameter.integer("size",1,100,70)
    img1=image(iw,ih)    
    setContext(img1)
    background(255)
    sprite(img,0,0)
    setContext()    
    w=img1.width
    h=img1.height
    print("slide this down")
end

function extract()
    tab={}
    dx,dy=0,0
    if wide=="" or high=="" then
        return
    end
    stepX=iw//wide
    stepY=ih//high
    for y=1,sizeY,stepY do
        for x=1,sizeX,stepX do
            table.insert(tab,img1:copy(x,y,stepX,stepY))
        end
    end
end

function draw()
    background(238, 185, 56)
    i=0
    if #tab>0 then
        for x=1,wide do
            for y=1,high do
                i=i+1
                sprite(tab[i],x*size+dx,y*size*1.5+dy,scale)
            end
        end
    else
        sprite(img1,dx,dy,400)
    end
end


function touched(t)
    if t.state==MOVING then
        dx=dx+t.deltaX
        dy=dy+t.deltaY 
    end   
end

Thanks, getting ready to take a peek…

Another question : it seems I can get sprite sheets into the codea documents, but I can’t get wav files into the documents, there must be a trick I don’t know about…

This works good, but do you have any PGM hanging around that would extract a single sprite image an mabey click through some more ? There must be a load image CMD, that would load just one image, and then fiddle with it…

@kendog400 @Simeon already answered the question about sound files in the other thread. Here is a step by step walkthrough of downloading a wav file from the internet and playing it in Codea

Go to your source of wav files (for this example, I’m downloading a free one off a random site I’ve found (no endorsement!) - https://www.wavsource.com/animals/animals.htm)

Long tap on the file you want and select download linked file

Open up “Files” app on the iPad

Locate your downloaded file (for recents). Long hold and select Move

Select “On my iPad then the Codea folder” Tap “copy” in top right

File will now be available in the Documents folder (note if Codea is already open then you may need to close then re-open to force a refresh on the asset list)

@kendog400 Here’s something I just threw together to copy a section of a sprite sheet. It uses your card sprite sheet that you show above. Run the code and set the parameter wide to 8 and parameter high to 7 to resize the red rectangle. Slide your finger on the screen to move the red rectangle over the area you want to copy. Then tap the copy parameter.

 displayMode(STANDARD)

function setup()
    parameter.integer("wide",1,20)
    parameter.integer("high",1,20)
    parameter.action("copy",function() img1=img:copy(dx//1,dy//1,cw,ch) end )
    spriteMode(CORNER)
    img=readImage(asset.documents.Dropbox.cards)
    iw=img.width
    ih=img.height
    dx,dy=0,0
end

function draw()
    background(0)
    cw=iw/wide
    ch=ih/high
    sprite(img,0,0)
    noFill()
    stroke(255,0,0)
    strokeWidth(4)
    rect(dx-2,dy-2,cw+4,ch+4)
    if img1~=nil then
        sprite(img1,WIDTH-200,HEIGHT-200)
    end
end

function touched(t)
    if t.state==CHANGED then
        dx=dx+t.deltaX
        dy=dy+t.deltaY
    end 
end

Thanks !

@kendog400 here is Dave’s function but I added when you press copy it saves the sprite-sheet frame image to your documents.

displayMode(STANDARD)

function setup()
    parameter.integer("wide",1,20)
    parameter.integer("high",1,20)
    parameter.action("copy",function() img1=img:copy(dx//1,dy//1,cw,ch)
    end)
    spriteMode(CORNER)
    img=readImage(asset.documents.Dropbox.cards)
    iw=img.width
    ih=img.height
    dx,dy=0,0
end

function draw()
    background(0)
    cw=iw/wide
    ch=ih/high
    sprite(img,0,0)
    noFill()
    stroke(255,0,0)
    strokeWidth(4)
    rect(dx-2,dy-2,cw+4,ch+4)
    if img1~=nil then
        sprite(img1,WIDTH-200,HEIGHT-200)
        myImage = img1
        saveImage(asset.documents.."frames.png",myImage)
    end
end

function touched(t)
    if t.state==CHANGED then
        dx=dx+t.deltaX
        dy=dy+t.deltaY
    end 
end

Thanks, I wanted to make a button and a touch fx, to click through the sprite sheet…

I once had Fuze / Nintendo switch, and they mostly use sprite sheets, I think I’m getting this confused with codea…