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.