Problem with 2D physics
Posted: Mon Aug 19, 2024 1:26 pm
Hey, I got a problem. so I created a Virus class, and when it collides with the player it should only stick to it, not move around or anything. But my problem is, when the virus' collision body collides with the player's, it passes through any other collision body after, like as if it's collision body is disabled. I'm using Windfield as the physics module. Here's the code:
virus.lua -
movement.lua (required by virus.lua) -
virus.lua -
Code: Select all
local Movement = require 'libraries/movement'
local Virus = {}
Virus.__index = Virus
function Virus.new(world, x, y, size, virusType)
local self = setmetatable({}, Virus)
self:init(world, x, y, size, virusType)
return self
end
function Virus:init(world, x, y, size, virusType)
self.collider = world:newCircleCollider(x, y, size)
self.size = size
self.virusType = virusType
self.movement = Movement.new(2000, 150, 0.9) -- Reduced speed and maxSpeed
self.health = virusType == "Unstable" and 200 or 100
self.damage = virusType == "Unstable" and 20 or 10
self.attackRange = 100
self.sticking = false
self.offsetX = 0
self.offsetY = 0
end
function Virus:update(dt, player)
if self.sticking then
self:stickToPlayer(player)
else
if self.virusType == "Passive" then
return
elseif self.virusType == "Hostile" then
self:moveTowardsPlayer(player)
elseif self.virusType == "Unstable" then
if math.random() > 0.5 then
self:moveTowardsPlayer(player)
end
end
end
end
function Virus:moveTowardsPlayer(player)
local px, py = player.collider:getPosition()
local x, y = self.collider:getPosition()
local distance = math.sqrt((px - x)^2 + (py - y)^2)
if distance < self.attackRange then
self.movement:moveTowards(self.collider, px, py)
end
end
function Virus:stickToPlayer(player)
local px, py = player.collider:getPosition()
self.collider:setPosition(px + self.offsetX, py + self.offsetY)
self.collider:setLinearVelocity(0, 0) -- Ensure no force is applied
end
function Virus:draw()
local x, y = self.collider:getPosition()
love.graphics.circle("fill", x, y, self.size)
end
function Virus:checkCollisionWithPlayer(player)
local px, py = player.collider:getPosition()
local x, y = self.collider:getPosition()
local distance = math.sqrt((px - x)^2 + (py - y)^2)
if distance < self.size + player.size then
self.sticking = true
self.offsetX = x - px
self.offsetY = y - py
self.collider:setLinearVelocity(0, 0) -- Stop the virus from moving
self.collider:setCollisionClass('Virus') -- Keep the collision class as 'Virus'
self.collider:setPreSolve(function(collider_1, collider_2, contact)
if (collider_1 == self.collider and collider_2 == player.collider) or
(collider_2 == self.collider and collider_1 == player.collider) then
contact:setEnabled(false) -- Disable collision response with the player
end
end)
end
end
return Virus
Code: Select all
local Movement = {}
Movement.__index = Movement
function Movement.new(speed, maxSpeed, deceleration)
local self = setmetatable({}, Movement)
self.speed = speed
self.maxSpeed = maxSpeed
self.deceleration = deceleration
return self
end
function Movement:handleInput(collider, controls)
local fx, fy = 0, 0
local vx, vy = collider:getLinearVelocity()
local movementApplied = false
if love.keyboard.isDown(controls.up) and vy > -self.maxSpeed then
fy = -self.speed
movementApplied = true
elseif love.keyboard.isDown(controls.down) and vy < self.maxSpeed then
fy = self.speed
movementApplied = true
end
if love.keyboard.isDown(controls.left) and vx > -self.maxSpeed then
fx = -self.speed
movementApplied = true
elseif love.keyboard.isDown(controls.right) and vx < self.maxSpeed then
fx = self.speed
movementApplied = true
end
if movementApplied then
collider:applyForce(fx, fy)
else
self:applyDeceleration(collider, vx, vy)
end
end
function Movement:applyDeceleration(collider, vx, vy)
vx, vy = vx * self.deceleration, vy * self.deceleration
if math.abs(vx) < 1 and math.abs(vy) < 1 then
vx, vy = 0, 0
end
collider:setLinearVelocity(vx, vy)
end
function Movement:moveTowards(collider, targetX, targetY)
local x, y = collider:getPosition()
local angle = math.atan2(targetY - y, targetX - x)
local fx = math.cos(angle) * self.speed
local fy = math.sin(angle) * self.speed
collider:applyForce(fx, fy)
end
return Movement