How to update as collision happens

Problem:
My detections are happening after the player collides, either freezing infront and then updating after moving away or going over a overlap collision.
Is there anyway I can have it update when the collision is happening and not after it happens?

Collision Code

local actualX, actualY, collisions, numeberOfCollisions = self:moveWithCollisions(self.x,self.y)
    for i=1, numeberOfCollisions do 
        local collision = collisions[i]
        local collidedSprite = collision.other
        local collisionTag = collidedSprite:getTag()
        if collisionTag == 1 then 
            if collisionDect == "F" then 
                collisionDect = "T"
            elseif collisionDect == "T" then 
                collisionDect = "F"
            end 
            return gfx.sprite.kCollisionTypeOverlap
        end 
    end

I'm trying to update collisionDect whenever the player goes into and out of the collision sprite; which is a invisible box under certain objects that I want to be interactable. I'm using it to check if the player is near a interactable object and if the collisionDect = "T" and they press the A button then dialogue would appear. I think if I were to use alphacollision detection it may work; since it deletes the need of a separate sprite for collisions, but I have no clue how to use it since I call in objects with this function

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

function Obj:init(x,y,cx,cy,l,h,image,Tag)
    self:setImage(image)
    self:moveTo(x,y)
    self:setZIndex(1)
    self:add()
    self:setCollideRect(cx,cy,l,h)
    self:setTag(Tag)
    self:setGroups(1)
end

I want whenever the player to enter the collision Sprite the collisionDect should be "T" and whenever the player leaves collisionDect should be "F".

You could assign 'F' to collisionDect right before the loop that handles collisions, then assign 'T' to collisionDect if one of the other sprite's tags is 1. That will make it so that collisionDect will always have a value of 'T' when the player is currently overlapping an interactable sprite and 'F' when the player is not currently overlapping an interactable sprite.

The collision Tag is already "F" and the player tag is 1 (My current tags are player = 1 detect = 2 cone = 3 and table = 4). I plan to use the tags for descriptions and that's why I have the groups so all sprites created with the Obj function share the same collision group. I might have been unclear but it works like button, you collide with it and it's "T" and if you collide with it again and it's back to "F". The set up I have would work if it didn't change the value after you left the collision. I want it CollisionDect to be "T" when you enter the collision and "F" when you leave. (like how it goes Collision True if the player is in and Collision False if the player is out in this squidgod video https://www.youtube.com/watch?v=27vCPiwgWzQ&t=340s)

Hmm. In the collision code that you posted, is it the player or a detect sprite that is being moved with collisions? It's bedtime for me, but here is some code and a demo. I'll check back in tomorrow. Hope it helps!

example

local player <const> = playdate.graphics.sprite.new(
	playdate.graphics.image.new(
		16,
		16,
		playdate.graphics.kColorBlack
	)
)

local interactable <const> = playdate.graphics.sprite.new(
	playdate.graphics.image.new(
		24,
		24,
		playdate.graphics.kColorBlack
	)
)

local collisionDect = 'F'

function player:collisionResponse(other)
	if other:getTag() == 2 then
		return playdate.graphics.sprite.kCollisionTypeOverlap
	end
	return playdate.graphics.sprite.kCollisionTypeSlide
end

function player:update()
	local dx = 0
	local dy = 0

	if playdate.buttonIsPressed(playdate.kButtonLeft) then
		dx = -1
	elseif playdate.buttonIsPressed(playdate.kButtonRight) then
		dx = 1
	end

	if playdate.buttonIsPressed(playdate.kButtonUp) then
		dy = -1
	elseif playdate.buttonIsPressed(playdate.kButtonDown) then
		dy = 1
	end

	local actualX <const>, actualY <const>, collisions <const>, length <const> = player:moveWithCollisions(player.x + dx, player.y + dy)

	collisionDect = 'F'
	for i = 1, #collisions do
		local collision <const> = collisions[i]
		if collision.other:getTag() == 2 then
			collisionDect = 'T'
		end
	end
end

player:setTag(1)
player:setGroups({1})
player:setCollidesWithGroups({1})
player:setCollideRect(0, 0, player:getSize())
player:moveTo(240, 120)
player:add()

interactable:setTag(2)
interactable:setGroups({1})
interactable:setCollideRect(0, 0, interactable:getSize())
interactable:moveTo(200, 120)
interactable:add()

function playdate.update()
	playdate.graphics.sprite.update()
	playdate.graphics.drawText('Overlapping interactable sprite? '..collisionDect, 10, 10)
end

It seems to work, I just needed to put the collisionDect = "F" into the player update function and remove return gfx.sprite.kCollisionTypeOverlap from the collision detection in the player update. Thanks again for the help!

1 Like