(Found using Lua SDK on Mac)
Expected behavior:
playdate.graphics.sprite:checkCollisions(x, y) should return an array of collisions with the sprite's collision rect.
Observed behavior:
when there are multiple overlapping collision rects, only a single one is returned by checkCollisions
You can see this in the following gif, which queries checkCollisions
every frame and should display all collisions on the screen:
additionally, it should print a message to the console when if there are multiple collisions in the response, but this message is never printed.
The issue can be reproduced with the following main.lua:
-- main.lua for collision test
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
local gfx <const> = playdate.graphics
-- Here's our sprite declaration
-- pre-render "player" image
local playerImage = gfx.image.new(20, 20)
gfx.lockFocus(playerImage)
-- black outline
gfx.setColor(gfx.kColorBlack)
gfx.fillCircleAtPoint(10, 10, 10)
-- white box in the middle
gfx.setColor(gfx.kColorWhite)
gfx.fillRect(8, 8, 4, 4)
gfx.unlockFocus()
local playerSprite = gfx.sprite.new( playerImage )
playerSprite:setCenter( 0.5, 0.5 )
playerSprite:moveTo( 200, 120 )
playerSprite:setCollideRect( 0, 0, playerSprite:getSize() )
playerSprite:add()
gfx.setLineWidth(3)
-- define box 1
local box_image = gfx.image.new(50, 50)
gfx.lockFocus(box_image)
gfx.setColor(gfx.kColorBlack)
gfx.drawRect(0, 0, 50, 50)
gfx.drawText("box1", 10, 10)
gfx.unlockFocus()
local box1 = gfx.sprite.new(box_image )
box1:setCenter( 0.5, 0.5 )
box1:moveTo( 100, 120 )
box1.name = "box1"
box1:setCollideRect( 0, 0, box1:getSize() )
box1:add()
-- define box 2
local box_image = gfx.image.new(50, 50)
gfx.lockFocus(box_image)
gfx.setColor(gfx.kColorBlack)
gfx.drawRect(0, 0, 50, 50)
gfx.drawText("box2", 10, 10)
gfx.unlockFocus()
local box2 = gfx.sprite.new(box_image )
box2:setCenter( 0.5, 0.5 )
box2:moveTo( 300, 120 )
box2.name = "box2"
box2:setCollideRect( 0, 0, box2:getSize() )
box2:add()
-- define box 3
local box_image = gfx.image.new(100, 100)
gfx.lockFocus(box_image)
gfx.setColor(gfx.kColorBlack)
gfx.drawRect(0, 0, 100, 100)
gfx.drawText("box3", 10, 10)
gfx.unlockFocus()
local box3 = gfx.sprite.new(box_image )
box3:setCenter( 0.5, 0.5 )
box3:moveTo( 180, 130 )
box3.name = "box3"
box3:setCollideRect( 0, 0, box3:getSize() )
box3:add()
-- define box 4
local box_image = gfx.image.new(100, 100)
gfx.lockFocus(box_image)
gfx.setColor(gfx.kColorBlack)
gfx.drawRect(0, 0, 100, 100)
gfx.drawText("box4", 10, 10)
gfx.unlockFocus()
local box4 = gfx.sprite.new(box_image )
box4:setCenter( 0.5, 0.5 )
box4:moveTo( 220, 180 )
box4.name = "box4"
box4:setCollideRect( 0, 0, box4:getSize() )
box4:add()
-- main update function
function playdate.update()
-- Poll the d-pad and move our player accordingly.
if playdate.buttonIsPressed( playdate.kButtonUp ) then
playerSprite:moveBy( 0, -2 )
end
if playdate.buttonIsPressed( playdate.kButtonRight ) then
playerSprite:moveBy( 2, 0 )
end
if playdate.buttonIsPressed( playdate.kButtonDown ) then
playerSprite:moveBy( 0, 2 )
end
if playdate.buttonIsPressed( playdate.kButtonLeft ) then
playerSprite:moveBy( -2, 0 )
end
-- update sprites
gfx.sprite.update()
gfx.drawText("Collision test", 10, 10)
-- collision detection
local positionX,positionY,collisionsP,lengthP = playerSprite:checkCollisions(playerSprite.x,playerSprite.y)
-- print the name of all objects on screen that the player is colliding with
if lengthP>0 then
for i=1,lengthP do
local object = collisionsP[i].other
gfx.drawText("Collision with " .. object.name , 250, 20 * i)
end
end
-- the condition below should trigger if the player's hitbox overlaps with several hitboxres, but as we'll see this never triggers!
if lengthP > 1 or #collisionsP > 1 then
print("PLAYER IS OVERLAPPING WITH MULTIPLE OBJECTS!")
end
end