in simulator and on hardware
Hey y’all! I’m using several gridviews in our game simultaneously, which slide on and off screen based on user input. They often overlap rapidly, so I need to have all the gridviews created and ready to go at once. There are a couple I’d like to manipulate while they’re offscreen, setting their scroll & selection. But I’m running into a bug where trying to scroll one gridview will very often scroll another.
I can’t figure out why this is happening, nor can I figure out exactly what determines the order they receive control in our more-complicated game. But I have replicated the bug in a very simple example. Here’s a full main.lua which illustrates the problem:
local gfx = playdate.graphics import 'CoreLibs/ui' local grid1 = playdate.ui.gridview.new(120, 100) grid1:setNumberOfColumns(10) grid1:setNumberOfRows(1) grid1:setScrollDuration(400) grid1.scrollCellsToCenter = true -- section, row, column grid1:setSelection(1, 1, 1) grid1:scrollCellToCenter(1, 1, 1, false) local grid2 = playdate.ui.gridview.new(120, 100) grid2:setNumberOfColumns(10) grid2:setNumberOfRows(1) grid2:setScrollDuration(400) grid2.scrollCellsToCenter = true grid2:setSelection(1, 1, 3) --[[ HERE'S THE BUG: ]] --[[ This should scroll grid2, but it scrolls grid1 ]] grid2:scrollCellToCenter(1, 1, 3, false) gfx.setColor(gfx.kColorBlack) gfx.setStrokeLocation(gfx.kStrokeInside) function playdate.update() gfx.clear() handleInput() -- gfx.drawText('test', 0, 0) grid1:drawInRect(0, 1, 400, 100) grid2:drawInRect(0, 102, 400, 100) gfx.drawText('*left/right to move grid1, B/A to move grid2*', 44, 212) playdate.timer.updateTimers() end function handleInput() if playdate.buttonJustPressed('left') then grid1:selectPreviousColumn() end if playdate.buttonJustPressed('right') then grid1:selectNextColumn() end if playdate.buttonJustPressed('B') then grid2:selectPreviousColumn() end if playdate.buttonJustPressed('A') then grid2:selectNextColumn() end end function grid1:drawCell(section, row, column, selected, x, y, width, height) gfx.pushContext() gfx.drawText('grid1 cell '..column, x + 10, y + 10) if selected then gfx.drawText('*selected*', x + 10, y + 38) gfx.setLineWidth(3) end gfx.drawRoundRect(x, y, width, height, 4) gfx.popContext() end function grid2:drawCell(section, row, column, selected, x, y, width, height) gfx.pushContext() gfx.drawText('grid2 cell '..column, x + 10, y + 10) if selected then gfx.drawText('*selected*', x + 10, y + 38) gfx.setLineWidth(3) end gfx.drawRoundRect(x, y, width, height, 4) gfx.popContext() end
Here’s what I’d expect to see, with grid2 having selected AND scrolled to column 3:
but instead I see:
Selection is assigned on
grid1 is scrolled instead! Here is it in motion, starting with a fresh boot, then pressing right twice to move the upper
grid1, then A A B B to move the lower
Now, I’ve been able to paper over this a few times by manually scrolling another gridview while it’s not visible, but I’ve run into one where I just can’t get it to work. The game opens on a view of the room, which is a gridview with each cell showing a different portion of the room. When it boots, I’ve attempted to scroll the offscreen gridview for the Ingredients Shelf to column 3, attempting to skip 2 empty cells so that the first ingredient appears centered. Here’s what that looks like:
Now, no matter what I do, or how many times I try to scroll that second grid’s position, I can’t do it, unless I run an attempt every frame after activating the ingredients shelf, in which case it scrolls on the SECOND frame. Weird!!! If I try to force the ingredient selection’s update loop to try scrolling every frame once it’s activated, look at this:
The first update trying to scroll
grid2 actually scrolls
grid1 to its 3rd cell (the one with the book), while the second update actually scrolls
grid2, moving the coffee bean into position.
I’ve tried so many things to try and trick this into happening in a different order, but I can’t get it to work. It seems to have to do with the order they’re created; but I can’t make sense of why
grid2 ever receives its scroll commands if they’re being intercepted in the first place. Except that manually triggering
selectPreviousColumn() with button input always seems to reach the correct gridview. So it seems like something within
And the main difference I see between
gridview:scrollCellToCenter() and the methods to select next or previous column is that those methods used the
local function scrollToSelectedCell(), whereas
gridview:scrollCellToCenter() doesn’t? That could be where the problem is, now that I’m looking about it? Because I think I’ve encountered this same bug trying to use
gridview:scrollToTop(), which also uses
BUT, I’ve also tried using grid2:selectNextColumn() before it comes into view, and for some reason that doesn’t seem to work until after it’s visible? So, that’s all I’ve figured out so far!
Any help is, of course, much appreciated!