sprite:collisionResponse triggering for all potential collisions

If I call moveWithCollisions to pass through several collide rects then it triggers for all the rects in the path.

NB: This isn't true for the collisions list returned from the method.

Here's an example to demonstrate:

import "CoreLibs/object"
import "CoreLibs/sprites"
import "CoreLibs/graphics"

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

local COLLIDE_GROUPS <const> = {
	A = 0x1,
	B = 0x2,
	C = 0x4,
	None = 0x8
}

class("SpriteA").extends(gfx.sprite)

function SpriteA:init(x, y)
	SpriteA.super.init(self)
	local image = gfx.image.new(32, 32)
	gfx.pushContext(image)
		gfx.drawRect(0, 0, image.width, image.height)
		gfx.drawTextInRect("A", 8, 8, image.width, image.height)
	gfx.popContext()
	self:setImage(image)
	self:setGroupMask(COLLIDE_GROUPS.A)
	self:setCollidesWithGroupsMask(COLLIDE_GROUPS.B | COLLIDE_GROUPS.C)
	self:setCollideRect(0, 0, image.width, image.height)
	self:moveTo(x, y)
	self:add()
end

function SpriteA:collisionResponse(other)
	print("Collision:  "..other.className)
end

class("SpriteB").extends(gfx.sprite)

function SpriteB:init(x, y)
	SpriteB.super.init(self)
	local image = gfx.image.new(32, 32)
	gfx.pushContext(image)
		gfx.drawRect(0, 0, image.width, image.height)
		gfx.drawTextInRect("B", 8, 8, image.width, image.height)
	gfx.popContext()
	self:setImage(image)
	self:setGroupMask(COLLIDE_GROUPS.B)
	self:setCollidesWithGroupsMask(COLLIDE_GROUPS.None)
	self:setCollideRect(0, 0, image.width, image.height)
	self:moveTo(x, y)
	self:add()
end

class("SpriteC").extends(gfx.sprite)

function SpriteC:init(x, y)
	SpriteC.super.init(self)
	local image = gfx.image.new(32, 32)
	gfx.pushContext(image)
		gfx.drawRect(0, 0, image.width, image.height)
		gfx.drawTextInRect("C", 8, 8, image.width, image.height)
	gfx.popContext()
	self:setImage(image)
	self:setGroupMask(COLLIDE_GROUPS.C)
	self:setCollidesWithGroupsMask(COLLIDE_GROUPS.None)
	self:setCollideRect(0, 0, image.width, image.height)
	self:moveTo(x, y)
	self:add()
end

local spriteA = SpriteA(50, 50)
SpriteB(100, 50)
SpriteC(150, 50)

spriteA:moveWithCollisions(150, 50)

function pd.update()
	gfx.sprite.update()
end

I've generated three sprites (A, B and C) and set their collide masks. A is moved through the two other sprites and the SpriteA:collideResponse() method prints the collision to the console.

Running this shows that two collisions are registered, despite the sprite freezing at sprite B.

21:09:54: SDK: C:\Users\banks\Documents\PlaydateSDK
21:09:54: Release: 2.0.1
21:09:54: CMD: C:\PlayDate\LearningSprites\builds\LearningSprites.pdx
21:09:54: Loading: C:\PlayDate\LearningSprites\builds\LearningSprites.pdx\
Collision:  SpriteB
Collision:  SpriteC
21:09:54: Loading: OK

image

The collisionResponse method is for checking how a sprite should respond to a collision, not performing the response. If Iā€™m understanding your code, it makes sense that it would have to call collisionResponse on all of the potential collisions, because it doesnā€™t know in advance that the first collision will return a freeze response ā€“ it could return slide, overlap, or bounce, which could potentially allow it to keep moving and collide with sprite C.

1 Like

That might be it, it makes sense.