I want to know the process of erasing bullets in a shooting game

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Okaka-S
Prole
Posts: 2
Joined: Thu Nov 12, 2020 9:15 am

I want to know the process of erasing bullets in a shooting game

Post by Okaka-S »

Hello everyone.
I have something to ask you, so I will post it in the forum for the first time.

I'm developing a shooting game sample.
I heard on the LOVE2D learning site that "the bullets should be put in a table and implemented", and the player succeeded in firing the bullets in the same way.

What I want to implement now is "the bullets will disappear from the screen after a certain amount of time".
A timer variable (mainshot_remove_timer) is prepared, and when the upper limit value (mainshot_remove_time) is reached, the bullet is erased.
When removing a bullet from the table, it is processed to erase [1] of the table so that it will be erased from the bullet fired first. The process has been successful, but I find this a bad idea.
Is the table-less approach more effective? I also thought, but I don't know what kind of approach is suitable.

How do you deal with such a problem (the process of multiple same objects appearing on the screen and erasing only a specific object)?
(If there is a good method, I would like to apply that method to erase the enemies whose life has become 0 from among the enemies that appear a lot)

I will attach a file that extracts only the game scene. The process of removing bullets is in "bullet_amattMain.lua". Fire a bullet with the "z" key.
I would be grateful if you could give me some advice!
game.love
(9.25 MiB) Downloaded 265 times
MrFariator
Party member
Posts: 509
Joined: Wed Oct 05, 2016 11:53 am

Re: I want to know the process of erasing bullets in a shooting game

Post by MrFariator »

If you want to (easily) spawn multiple objects, update them, and delete them when appropriate, you're inevitably going to have to use some way to manage a collection of them. In other words, you pretty much need a table. You could have a few different categories (ie. a table for enemies, a table for bullets, etc), but how you do that split (or don't) is up to you.

Generally, you might update objects and delete them from the container table within the same loop, or you might update first in one loop, and then do a cleaning sweep later in another. There's pros and cons to both approaches, so you may take your pick, really.
When removing a bullet from the table, it is processed to erase [1] of the table so that it will be erased from the bullet fired first.
This assumption may cause wrong bullet to be deleted when one makes contact with an enemy. In a game with multiple bullets on screen at once, there is no guarantee that the bullet that was fired first will hit an enemy before a bullet that was fired later.
User avatar
Okaka-S
Prole
Posts: 2
Joined: Thu Nov 12, 2020 9:15 am

Re: I want to know the process of erasing bullets in a shooting game

Post by Okaka-S »

> MrFariator

thank you for your reply!
I tested it based on your advice.
as a result,
1. Create a loop that sets "remove flag" to true after a certain period of time (bullet.lua),
2. Create a loop to remove from table when "remove flag" is true (main.lua)
The expected processing was successful.
I was saved!
User avatar
Nikki
Citizen
Posts: 83
Joined: Wed Jan 25, 2017 5:42 pm

Re: I want to know the process of erasing bullets in a shooting game

Post by Nikki »

Instead of all the instancing, adding and deleting from a list you could also look at a Pool

Bullets are the perfect case for them I think.


edit:

here is a little example of a very simple pool implementation in action in love2d:
50k bullets onscreen runs smoothly at 60fps on my low end machine over here

Code: Select all

 
 local rnd = love.math.random

function love.keypressed(key)
   if key == 'escape' then
      love.event.quit()
   end
end

function love.load()
   love.window.setMode( 800, 600, {resizable=true, vsync=true} )
   local w,h = love.graphics.getDimensions()
   
   bullets = {}
   for i = 1, 50000 do
      bullets[i] = {
         on = true,
         x = rnd(w), y = rnd(h),
         speed = rnd(10) + 5,
         size = rnd(3) + 1,
         direction = rnd() * (math.pi*2)
      }
   end
   
end

function love.draw()
   for i = 1, #bullets do
      local b = bullets[i]
      if b.on then
         love.graphics.rectangle('fill', b.x, b.y, b.size, b.size)
      end
   end
   love.graphics.print(love.timer.getFPS())
end

function love.update()
   local w,h = love.graphics.getDimensions()
   for i = 1, #bullets do
      local b = bullets[i]
      if b.on==true then
         bullets[i].x = b.x + b.speed * math.cos(b.direction)
         bullets[i].y = b.y + b.speed * math.sin(b.direction) 
         if b.x < 0 or b.x > w or b.y < 0 or b.y > h then
            bullets[i].on = false
         end
      end

      if b.on == false then
         bullets[i].x = w/2
         bullets[i].y = h/2
         bullets[i].speed = rnd() * 10 + 5
         bullets[i].on = true
      end
   end
end

 
 
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: I want to know the process of erasing bullets in a shooting game

Post by Jasoco »

Okaka-S wrote: Thu Nov 12, 2020 9:17 pm > MrFariator

thank you for your reply!
I tested it based on your advice.
as a result,
1. Create a loop that sets "remove flag" to true after a certain period of time (bullet.lua),
2. Create a loop to remove from table when "remove flag" is true (main.lua)
The expected processing was successful.
I was saved!
This is basically how I do it.

Entities go into a single table. Each one gets its own unique "nameID". For instance, entityList["player"] or entityList["enemy_19393"]. And each entity knows its own nameID as well.
Before running through entities for update and draw below, create (Or replace on subsequent loops) a table for placing removed entity IDs.
The table is looped through during update and draw.
If an entity is "removed" from play, either killed, leaves the scene or is a bullet that hit something, whatever the case, it's flagged as self.removeThis = true.
Immediately after calling the update() function for each entity, I check to see if the removeThis flag was set. If so, add its nameID to the separate "entities to remove" table. Basically entitiesToRemove[the_current_entitys_nameID] = true.
Then at the end of the whole update process, run through the entitiesToRemove table and set all entities with a matching nameID to nil.

I also do a special case where I exclude the player from the main entity update loop and make sure to update it first separately before the loop. This ensures that everything is in sync with the player. In my current project I also place all moving platforms (Which other entities need to interact with) into a separate entity pool that gets updated before the player and the other entities just to make sure everything is in sync.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 54 guests