Hi, I'm a new dev trying to create a background image that I can move using the crank. Currently, I have the mechanic working, except for the fact that in its current state (not a background image) I can't display sprites above the image. I've tried using setZIndex on both my test sprite and my image, but it still doesn't seem to work.
Due to the way I've implemented moving the image up and down with the crank (creates a scrolling effect) I'm adjusting the y position of the image every time there's a change in the crank position, and at each draw, I'm using drawAnchored because I want the default position to show the bottom of the image (not the top).
Could I get some guidance on what the best course of action would be here? In essence, I just need the image as far back as possible and have the ability to scroll/move it on the y-axis, while being able to display sprites above it. Thanks!
main.lua:
--main imports
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
--declarations
local gfx <const> = playdate.graphics
local baseY = 240
--setup func
local function setup()
--board image
backgroundImage = gfx.image.new("images/background")
assert( backgroundImage )
--star test
local testStar = gfx.image.new("images/testStar")
testStarDisplay = gfx.sprite.new(testStar)
end
function scrollBoard()
local change, acceleratedChange = playdate.getCrankChange()
baseY += change
if acceleratedChange > 15 then
acceleratedChange = 15
end
if acceleratedChange < -15 then
acceleratedChange = -15
end
baseY += acceleratedChange
if baseY <= 400 then
if baseY >= 240 then
backgroundImage:drawAnchored(0, baseY, 0.0, 1.0)
else
baseY = 240
backgroundImage:drawAnchored(0, 240, 0.0, 1.0)
end
else
baseY = 400
backgroundImage:drawAnchored(0, 400, 0.0, 1.0)
end
end
--calling setup functions
setup()
--main update func
function playdate.update()
gfx.sprite.update()
scrollBoard()
if playdate.buttonIsPressed(playdate.kButtonA) then
print("pressed")
testStarDisplay:moveTo(200, 120)
print("after move")
testStarDisplay:add()
print("after add")
testStarDisplay:setZIndex(32767)
print("after zindex")
end
playdate.drawFPS(0, 0)
end
You should just be able to call gfx.sprite.update() after scrollBoard() instead of before. When you draw an image directly (not in a sprite), it is not influenced by ZIndex or any other factors other than the order the draw functions are called.
Yeah, it seems like gfx.sprite.update() clears the screen when it's called, so I guess it isn't possible to draw images behind sprites without making the background itself a sprite. I reimplemented the background as a sprite, and it seems to work correctly. I wasn't really sure what you meant by the default position showing the bottom of the image, so I just used the top left as the origin, but you could change the center to setCenter(0, 1) if you want.
--main imports
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
--declarations
local gfx <const> = playdate.graphics
local baseY = 0
--setup func
local function setup()
--board image
backgroundImage = gfx.image.new("images/background")
backgroundSprite = gfx.sprite.new(backgroundImage)
backgroundSprite:setZIndex(-32768)
backgroundSprite:setCenter(0, 0)
backgroundSprite:add()
assert( backgroundImage )
--star test
local testStar = gfx.image.new("images/testStar")
testStarDisplay = gfx.sprite.new(testStar)
end
function scrollBoard()
local change, acceleratedChange = playdate.getCrankChange()
baseY += change
if acceleratedChange > 15 then
acceleratedChange = 15
end
if acceleratedChange < -15 then
acceleratedChange = -15
end
baseY += acceleratedChange
if baseY < 0 then baseY = 0 end
backgroundSprite:moveTo(0, baseY)
end
--calling setup functions
setup()
--main update func
function playdate.update()
gfx.sprite.update()
scrollBoard()
if playdate.buttonIsPressed(playdate.kButtonA) then
print("pressed")
testStarDisplay:moveTo(200, 120)
print("after move")
testStarDisplay:add()
print("after add")
testStarDisplay:setZIndex(32767)
print("after zindex")
end
playdate.drawFPS(0, 0)
end
I had to edit the scrollboard func a little from what you changed as it wasn't working completely(I also didn't fully understand what you wrote) but everything works! I also essentially replicated drawAnchored(0, 240, 0.0, 1.0) by using setCenter(0, 1) (thank you for that) and moveTo(0, 240).
For anyone who might have the same issue in the future this is the full edited code:
--main imports
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
--declarations
local gfx <const> = playdate.graphics
local baseY = 0
--setup func
local function setup()
--board sprite
backgroundImage = gfx.image.new("images/background")
backgroundSprite = gfx.sprite.new(backgroundImage)
backgroundSprite:setZIndex(-32768)
backgroundSprite:setCenter(0, 1)
backgroundSprite:moveTo(0, 240)
backgroundSprite:add()
assert( backgroundImage )
--star test
local testStar = gfx.image.new("images/testStar")
testStarDisplay = gfx.sprite.new(testStar)
end
--scrolling along using the crank
function scrollBoard()
--get change
local change, acceleratedChange = playdate.getCrankChange()
--adding the change in crank value to baseY
baseY += change
--making sure you can't crank too quickly and produce a glithc effect
if acceleratedChange > 10 then
acceleratedChange = 10
end
if acceleratedChange < -10 then
acceleratedChange = -10
end
--adding the acceleratedChange to the total baseY var
baseY += acceleratedChange
--scrolling & adding a limit to how far you can scroll
if baseY <= 400 then
if baseY >= 240 then
backgroundSprite:moveTo(0, baseY)
else
baseY = 240
backgroundSprite:moveTo(0, baseY)
end
else
baseY = 400
backgroundSprite:moveTo(0, baseY)
end
end
--calling setup function(s)
setup()
--main display update func
function playdate.update()
gfx.sprite.update()
scrollBoard()
--button star sprite test
if playdate.buttonIsPressed(playdate.kButtonA) then
testStarDisplay:moveTo(200, 120)
testStarDisplay:add()
testStarDisplay:setZIndex(32767)
end
playdate.drawFPS(0, 0)
end
I found I had to make my background tile map a sprite aswell to have it show up below the player. It seems that the single file tilemap example maybe out of date or something as I cannot for the life of me work out how they display the map without adding it to a sprite but it still works ?!
I’m Currently stuck trying to implement Addwallsprites to the right tiles