Collision Bug

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
ausboss20001
Prole
Posts: 4
Joined: Sat Nov 18, 2023 5:16 pm

Collision Bug

Post by ausboss20001 »

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
}
User avatar
ausboss20001
Prole
Posts: 4
Joined: Sat Nov 18, 2023 5:16 pm

Re: Collision Bug

Post by ausboss20001 »

nevermind i fixed it
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Collision Bug

Post by milon »

Great! Also please consider using [ code ] tags in the future so we can help you easier. ;)
ausboss20001 wrote: Thu Nov 23, 2023 6:27 pm Here is my code (knife.lua):

Code: Select all

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
}
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
ausboss20001
Prole
Posts: 4
Joined: Sat Nov 18, 2023 5:16 pm

Re: Collision Bug

Post by ausboss20001 »

ok i will make sure to do that next time
Post Reply

Who is online

Users browsing this forum: gianmichele, Google [Bot] and 71 guests