Collision Bug
Posted: Thu Nov 23, 2023 6:27 pm
Hello. This is my first post on the Love2D forums. I have a game I'm working on and in the game you can throw knives at enemies. When you throw knives at walls they are supposed to move 8 pixels in the direction of the wall and destroy the body to give the illusion that the knife has sunk into the wall. Instead, it just sits infront of the wall and does nothing. Here is the video of the bug:
https://www.youtube.com/watch?v=69MR-PiTork
Here is my code (knife.lua):
Knife = {img = love.graphics.newImage("map/knife_textures/knife_texture1.png")}
Knife.__index = Knife
Knife.width = 16
Knife.height = 16
ActiveKnifes = {}
require("enemy")
require("player")
function Knife.new(x, y, direction)
local instance = setmetatable({}, Knife)
instance.x = x
instance.y = y
instance.r = -90
instance.destroyed = false
instance.direction = direction
instance.physics = {}
instance.physics.body = love.physics.newBody(World, instance.x, instance.y, "dynamic")
instance.physics.shape = love.physics.newRectangleShape(instance.width, instance.height)
instance.physics.fixture = love.physics.newFixture(instance.physics.body, instance.physics.shape)
instance.physics.fixture:setUserData("Knife")
instance.scaleX = 1
if direction == "left" then
instance.scaleX = -1
instance.r = 90
end
instance.physics.body:setGravityScale(0)
table.insert(ActiveKnifes, instance)
return instance
end
function Knife:update(dt)
if self.physics.body:isDestroyed() == false then
self:syncPhysics()
end
end
function Knife:syncPhysics()
if self.physics.body:isDestroyed() == false then
self.x, self.y = self.physics.body:getPosition()
if self.scaleX == -1 then
self.r = self.r - 0.5
elseif self.scaleX == 1 then
self.r = self.r + 0.5
end
if self.direction == "left" then
self.physics.body:setLinearVelocity(-500, 0)
elseif self.direction == "right" then
self.physics.body:setLinearVelocity(500, 0)
end
end
end
function Knife:draw()
if self.physics.body:isDestroyed() == false then
love.graphics.draw(self.img, self.x, self.y, self.r, self.scaleX, 1, self.width / 2, self.height / 2)
end
end
function Knife.updateAll()
for i, v in ipairs(ActiveKnifes) do
v:update(dt)
end
end
function Knife.drawAll()
for i, v in ipairs(ActiveKnifes) do
v:draw()
end
end
function Knife:beginContact(a, b, collision)
if self.physics.body:isDestroyed() == false then
local nx, ny = collision:getNormal()
if a:getUserData() ~= "Knife" and b:getUserData() ~= "Knife" and a ~= Player.physics.fixture and b ~= Player.physics.fixture then
if b:getUserData() == "Enemy" or b:getUserData() == "Box" or b:getUserData() == "Crate" then
for i,v in ipairs(ActiveKnifes) do
if v == self then
table.remove(ActiveKnifes, i)
end
end
if b:getUserData() == "Enemy" then
love.audio.newSource("sound_effects/StabSound.mp3", "static"):play()
end
elseif a:getUserData() == "Enemy" or a:getUserData() == "Box" or a:getUserData() == "Crate" then
for i,v in ipairs(ActiveKnifes) do
if v == self then
table.remove(ActiveKnifes, i)
end
end
if a:getUserData() == "Enemy" then
love.audio.newSource("sound_effects/StabSound.mp3", "static"):play()
end
end
if self.scaleX == 1 then
self.x = self.x + 8
elseif self.scaleX == -1 then
self.x = self.x - 8
end
self.physics.body:destroy()
end
end
end
function Knife:removeAll()
ActiveKnifes = {}
end
return {
Knife = Knife,
ActiveKnifes = ActiveKnifes
}
https://www.youtube.com/watch?v=69MR-PiTork
Here is my code (knife.lua):
Knife = {img = love.graphics.newImage("map/knife_textures/knife_texture1.png")}
Knife.__index = Knife
Knife.width = 16
Knife.height = 16
ActiveKnifes = {}
require("enemy")
require("player")
function Knife.new(x, y, direction)
local instance = setmetatable({}, Knife)
instance.x = x
instance.y = y
instance.r = -90
instance.destroyed = false
instance.direction = direction
instance.physics = {}
instance.physics.body = love.physics.newBody(World, instance.x, instance.y, "dynamic")
instance.physics.shape = love.physics.newRectangleShape(instance.width, instance.height)
instance.physics.fixture = love.physics.newFixture(instance.physics.body, instance.physics.shape)
instance.physics.fixture:setUserData("Knife")
instance.scaleX = 1
if direction == "left" then
instance.scaleX = -1
instance.r = 90
end
instance.physics.body:setGravityScale(0)
table.insert(ActiveKnifes, instance)
return instance
end
function Knife:update(dt)
if self.physics.body:isDestroyed() == false then
self:syncPhysics()
end
end
function Knife:syncPhysics()
if self.physics.body:isDestroyed() == false then
self.x, self.y = self.physics.body:getPosition()
if self.scaleX == -1 then
self.r = self.r - 0.5
elseif self.scaleX == 1 then
self.r = self.r + 0.5
end
if self.direction == "left" then
self.physics.body:setLinearVelocity(-500, 0)
elseif self.direction == "right" then
self.physics.body:setLinearVelocity(500, 0)
end
end
end
function Knife:draw()
if self.physics.body:isDestroyed() == false then
love.graphics.draw(self.img, self.x, self.y, self.r, self.scaleX, 1, self.width / 2, self.height / 2)
end
end
function Knife.updateAll()
for i, v in ipairs(ActiveKnifes) do
v:update(dt)
end
end
function Knife.drawAll()
for i, v in ipairs(ActiveKnifes) do
v:draw()
end
end
function Knife:beginContact(a, b, collision)
if self.physics.body:isDestroyed() == false then
local nx, ny = collision:getNormal()
if a:getUserData() ~= "Knife" and b:getUserData() ~= "Knife" and a ~= Player.physics.fixture and b ~= Player.physics.fixture then
if b:getUserData() == "Enemy" or b:getUserData() == "Box" or b:getUserData() == "Crate" then
for i,v in ipairs(ActiveKnifes) do
if v == self then
table.remove(ActiveKnifes, i)
end
end
if b:getUserData() == "Enemy" then
love.audio.newSource("sound_effects/StabSound.mp3", "static"):play()
end
elseif a:getUserData() == "Enemy" or a:getUserData() == "Box" or a:getUserData() == "Crate" then
for i,v in ipairs(ActiveKnifes) do
if v == self then
table.remove(ActiveKnifes, i)
end
end
if a:getUserData() == "Enemy" then
love.audio.newSource("sound_effects/StabSound.mp3", "static"):play()
end
end
if self.scaleX == 1 then
self.x = self.x + 8
elseif self.scaleX == -1 then
self.x = self.x - 8
end
self.physics.body:destroy()
end
end
end
function Knife:removeAll()
ActiveKnifes = {}
end
return {
Knife = Knife,
ActiveKnifes = ActiveKnifes
}