Log In  


I wanted to take a screenshot and draw it back to the screen like a sprite.

This is useful for screen transitions, like in Bubble Bobble where you scroll up to the next level.

The nice folks on the Pico-8 discord helped me put together this, which copies the screen to 0x8000 (the extended map location in 2.4+). Then when we want to draw it we copy it over the whole sprite sheet, draw that like a sprite, then reload the original sprite sheet.

Cart #screengrab_sprite-0 | 2023-01-16 | Code ▽ | Embed ▽ | No License
1

function _init()
	cls()
	-- make something to screengrab
	for x=0,127,8 do
		for y=0,127,8 do
			rect(x, y, x+7, y+7, flr(rnd(16)))
		end
	end
	target_x, target_y = 0,0
	screengrab()
end

function _update()
	-- test we can draw the screengrab to a different place
	target_x = (target_x + 1) % 128
end

function _draw()
	cls()
	-- copy to sprite sheet location
	memcpy(0x0000, 0x8000, 8192)
	-- draw it to screen
	sspr(0, 0, 128, 128, target_x, target_y)
	-- restore the sprite sheet
	reload(0x0000,0x0000,8192)
	-- debug where the screen should be painted to
	rect(target_x, target_y, target_x + 2, target_y + 2, 7)
	-- check we reloaded the sprite sheet
	spr(0, target_x, target_y + 8)
end

-- copy the screen to extended map location
function screengrab()
	memcpy(0x8000,0x6000,8192)
end

Other methods could be used like using memcpy to paint direct from memory - which would be a lot faster. This thread may offer some help with that.

If anyone would like to improve on this example please do. There's not a lot of posts on the subject that offer any working examples so the more the merrier.

1


FReDs72 on Discord suggested this alternative for just scrolling the screen away:

function _init()
	cls()
	-- make something to screengrab
	for x=0,127,8 do
	 for y=0,127,8 do
		rect(x, y, x+7, y+7, flr(rnd(16)))
	 end
	end
	dx, dy = 0,-1
  sx,sy = -128*mid(-1,1,dx\0x.0001),-128*mid(-1,1,dy\0x.0001)
 end

 function _update()
	sx+=dx
	sy+=dy
	-- end of transition
	if(sx%128==0) dx=0
	if(sy%128==0) dy=0
 end

 function _draw()
	palt(0,false)
	-- use screen as sprite source
	poke(0x5f54,0x60)
	-- shift screen dx/dy pixels
	sspr(0,0,128,128,dx,dy)
	-- reset
	poke(0x5f54,0x00)

	-- next level
	camera(-sx,-sy)
	rectfill(0,0,127,127,0)
	rect(0,0,127,127,7)
	print("next level",56,64,7)
	camera()
 end

This uses the screen itself as a sprite sheet instead of storing it in memory.



[Please log in to post a comment]