Howdy, Stranger!

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

Sprite Sheet maker/reader

dave1707dave1707 Mod
edited October 2013 in Code Sharing Posts: 8,456

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("\nTap   pack   to start.")     print("\nYou 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("\nTap 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("\nSprite 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("\nEnd 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

Comments

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @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!

  • dave1707dave1707 Mod
    Posts: 8,456

    @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.

  • Posts: 193
    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
  • Posts: 193
    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...
  • dave1707dave1707 Mod
    Posts: 8,456

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

  • Posts: 193
    Ok, thanks....
  • dave1707dave1707 Mod
    Posts: 8,456

    @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
    
  • Posts: 193
    Thanks, getting ready to take a peek....
  • Posts: 193
    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...
  • Posts: 193
    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...
  • Posts: 789

    @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)

  • dave1707dave1707 Mod
    edited June 22 Posts: 8,456

    @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
    
  • Posts: 193
    Thanks !
  • Posts: 126

    @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
    
  • Posts: 193
    Thanks, I wanted to make a button and a touch fx, to click through the sprite sheet....
  • Posts: 193
    I once had Fuze / Nintendo switch, and they mostly use sprite sheets, I think I'm getting this confused with codea....
Sign In or Register to comment.