Scrolling backgroud

hello, anyone have an example of an infinite scrolling background? Thank you

1 Like

I haven't done exactly that, but I think I'd do it using one or more layers of sprites wider than the screen, each one resetting to the opposite edge of the screen once it is out of view in either direction.

1 Like

I'm also yet to do this but I believe you're looking for one of the following.

You vary the origin of the tiling to simulate scrolling/moving image.

playdate.graphics.image:drawTiled(x, y, width, height, [flip]) playdate.graphics.image:drawTiled(rect, [flip])
https://sdk.play.date/inside-playdate/#m-graphics.image.drawTiled

or
playdate.graphics.sprite:setStencilImage(stencil)
https://sdk.play.date/inside-playdate/#f-graphics.setStencilImage

This is for a tiled or patterned background!

1 Like

First of all, it is probably a good idea to chunk your stage. For 1D scrolling, you will probably have two chunks loaded at a time. For 2D scrolling, you will probably have 4. It probably makes sense for the chunks to be slightly larger than the screen size so you that you have time to load the next one in as the player moves. If different chunks use different tilesets, they will need to be loaded with the chunk.

Assuming your background is not animated, you can optimize by drawing to a rolling buffer. I do not think the Playdate natively supports rolling bitmap buffers, so you will probably need to use four draw calls to copy it for final rendering when scrolling in 2D.

If you are not familiar with a how a rolling buffer works, assume the buffer 32x32 tiles. The tiles at (0, 0), (32, 0), (64, 0)... all get written to the exact same place in the buffer. So do the tiles at (0, 32), (0, 64), etc. Say column 77 of your map scrolls in, 13 + 32 * 2 == 77, so everything in column 13 of your buffer would be overwritten with the contents column 77 in your stage. (Presumably it previously contained the stage data for column 45 if scrolling right, or the stage data for column 109 if scrolling left.)

I want to get around to writing a demo that uses infinite scrolling, but I am backed up.

EDIT: Rolling buffers can generally be used to optimize stages with animated backgrounds as well, assuming the entire map is not animated. Just overwrite the animated tiles at the appropriate buffer locations.

EDIT 2: You could just have a rolling buffer that completely loads 4 chunks. Move past the halfway mark, load the chunk on the other side if it is not already in memory. This code would probably be simpler and one draw call could be used to copy the appropriate portion of the buffer for final rendering. You could even split loading and rendering to the buffer across frames if you need to optimize.

2 Likes

thank you for your advice, to create starry animated background I chose this solution:
(beginner developer :blush:)

ezgif-5-ebf79bbb81

local function createBackgroundSprite()

local bg = gfx.sprite.new()

local bgImg = gfx.image.new('images/background.png')

local w, h = bgImg:getSize()

bgH = h

bg:setBounds(0, 0, 400, 240)

function bg:draw(x, y, width, height)

    bgImg:draw(0, bgY)

    bgImg:draw(0, bgY-bgH)

end

function bg:update()

    bgY = bgY + 1

    if bgY > bgH then

        bgY = 0

    end

    self:markDirty()

end

bg:setZIndex(0)

bg:add()

end

3 Likes

Just drawing the BG image twice is absolutely the simplest approach for 1D scrolling. If you want to be able to shift left and right, you will need to draw the image four times for 2D scrolling.

1 Like