Making a Menu with Gridview inside a subclass/scene

Hello, everyone!

I've been working on my first game and have hit a problem I can't quite solve with my limited lua experience.

I've used SquidGod's scene-manager technique to set up multiple scenes.

This means my main.lua file is basically empty and I have a number of separate .lua files that contain the code for each scene. The scene_manager allows me to transition between one scene and the next.

I've been trying to implement a menu inside of one of these scenes and I can't get it to display.

Here's my code - is there any way to get this gridview to appear within a class like this?

import "scripts/gameScene"

local pd <const> = playdate
local gfx <const> = playdate.graphics

class('scene03_menu').extends(gfx.sprite)

local gridview = pd.ui.gridview.new(32, 32)

gridview:setNumberOfColumns(8)
gridview:setNumberOfRows(6)

function scene03_menu:init()
    local backgroundImage = gfx.image.new("images/menu")
    gfx.sprite.setBackgroundDrawingCallback(function()
        backgroundImage:draw(0, 0)
    end)
    self:setZIndex(-1000)
    self:add()
end

function scene03_menu:update()
    gridview:drawInRect(100, 70, 200, 100)
    if pd.buttonJustPressed(pd.kButtonA) then
        SCENE_MANAGER:switchScene(GameScene)
    end
end

I've found that using this gridview code in my main.lua file makes it display, but when used inside my class like this, it won't display at all. SquidGod does mention in his Scene Manager video that a drawback is 'no overlaid scenes' - is that referring to this exact problem?

Any suggestions? I'd like to be able to have a level select on the main menu, and a 'replay or select level' sort of table upon Game Over. Is there a better implementation of a level select I should consider instead?

Thanks for your help!
-Darrell

Did you solve this? The way to do it is to call self:setSize(400,240) in init() and then implement draw(), and call the gridview draw in that.

Alternatively, you can create an image of the screen's size, assign the image to the sprite in init(), and draw it to the image in the update.

As a third option, you could add your draw to the background drawing callback you create.

Hi, I'm having the same issue as OP, would you be able to elaborate on this a bit more? What do you mean by implementing draw()? Thanks!

Hello!
Yes, you can override a sprite's draw() function and do your own drawing in there instead of using an image. To make it work, you first need to set the sprite's size (In this case I recommended using 400x240 but I see from the original code it should be 200x100). So the code would look something like this:

-- recommend doing all your imports from main.lua
--import "scripts/gameScene"

local pd <const> = playdate
local gfx <const> = playdate.graphics

class('scene03_menu').extends(gfx.sprite)

function scene03_menu:init()
    local backgroundImage = gfx.image.new("images/menu")
    gfx.sprite.setBackgroundDrawingCallback(function()
        backgroundImage:draw(0, 0)
    end)
    self:setZIndex(-1000)
    self:add()

    -- set size to enable draw
    self:setSize(200, 100)
    -- move to the right spot
    self:moveTo(100, 70)

    -- define the gridview locally and assign to this sprite's table
    local gridview = pd.ui.gridview.new(32, 32)

    gridview:setNumberOfColumns(8)
    gridview:setNumberOfRows(6)

    self.gridview = gridview
end

function scene03_menu:update()
    if pd.buttonJustPressed(pd.kButtonA) then
        SCENE_MANAGER:switchScene(GameScene)
    end
end

function scene03_menu:draw(x,y,w,h)
    -- coordinates are now local to the sprite so we draw from 0, 0
    self.gridview:drawInRect(0, 0, self.width, self.height)
end
1 Like

This worked, thank you!!

1 Like