Bump - How to remove item fully from world?

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
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Bump - How to remove item fully from world?

Post by hasen »

I run

Code: Select all

self.world:remove(self)
on an enemy entity when it is destroyed but yet I get the error:

"Error: lib/bump.lua:529: Item Enemy 418.129216 520.000000 [24.000000 48.000000] must be added to the world before getting its rect. Use world:add(item, x,y,w,h) to add it first."

It's move function continues to be called even after it's removed...not sure how to kill it completely? The entity is gone and can't be seen but somehow all it's functions, or at least the move one is still being run for the object after it's death.

Do I need to turn off the

Code: Select all

Enemy:update
function or something? I've not come across that and am not sure how to do that if that is the case.
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Bump - How to remove item fully from world?

Post by MrFariator »

Without seeing your code, I think you're attempting to destroy the enemy object while the Enemy:update method is still being resolved for that frame. This then leads to it trying to query bump, even though the object doesn't exist there anymore. Simplest solution would be to put something akin to

Code: Select all

if self.destroyed then return end
in relevant spots in your code. I myself delay deletion until the end of the frame, where my game object manager calls each deleted object's clean up method.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Re: Bump - How to remove item fully from world?

Post by hasen »

Ok I'll try that. Sounds like a good way to figure out where it's happening.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Re: Bump - How to remove item fully from world?

Post by hasen »

Really can't figure out why this is happening. I have a bullet that destroys itself when hitting a wall with no problem but upon hitting the ground it throws the bump error as above. The object for the wall and ground are both 'Block' though so I can't see the difference.

Code: Select all

function Bullet:filter(other)
  local kind = other.class.name
  if kind == 'Block'
  or kind == 'Enemy'
  or (kind == 'Player' and not self.ignoresParent)
  then
    return "cross"
  end
end

Code: Select all

function Bullet:moveColliding(dt)
  local world = self.world
  local parent = self.parent
  self.vx = self.speed * self.facing
  local future_l = self.l + self.vx * dt
  local future_t = self.t + 2

  local next_l, next_t, cols, len = world:move(self, future_l, future_t, self.filter)

  for i=1, len do
    local col = cols[i]
    local other = col.other
    local kind = other.class.name
    if kind == 'Enemy' then
      self:damageItem(other)
      return
    elseif kind == 'Block' then
      Entity.destroy(self)
    elseif kind == 'Player' then
      return "cross"
    end

    if other ~= parent or not self.ignoresParent then
      local nx, ny = col.normal.x, col.normal.y
      self:changeVelocityByCollisionNormal(nx,ny)
    end
  end

  self.l, self.t = next_l, next_t
end
If I jump and fire then the bullet fires downwards and hits the wall there is no problem, but if it hits the ground then the bump error is thrown. I really can't tell what the difference is since the objects are all the same.

EDIT: Ok I've isolated that the error only happens when the bullet hits the point where the blocks meet.....anyone any ideas why this would happen?
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Bump - How to remove item fully from world?

Post by MrFariator »

Inside your for-loop, when you call Entity.destroy, you are not breaking out of the loop. As such, if the len is greater than 1, the Entity.destroy is called multiple times (if bullet hit a block seam, anyway), and I assume that's where you try to remove the bullet from the bump world, leading to your error.

You could simply change it to something like:

Code: Select all

local destroyed = false

for i=1, len do
  local col = cols[i]
  local other = col.other
  local kind = other.class.name
  if kind == 'Enemy' then
    self:damageItem(other)
    return
  elseif kind == 'Block' then
    destroyed = true
  elseif kind == 'Player' then
    return "cross" 
  end

  if other ~= parent or not self.ignoresParent then
    local nx, ny = col.normal.x, col.normal.y
    self:changeVelocityByCollisionNormal(nx,ny)
  end
end

if destroyed then
  Entity.destroy(self)
  return
end
Because you probably want to check all collisions before deleting the bullet (the bullet might hit an enemy and a floor block on the same frame), it's better to put the call to Entity.destroy after the loop has finished.

On a side note, I'm not sure why you have that kind == 'Player' comparison there. This would lead to a situation where if player and enemy are overlapping, the bullet might just not hit its target, leaving it entirely up to the order in which bump returns the collisions.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Re: Bump - How to remove item fully from world?

Post by hasen »

Great, thanks a lot. :) So you think I should remove the whole player check completely? I want the bullet to always pass through the player and not get stuck on him is all.
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Bump - How to remove item fully from world?

Post by MrFariator »

Yeah, it's an unnecessary check within that for-loop. Keep in mind that with bump's filters it will only return a collision if it's defined to do so, like from my own game's code:

Code: Select all

local filter = function ( item, other ) 
  if other.properties then
    if other.properties.isSlopeEnder or other.properties.isTile then return "touch"
    elseif other.properties.isSlope then return "cross" end
  end
end
Because the filter doesn't return anything when other.properties.isPlayer equals to true (returns nil), that collision is simply ignored and so I don't have to account for it when looping through collisions.

Another point probably worth noting is this bit in your for-loop

Code: Select all

self:damageItem(other)
return
You might want to change that 'return' to 'break' (so that "self.l, self.t = next_l, next_t" is executed), or just remove it altogether if you want two overlapping enemies to take damage from the same bullet. Of course, that is only if self:damageItem doesn't make a call to Entity.destroy.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Re: Bump - How to remove item fully from world?

Post by hasen »

Ok I see. This is my first attempt at making a game and there's so much to consider. It seems to me that at least with a platform shooter, collisions are basically the entire game...all the rest is just decoration.
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Bump - How to remove item fully from world?

Post by MrFariator »

Yeah, a lot of these considerations have to do with what kind of game you want to make. Something like classic Mega Man doesn't do any "hit both enemies if they're overlapping" checks, but something with piercing ammo (eq. monster hunter's bowguns) will probably do it. It also plays a lot into the fairness of the game, like how Anima on WiIWare is infamous for only allowing you to hit a single enemy at a time (on normal and hard difficulty, anyway, the cap is raised to 2 on easy) in a game where enemies can and WILL stand on top of one another, and hit the player out of their sword combo.
Post Reply

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 83 guests