I have checked a bit around and all I found was about stating that enemy is dead and stoping all his actions...
But how to truly remove him from list of active enemies?
There is table.remove, but I don't know how to set it up so it would aim at enemies, who fulfilled death conditions like having zero health points or fell off the map.
Death of enemy, obj. removing and other stuff (game added)
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Death of enemy, obj. removing and other stuff (game added)
Last edited by Kreg on Tue Jan 13, 2015 7:34 pm, edited 4 times in total.
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Death of enemy and object removing
The best way is to have a table that's reset to {} at the beginning of the update loop and when an entity is set to dead, add its ID to this table and at the end of the update loop run through the table and remove all entities referenced.
The way it's done is dependent on how your project is set up. We can't help much more without seeing your code.
The way it's done is dependent on how your project is set up. We can't help much more without seeing your code.
Re: Death of enemy and object removing
It's nothing big, I'm quite new.
- Attachments
-
- Game2.zip
- (1.68 KiB) Downloaded 145 times
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Death of enemy and object removing
I notice you use separate tables for the player and enemies. If I did it I'd put them in one table just to make it easier to handle, but you can do it that way if you want. In that case you would need to do the following:
When you "kill" an enemy, set its "dead" flag to true. (Which you already do) Then at the end of the "enemyMove" function, run through the table once more checking for dead enemies and if true, remove it from the table. Pretty simple actually.
One suggestion though is to use pairs instead of ipairs when doing the removing since if you use ipairs, it will fail very quickly if an entity with a numbered index that isn't at the end is deleted and the table is restructured when you use table.remove. (If you try removing an enemy in that ipairs loop now, you will have problems when you try to remove an enemy from the middle of the table since all enemies will shift down and the loop will become unsynced.)
Personally I never really use numbered IDs for my entities, rather named IDs of say "enemy_2054943" where that number is randomly chosen, or pulled from an ever increasing counter that I increment myself. Then when I delete an entity, I set its table to nil instead of using table.remove. Since setting it to nil won't perform the restructuring that table.remove does. (The only problem here is you can't use #table anymore to get the count of enemies. Rather you'll have to count them manually at update time with a global counter value that is set to 0 and incremented in the for loop that runs through the enemies. Then print that value instead. But that's no big deal when debugging. Since you're already running through the table anyway there's no problem simply counting them as you go.)
I'd also suggest stress testing it. Once you implement a proper remover, try creating a whole bunch of enemies at the same time each with different speeds so they disappear at a less predictable time so you can make sure they're being removed properly.
When you "kill" an enemy, set its "dead" flag to true. (Which you already do) Then at the end of the "enemyMove" function, run through the table once more checking for dead enemies and if true, remove it from the table. Pretty simple actually.
One suggestion though is to use pairs instead of ipairs when doing the removing since if you use ipairs, it will fail very quickly if an entity with a numbered index that isn't at the end is deleted and the table is restructured when you use table.remove. (If you try removing an enemy in that ipairs loop now, you will have problems when you try to remove an enemy from the middle of the table since all enemies will shift down and the loop will become unsynced.)
Personally I never really use numbered IDs for my entities, rather named IDs of say "enemy_2054943" where that number is randomly chosen, or pulled from an ever increasing counter that I increment myself. Then when I delete an entity, I set its table to nil instead of using table.remove. Since setting it to nil won't perform the restructuring that table.remove does. (The only problem here is you can't use #table anymore to get the count of enemies. Rather you'll have to count them manually at update time with a global counter value that is set to 0 and incremented in the for loop that runs through the enemies. Then print that value instead. But that's no big deal when debugging. Since you're already running through the table anyway there's no problem simply counting them as you go.)
I'd also suggest stress testing it. Once you implement a proper remover, try creating a whole bunch of enemies at the same time each with different speeds so they disappear at a less predictable time so you can make sure they're being removed properly.
Re: Death of enemy and object removing
Thing is that I don't know how to do this.Jasoco wrote: Then at the end of the "enemyMove" function, run through the table once more checking for dead enemies and if true, remove it from the table. Pretty simple actually.
I did something like this:
Code: Select all
function EnemyMove(dt)
for i,v in pairs(enemyList) do
if v.dead ~= true then
v.x=v.x-200*dt
if v.dead == true then
table.remove(enemyList,Enemy)
end
end
end
end
Ealier when I was trying to do this it was removing all objects.
Last edited by Kreg on Sat Nov 29, 2014 12:25 pm, edited 1 time in total.
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Death of enemy and object removing
Because in that example you're not removing a specific index. I mean what is "Enemy"? If anything you would be removing "i". But you really should run over the table a second time using just pairs, removing any index whose entity is "dead".
The "i" is the index of the current table entry. The "e" (Formerly "v" in your old code, though it can be anything) represents the current entity, or table row, itself. And "pairs" means it will iterate over every entity in the table whereas "ipairs" will stop as soon as it hits a missing number. I prefer to use pairs and set table entries to nil instead of numbering each table row incrementally and using table.remove as those methods could break or slow down badly when dealing with constantly removed table entries.
The above code would be at the end of your enemyMove function.
Test it out by giving each enemy a random speed and bump up the spawn rate and make sure it works.
Also, please use the Code tags on the forum when posting code. It makes your post readable.
Code: Select all
for i,e in pairs(enemyList) do
if e.dead then
table.remove(enemyList, i)
-- Alternatively I'd use enemyList[i] = nil
end
end
The above code would be at the end of your enemyMove function.
Test it out by giving each enemy a random speed and bump up the spawn rate and make sure it works.
Also, please use the Code tags on the forum when posting code. It makes your post readable.
Re: Death of enemy and object removing
Thanks very much! It works now.
If I understand right:
"i" means whole Enemy's table, which is put in table of enemyList, but also is linked with "EnemyClass" metatable.
"e." is just a link to enemy's variable.
"EnemyClass" metatable sets orginal stuff for all objects created from this (basic things like checking if object is dead)
But I have another question:
Let's assume there are two bullet types, where one gives more damage. How to check which bullet hit the enemy?
I guess this needs to check bullet's table values,then show it to enemy's table. How to link it?
I kinda understand collision detection because I made simple pong before.
I guess I could create "Bullets" table, then make creating functions, one for each bullet type.
Next I should do simple collision detection, checking "Bullets" and "EnemyList" tables for collision at same time, probably by using pairs in the same line, if it is possible.
In case of collision decrease e(nemy's).HP by b(ullet's).damage.
If I understand right:
"i" means whole Enemy's table, which is put in table of enemyList, but also is linked with "EnemyClass" metatable.
"e." is just a link to enemy's variable.
"EnemyClass" metatable sets orginal stuff for all objects created from this (basic things like checking if object is dead)
But I have another question:
Let's assume there are two bullet types, where one gives more damage. How to check which bullet hit the enemy?
I guess this needs to check bullet's table values,then show it to enemy's table. How to link it?
I kinda understand collision detection because I made simple pong before.
I guess I could create "Bullets" table, then make creating functions, one for each bullet type.
Next I should do simple collision detection, checking "Bullets" and "EnemyList" tables for collision at same time, probably by using pairs in the same line, if it is possible.
In case of collision decrease e(nemy's).HP by b(ullet's).damage.
- Luke100000
- Party member
- Posts: 232
- Joined: Mon Jul 22, 2013 9:17 am
- Location: Austria
- Contact:
Re: Death of enemy and object removing
when I understand your question:
or
e.live is the amount of HT of the enemys
b.typ is the type of the bullet
b.damage is the damage of a bullet
Code: Select all
function love.update(dt)
for i, e in pairs(enemys) do
for i2, b in pairs(bullets) do
if collided() then --your colliding function
if b.typ == 1 then
e.live = e.live - 5
if b.typ == 2 then
e.live = e.live - 20
end
end
end
end
end
Code: Select all
function love.update(dt)
for i, e in pairs(enemys) do
for i2, b in pairs(bullets) do
if collided() then --your colliding function
e.live = e.live - b.damage
end
end
end
end
b.typ is the type of the bullet
b.damage is the damage of a bullet
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Death of enemy and object removing
Yes, in the following line of code:Kreg wrote:Thanks very much! It works now.
If I understand right:
"i" means whole Enemy's table, which is put in table of enemyList, but also is linked with "EnemyClass" metatable.
"e." is just a link to enemy's variable.
"EnemyClass" metatable sets orginal stuff for all objects created from this (basic things like checking if object is dead)
Code: Select all
for i,e in pairs(enemyList) do
"e" is a shortcut to the current table index and basically stands for enemyList. In other words, e = enemyList.
Re: Death of enemy and object removing
Thanks for help, Luke. I will try it when I will need this.
EDIT:
Nevermind, I have other question: how to set collision check between entities in the same table?
EDIT:
Nevermind, I have other question: how to set collision check between entities in the same table?
Who is online
Users browsing this forum: Ahrefs [Bot] and 6 guests