Hello Jakub,
thank you very much for your replay.
Thanks for your solution. I had something similar in mind, but it doesn't work.
What I try to achieve is on my game's main screen and/or on my game's gameplay screen, pressing the home button, I want to give the player a level select option. I decided to use a grid view, because I like the movement with the D-pad and the 'selected' parameter. I've seen other developers using the grid view as a sprite, which I didn't get to work either.
From the game screen I press home-button and select 'select level' option and the level select screen is loaded.
After selecting a level pressing the A-Button nothing seems to happen and the program is staying on level select screen.
Debugging the code, I can see that the level number is correctly selected, but it looks like the code is stuck in the A-button up function.
Could be that I do something fundamentally wrong in coding.
local pd <const> = playdate
local gfx <const> = playdate.graphics
local ldtk <const> = LDtk
oxydianFontInstance = gfx.font.new("font/font-full-circle")
gfx.setFont(oxydianFontInstance)
TAGS = {
Solid = 1,
WallBounce = 2,
circleStone = 3,
triangleStone = 4,
BounceStone = 5,
Player = 6,
Interactable = 7,
Pickup = 8,
MeshStone = 9,
Hazard = 10,
ArrowLeft = 11,
ArrowRight = 12,
ArrowUp = 13,
ArrowDown = 14,
WormHole = 15
}
Z_INDEXES = {
Player = 100,
WallBounce = 120,
PuzzleStone = 110,
MeshStone = 121,
Pickup = 90,
Gate = 0
}
Hit_DIRECTIONS = {
Up = 8,
Down = 8,
Left = 8,
Right = 8
}
Bounce_DIRECTIONS = {
Up = 10,
Down = 10,
Left = 10,
Right = 10
}
COLLISION_GROUPS = {
player = 1
}
ldtk.load("levels/oxydian.ldtk", false)
class("GameScene").extends()
function GameScene:init()
self:goToLevel("Level_1")
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 4
self:drawLevelNumber("1")
local systemMenu = pd.getSystemMenu()
systemMenu:removeAllMenuItems()
systemMenu:addMenuItem("Level select", function()
self:drawLevelScreen()
end)
systemMenu:addMenuItem("Restart level", function()
self:resetLevel()
end)
systemMenu:addMenuItem("Reset player", function()
self:resetPlayer()
end)
self.player = Player(self.spawnX, self.spawnY, self)
end
function GameScene:resetPlayer()
self.player:moveTo(self.spawnX, self.spawnY)
end
function GameScene:resetLevel()
local resetLevelNumber = string.match(self.levelname, "_(.*)")
if self.levelname == "Level_1" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_2" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
elseif self.levelname == "Level_3" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_4" then
self.spawnX = 7 * 28
self.spawnY = 5 * 28
elseif self.levelname == "Level_5" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_6" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
elseif self.levelname == "Level_7" then
self.spawnX = 3 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_8" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_9" then
self.spawnX = 8 * 28
self.spawnY = 6 * 28
elseif self.levelname == "Level_10" then
self.spawnX = 10 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_11" then
self.spawnX = 8.5 * 28
self.spawnY = 4.5 * 28
elseif self.levelname == "Level_12" then
self.spawnX = 8.5 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_13" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_14" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_15" then
self.spawnX = 2 * 28
self.spawnY = 3.5 * 28
elseif self.levelname == "Level_16" then
self.spawnX = 7 * 28
self.spawnY = 3.5 * 28
elseif self.levelname == "Level_17" then
self.spawnX = 1.5 * 28
self.spawnY = 2.5 * 28
elseif self.levelname == "Level_18" then
self.spawnX = 9 * 28
self.spawnY = 7 * 28
elseif self.levelname == "Level_19" then
self.spawnX = 7 * 28
self.spawnY = 3.5 * 28
elseif self.levelname == "Level_20" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
elseif self.levelname == "Level_21" then
self.spawnX = 10.5 * 28
self.spawnY = 3.5 * 28
elseif self.levelname == "Level_22" then
self.spawnX = 2 * 28
self.spawnY = 2.5 * 28
elseif self.levelname == "Level_23" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_24" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
elseif self.levelname == "Level_25" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
end
self:goToLevel(self.levelname)
self:drawLevelNumber(resetLevelNumber)
self.player = Player(self.spawnX, self.spawnY, self)
end
function GameScene:nextLevel()
local nextLevelNumber = string.match(self.levelname, "_(.*)")
nextLevelNumber = nextLevelNumber + 1
local nextLevelName = "Level_" .. nextLevelNumber
if nextLevelName == "Level_2" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
puzzleStoneCount = 6
elseif nextLevelName == "Level_3" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 12
elseif nextLevelName == "Level_4" then
self.spawnX = 7 * 28
self.spawnY = 5 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_5" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 12
elseif nextLevelName == "Level_6" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
puzzleStoneCount = 10
elseif nextLevelName == "Level_7" then
self.spawnX = 3 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 4
elseif nextLevelName == "Level_8" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_9" then
self.spawnX = 8 * 28
self.spawnY = 6 * 28
puzzleStoneCount = 6
elseif nextLevelName == "Level_10" then
self.spawnX = 10 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_11" then
self.spawnX = 8.5 * 28
self.spawnY = 4.5 * 28
puzzleStoneCount = 4
elseif nextLevelName == "Level_12" then
self.spawnX = 8.5 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_13" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_14" then
self.spawnX = 7 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_15" then
self.spawnX = 2 * 28
self.spawnY = 3.5 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_16" then
self.spawnX = 7 * 28
self.spawnY = 3.5 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_17" then
self.spawnX = 1.5 * 28
self.spawnY = 2.5 * 28
puzzleStoneCount = 6
elseif nextLevelName == "Level_18" then
self.spawnX = 9 * 28
self.spawnY = 7 * 28
puzzleStoneCount = 6
elseif nextLevelName == "Level_19" then
self.spawnX = 7 * 28
self.spawnY = 3.5 * 28
puzzleStoneCount = 10
elseif nextLevelName == "Level_20" then
self.spawnX = 7 * 28
self.spawnY = 6 * 28
puzzleStoneCount = 16
elseif nextLevelName == "Level_21" then
self.spawnX = 10.5 * 28
self.spawnY = 3.5 * 28
puzzleStoneCount = 4
elseif nextLevelName == "Level_22" then
self.spawnX = 2 * 28
self.spawnY = 2.5 * 28
puzzleStoneCount = 6
elseif nextLevelName == "Level_23" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 12
elseif nextLevelName == "Level_24" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 8
elseif nextLevelName == "Level_25" then
self.spawnX = 4 * 28
self.spawnY = 4 * 28
puzzleStoneCount = 6
end
self:goToLevel(nextLevelName)
self:drawLevelNumber(nextLevelNumber)
self.player = Player(self.spawnX, self.spawnY, self)
end
function GameScene:goToLevel(levelName)
if not levelName then return end
self.levelname = levelName
gfx.sprite.removeAll()
PuzzleStoneSet = {}
for layerName, layer in pairs(ldtk.get_layers(levelName)) do
if layer.tiles then
local tilemap = ldtk.create_tilemap(levelName, layerName)
local layerSprite = gfx.sprite.new()
layerSprite:setTilemap(tilemap)
layerSprite:setCenter(0, 0)
layerSprite:moveTo(0, 0)
layerSprite:setZIndex(layer.zIndex)
layerSprite:add()
for enum, tag in pairs(TAGS) do
local emptyTiles = ldtk.get_empty_tileIDs(levelName, enum, layerName)
if emptyTiles then
local tileSprites = gfx.sprite.addWallSprites(tilemap, emptyTiles)
for i=1,#tileSprites do
local tileSprite = tileSprites[i]
tileSprite:setTag(tag)
end
end
end
end
end
for _, entity in ipairs(ldtk.get_entities(levelName)) do
local entityX, entityY = entity.position.x, entity.position.y
local entityName = entity.name
if entityName == "PuzzleStone" then
PuzzleStone(entityX, entityY, entity)
elseif entityName == "BlackPuzzleStone" then
BlackPuzzleStone(entityX, entityY, entity)
elseif entityName == "MeshStone" then
MeshStone(entityX, entityY)
elseif entityName == "MeshStone2" then
MeshStone2(entityX, entityY)
elseif entityName == "MeshStone3" then
MeshStone3(entityX, entityY)
elseif entityName == "MeshStone4" then
MeshStone4(entityX, entityY)
elseif entityName == "Memo" then
Memo(entityX, entityY, entity)
elseif entityName == "Skull" then
Skull(entityX, entityY, entity)
elseif entityName == "ArrowLeft" then
ArrowLeft(entityX, entityY)
elseif entityName == "ArrowRight" then
ArrowRight(entityX, entityY)
elseif entityName == "BouncerStone" then
BouncerStone(entityX, entityY)
elseif entityName == "Umbrella" then
Umbrella(entityX, entityY, entity)
elseif entityName == "SwitchStone" then
SwitchStone(entityX, entityY, entity)
elseif entityName == "MeshTimerStone" then
MeshTimerStone(entityX, entityY, entity)
elseif entityName == "WormHole" then
WormHole(entityX, entityY, entity)
elseif entityName == "ArrowUp" then
ArrowUp(entityX, entityY)
elseif entityName == "ArrowDown" then
ArrowDown(entityX, entityY)
elseif entityName == "SpaceTile" then
SpaceTile(entityX, entityY)
end
end
end
function GameScene:drawLevelNumber(levelNumber)
LevelSprite = gfx.sprite.new()
local textWidth, textHeight = gfx.getTextSize(levelNumber)
local textImage = gfx.image.new(25, textHeight)
local x = 2
gfx.pushContext(textImage)
gfx.drawText("L"..levelNumber, 0, 0)
gfx.popContext()
LevelSprite:setImage(textImage)
LevelSprite:setCenter(0, 0)
LevelSprite:moveTo(x, 226)
LevelSprite:add()
end
function GameScene:drawLevelScreen()
--grid view --
oxydianFontInstance:setTracking(1)
local gridview = playdate.ui.gridview.new(28, 28)
gridview.backgroundImage = playdate.graphics.nineSlice.new('images/LevelSelect_Background', 4, 4, 28, 28)
gridview:setNumberOfColumns(10)
gridview:setNumberOfRows(5) -- number of sections is set automatically
gridview:setSectionHeaderHeight(0)
gridview:setContentInset(58, 4, 58, 4)
gridview:setCellPadding(0, 0, 0, 0)
gridview.changeRowOnColumnWrap = false
function gridview:drawCell(section, row, column, selected, x, y, width, height)
if selected then
gfx.setLineWidth(0)
gfx.fillRect(x, y, 23, 23)
gfx.setImageDrawMode(gfx.kDrawModeFillWhite)
else
gfx.setLineWidth(0)
gfx.drawRect(x, y, 24, 24)
gfx.setImageDrawMode(gfx.kDrawModeCopy)
end
if row == 1 then
cellText = ""..row * column
elseif row == 2 then
cellText = ""..((row - 1) * column) + 10
elseif row == 3 then
cellText = ""..((row - 2) * column) + 20
elseif row == 4 then
cellText = ""..((row - 3) * column) + 30
elseif row == 5 then
cellText = ""..((row - 4) * column) + 40
end
gfx.setFont(oxydianFontInstance)
gfx.drawTextInRect(cellText, x - 2, y + 6, width, height, nil, nil, kTextAlignment.center)
end
-- buttons --
function pd.AButtonUp()
local section, row, column = gridview:getSelection()
if row == 1 then
levelNumber = row * column
elseif row == 2 then
levelNumber = ((row - 1) * column) + 10
elseif row == 3 then
levelNumber = ((row - 2) * column) + 20
elseif row == 4 then
levelNumber = ((row - 3) * column) + 30
elseif row == 5 then
levelNumber = ((row - 4) * column) + 40
end
local levelname <const> = "Level_" .. levelNumber
self:goToLevel(levelname)
end
function pd.upButtonUp()
gridview:selectPreviousRow(true)
end
function pd.downButtonUp()
gridview:selectNextRow(true)
end
function pd.leftButtonUp()
gridview:selectPreviousColumn(true)
end
function pd.rightButtonUp()
gridview:selectNextColumn(true)
end
function pd.update()
if gridview.needsDisplay == true then
gridview:drawInRect(0, 0, 400, 240)
end
end
end