How to detect collisions for something that has multiple instances?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
COMRADECHOnKy
Prole
Posts: 2
Joined: Wed Jul 03, 2024 3:20 pm

How to detect collisions for something that has multiple instances?

Post by COMRADECHOnKy »

Hello. I have been making a simple shooter game where the player has a gun and there are enemies. But I have run into a problem, I have made the collision system for the player and enemy just fine and the enemy damages the player and it dies when it collides with the player and

I want to do the same thing for the bullets and the enemy where the enemy will die after the bullet collides with it but it has multiple instances and I cant find a solution to it.

Bullet code:

Code: Select all

require("enemy")

image = love.graphics.newImage("bullet.png")

function bullet()
    return{ 
        x = 0,
        y = 0,
        width = 5,
        height = 5,
        speed = 150,
        direction = 0,
        delete = false,

        load = function (self,gun_x,gun_y,gun_direction)
            self.x = gun_x
            self.y = gun_y
            self.direction = gun_direction
        end,

        update = function (self,enem,dt)
            self.x = self.x + math.cos(self.direction) * self.speed * dt
            self.y = self.y + math.sin(self.direction) * self.speed * dt

            if self.x > love.graphics.getWidth() then
                self.delete = true
            end
            if self.y > love.graphics.getHeight() then
                self.delete = true
            end

            half_enemy_width,half_enemy_height = enem.width / 2
            ,enem.height / 2

            enemy_center_x = half_enemy_width + enem.x
            enemy_center_y = half_enemy_height + enem.y

            self_half_width = self.width / 2
            self_half_height = self.height / 2

            if math.abs(self_half_width + self.x - enemy_center_x) < math.abs(self_half_width + half_enemy_width) and
            math.abs(self_half_width + self.y - enemy_center_y) < math.abs(self_half_height + half_enemy_height) then
                self.delete = true
            end
        end,

        draw = function (self)
            love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
        end
    }
end
gun code:

Code: Select all

require("player")
require("bullet")
require("enemy")

gun = {
    x = 100,
    y = 50,
    angle,
    image = love.graphics.newImage("simple_m4.png")
}

bullet_list = {}
bullet_delete_list = {}

function gun:load()
end

function gun:update(dt)

    local mouse_x,mouse_y = love.mouse.getPosition()
    gun.angle = math.atan2(mouse_y - gun.y,mouse_x - gun.x)
    --bullet.direction = gun.angle    

    gun.x = player.x + (player.image:getHeight() / 2)
    gun.y = player.y + (player.image:getHeight() / 2)


    if love.mouse.isDown(1) then
        local new_bullet = bullet()
        new_bullet:load(gun.x,gun.y,gun.angle)
        table.insert(bullet_list,new_bullet)
    end

    for _, b in ipairs(bullet_list) do
        b:update(enem,dt)
    end
    for i = #bullet_list,1,-1 do
        if bullet_list[1].delete == true then
            table.remove(bullet_list,i)
        end
    end
end

function gun:draw()
    love.graphics.push()

    love.graphics.translate(gun.x,gun.y)
    love.graphics.rotate(gun.angle)

    love.graphics.draw(gun.image,-gun.image:getWidth() / 2,-gun.image:getHeight() / 2)

    love.graphics.pop()

    for i, b in ipairs(bullet_list) do
        b:draw()
    end
end

Code: Select all

enem = {}

function enemy()
    return {
        x = 0,
        y = 0,
        spd = 1000,
        width = 20,
        height = 20,
        spawned = true,
        hp = 4000,
        dead = false,

        update = function (self,player_x,player_y)
            enem.x = self.x
            enem.y = self.y
            enem.width = self.width
            enem.height = self.height

            local direction_X,direction_Y = player_x - self.x,player_y - self.y

            self.x = self.x + (direction_X / self.spd)
            self.y = self.y + (direction_Y / self.spd)

        end,

        checkCollision = function (self,player)
            half_player_width,half_player_height = player.image:getWidth() / 2
            ,player.image:getHeight() / 2

            player_center_x = half_player_width + player.x
            player_center_y = half_player_height + player.y

            self_half_width = self.width / 2
            self_half_height = self.height / 2

            if math.abs(self_half_width + self.x - player_center_x) < math.abs(self_half_width + half_player_width) and
            math.abs(self_half_width + self.y - player_center_y) < math.abs(self_half_height + half_player_height) then
                self.dead = true
                player.hp = player.hp - 1
            end
        end,

        drawEnemy = function (self)
            love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
        end
    }
end
User avatar
dusoft
Party member
Posts: 611
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: How to detect collisions for something that has multiple instances?

Post by dusoft »

You need to compare each bullet instance with another object (enemy/player). Make a table of bullets fired and their positions, compare with a player. You might hit a block here with bullets being faster than your detection, but search the forum it has been discussed.
COMRADECHOnKy
Prole
Posts: 2
Joined: Wed Jul 03, 2024 3:20 pm

Re: How to detect collisions for something that has multiple instances?

Post by COMRADECHOnKy »

dusoft wrote: Thu Jul 04, 2024 12:03 pm You need to compare each bullet instance with another object (enemy/player). Make a table of bullets fired and their positions, compare with a player. You might hit a block here with bullets being faster than your detection, but search the forum it has been discussed.
wow man, thank you so much. That's is pretty smart way to do that. I now have an idea of what to do.
RNavega
Party member
Posts: 341
Joined: Sun Aug 16, 2020 1:28 pm

Re: How to detect collisions for something that has multiple instances?

Post by RNavega »

COMRADECHOnKy wrote: Thu Jul 04, 2024 6:12 am

Code: Select all

function bullet()
    return{ 
        ...

        load = function (self,gun_x,gun_y,gun_direction)
            self.x = gun_x
            self.y = gun_y
            self.direction = gun_direction
        end
        
        ...
        }
end
Hi. While you're probably never going to run into problems with this, if I'm not mistaken, each time the bullet() function is called, the load etc functions will be instantiated, generating more garbage in memory, using up more memory that has to be cleared later by the garbage collector.
The solution to this is to declare the load etc functions before the bullet() function and as local functions (eg "local function _load(...)"), and then just assign references inside the bullet() function: {x = ..., y = ..., load = _load}.
This way the bullet tables only hold references to the same functions, not references to new instances of the functions per bullet.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 3 guests