Log In  


I have been searching through this forum and other places online for a solution, but couldn't find the answer.

I would like to use the limited space for sprites more efficiently by splitting the sprites up in pieces, and would like to know how I can combine them. For example:

The top half with the lilac background are the full sprites. The bottom half with the green background is how I have split my sprites up.

So basically I could create the first sprite by combining them as follows:

1 1(mirrored)
2 2(mirrored)
3 3(mirrored)
4 4(mirrored)

The second sprite I would create like this:

1 1(mirrored)
2 5
6(mirrored) 3(mirrored)
7(mirrored) 4(mirrored)

I am new to PICO-8 and game development, and couldn't get much further than below code so far. But that just overlays both halves of the character over the same 4-sprite high unit.

function draw_player()
 spr(1,px,py,1,4)
 spr(1,px,py,1,4,true)
end

How can I recreate the sprites in the lilac segment using the partial sprites I have in the green segment?

2


1

I'll post it in this form for now.

You can probably pack more sprites in by adjusting the offset and height of each sprite.

Also, because these sprites have few colors, I think you can do palette animation. In that case, you might be able to get by with just 8 sprites.
[32x32]

playerspr={
{1,49,2,2}
,{1,50,3,4}
,{1,51,4,3}
}
playersprp={
{0,0}
,{0,24}
,{-1,0}
,{1,0,true}
}

animnum={1,2,3,2,3,2,3,2,3}
while 1 do
cls()
x,y=64,48

a=(time()*4\1)%#animnum
a=animnum[a+1]
camera(-x,-y)
for i,v in pairs(playerspr[a]) do
	px,py,f=unpack(playersprp[i])
	spr(v,px,py,1,3,f)
end
flip()
end

--spr(1,x,y,1,3) -- head&body
--spr(49,x,y+24,1,3) --feet
--spr(2,x-1,y,1,3) --arm-r
--spr(2,x+1,y,1,3,true) --arm-l

1

I used something like this for a game I made a while ago. Here's a simple version of it. It's 91 tokens for the function, but it'll work with objects that are any number of sprites wide, and objects can be flipped horizontally like normal and everything will draw correctly. Each character/object will just need its own string of values. Each string is divided into animation frame entries by commas, and each entry's values are divided by colons (:). Each number represents a sprite number, and if it's negative that means it's horizontally flipped.

sprtbl=split"1:-1:17:-17:33:-33:49:-49,1:-1:17:18:33:2:-50:-49,1:-1:-18:-17:-2:34:49:50"

--s:sprite table entry number
--x:sprite x-position (center)
--y:sprite y-position
--tw:# of tiles wide sprite is
--yos:y-offset
--fx:if sprite is x-flipped

function mspr(s,x,y,tw,yos,fx)
 local tbl=split(sprtbl[s],":")
 for i=1,#tbl do
  local sp,k=tbl[i],i-1
  local flp,dir,xos=sgn(sp),1,-tw*4
  if(fx) flp*=-1 dir=-1 xos=tw*4-8
  spr(abs(sp),x+xos+k%tw*dir*8,y+k\tw*8+yos,1,1,flp<0)
 end
end

palt"0"
tic=0

function _update60()
 cls(13) 
 mspr(tic\10%3+1,63,63,2,-16,false)
 tic+=1
end

This just uses 8 sprites, but the system would have trouble flipping sprite 0, so I moved it over on the spritesheet.


>I am new to PICO-8 and game development, and couldn't get much further than below code so far. But that just overlays both halves of the character over the same 4-sprite high unit.

for the second sprite, it's just spr(1,px+8,py,1,4,true) to nudge it over 8 pixels.

If you really want to pack it in, you could use sspr to cut up the spritesheet by pixel

^-- the spritesheet

px=64
py=44

function draw_player()
 local st = {
  -- head
  {8,0,3,8, px,py,3,8},
  {8,0,3,8, px+3,py,3,8, 1},
  -- body
  {8,8,4,8, px-1,py+8,4,8},
  {8,8,4,8, px+3,py+8,4,8, 1},
  -- legs
  {11,0,3,8, px,py+16,3,8},
  {11,0,3,8, px+3,py+16,3,8, 1},
  -- arms
  {14,0,3,8, px-2,py+11,3,8},
  {14,0,3,8, px+6,py+11,3,8},
  -- feet
  {12,8,4,4, px-1,py+24,4,4},
  {12,8,4,4, px+3,py+24,4,4, 1},
 }

 for s in all(st) do
  sspr(unpack(s))
 end
end

function _draw()
 cls()
 draw_player()
end

The above implementation uses 2 sprite indexes to draw the player, and with a little more work it could be used to draw them running as well.


1

wow Thanks for all your swift and thorough suggestions, guys! I will try out all of them to learn these different tricks.


1

@shiftalow, @nssgames
Regarding palette animation, it's true that only 7 colors (counting transparency) are used across the 3 sprites, but each distinct ordered triplet of colors from the same position in three sprites needs a different color to pack the 3 sprites into one.
We only have 16 palette entries and have more than 20 distinct triplets, so no simple packing in this case.
If we take advantage of the fact that the 3rd sprite is a mirrored version of the second, we can check how many ordered duets for the 1st second frames that makes... and it's 15, so it's doable to store the first two sprites into one, and use mirroring in the code to display the third.
Here's an example of what the merged sprite might look like in the sprite-sheet :

It's not evident with this picture, but a single color doesn't have to be continuous. For example, the pink hands both become transparent in the 2nd frame, so they are the same color in the sprite sheet (orange).
This can often yield great palette entry savings (progressive fireworks, for example).


Recoloring can be pretty useful, though it's somewhat limited for animation, so I've found it to work best for changing tileset colors or simple background animations. I did make a system a while ago that lets you reassign colors however you want, though, if it would come in handy:
https://www.lexaloffle.com/bbs/?tid=40062



[Please log in to post a comment]