Error when killing enemies

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
User avatar
Autophoenix
Prole
Posts: 40
Joined: Thu Mar 06, 2014 4:18 pm
Location: Rio de Janeiro, Brazil

Error when killing enemies

Post by Autophoenix »

In my game the player can throw wrenches at the enemies.

But I got a problem: When I have multiple wrenches at the screen, most of the time the wrench don't kill the enemy. And I usually got an error in this. :(

In scripts/player.lua I got these variables:

Code: Select all

wr = {}
   wr.positionsX = {}
   wr.positionsY = {}
   wr.rotations = {}
They are the wrench X, Y and its rotation.

In scripts/enemies/spycrab.lua I got:

Code: Select all

sc = {}
   sc.X = {}
   sc.Y = {}
   sc.Rot = {}
It's the same thing as the wrench positions.
In spycrab_update(dt) is the code that checks if an wrench collides with the player:

Code: Select all

if #sc.X ~= 0 and #wr.positionsX ~= 0 then
      for n = 1, #sc.X do
         if n > #wr.positionsX then break else
            if wr.positionsX[n]+wrench:getWidth() > sc.X[n] and wr.positionsX[n] < sc.X[n]+spycrab:getWidth() and wr.positionsY[n]+(wrench:getHeight()/2) > sc.Y[n] and wr.positionsY[n]+(wrench:getHeight()/2) < sc.Y[n]+spycrab:getHeight() then
               table.remove(wr.positionsX, n)
               table.remove(wr.positionsY, n)
               table.remove(wr.rotations, n)
               nadd = nadd - 1

               table.remove(sc.X, n)
               table.remove(sc.Y, n)
               table.remove(sc.Rot, n)

               scAdd = scAdd - 1

               return #sc.X, #wr.positionsX
            end
         end
      end
   end
I've already tryied put 'break' instead of 'return #sc.X, #wr.positionsX', but when I have multiple wrenches at the screen, the program breaks the loop.

Can someone throw me a light? :cry:
Attachments
svl.love
(6.79 MiB) Downloaded 90 times
a² = b² + c²
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Error with killing enemies

Post by davisdude »

You've already done this topic.
As a common rule, you should AT LEAST wait until it gets off the first page before bumping a thread.

About your code (not collisions, but still relevant):

player.lua

On line 2 you assign 192 to vagineerY, but 5 is just lost.

Lines 4-56 could be condensed to this:

Code: Select all

playerAnimation = {}
for Index = 1, 56 do
    playerAnimation[a] = love.graphics.newImages( 'img/player/animation/' .. a .. '.png' )
end
Lines 90:
if i == 53 then is generally frowned upon, for 2 reasons:
- It is hard-coded, which makes it more work for yourself if you need to change anything.
- If the frame-rate spikes, and i becomes > than 53 without ever being checked, you have yourself a problem.
Granted, these things probably won't happen, but it's still good to practice good coding.
If I were you, I would switch it to something like if i >= #playerAnimation then

And generally speaking, all of the hard-coded variables in general is bad practice.

Anyway, back on topic:
Your problem lies in lines 154 and 159-162.
You are traversing a for-loop forwards, and removing values. This is bad, because some "wrenches" will never be updated.
Take the example:

Code: Select all

local LOVERS = { 
    davisdude = {
        Posts = love.math.random( 1000 ), 
        Online = true, 
    }, 
    Autophenix = {
        Posts = love.math.random( 1000 )
        Online = true, 
    },
}

function LOVERS.CheckOnline( Table )
    for a = 1, #Table do
        local Table[a] = LOVER
        if not LOVER.Online then 
            table.remove( Table, a )
        end
    end
end
Now, say that I went offline. Suddenly, that table switches from having a length of 2 to having a length of 1. Having already gone over once (when it checked me), it would stop, since the length is only 1.
The way to combat this problem is with a backwards iterating table! This name may sound frightening, but it is really quite simple.
In case you don't now, a for-loop has 3 "arguments" if you will, the Index (and value), the number at which it terminates, and the iterator (how much it increases by each time). So, you can simply do this

Code: Select all

for Index = #Table, 1, -1 do
    -- Update things, whatever.
end
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Autophoenix
Prole
Posts: 40
Joined: Thu Mar 06, 2014 4:18 pm
Location: Rio de Janeiro, Brazil

Re: Error when killing enemies

Post by Autophoenix »

I'm really sorry and I feel awful for what I've done with the rules.
How can I delete that post?

And thanks for helping me.
I'm new to programming (I started at November/2013) and I don't have so many pratice.

It's hard for me finding good Lua and Love tutorials in portuguese. Well, I understand well americans speaking in the videos, but I cannot catch everything..
PS: If you don't know, brazillians don't speak spanish, and portuguese is not the same thing as spanish :ultrahappy:

I really need to pratice more, thanks for the tip about the animation!
a² = b² + c²
User avatar
moikmellah
Prole
Posts: 12
Joined: Fri Jan 31, 2014 8:31 pm
Location: USA
Contact:

Re: Error when killing enemies

Post by moikmellah »

One other problem worth mentioning:

Code: Select all

if #sc.X ~= 0 and #wr.positionsX ~= 0 then
  for n = 1, #sc.X do
    if n > #wr.positionsX then break else
      if wr.positionsX[n]+wrench:getWidth() > sc.X[n] and wr.positionsX[n] < sc.X[n]+spycrab:getWidth() and wr.positionsY[n]+(wrench:getHeight()/2) > sc.Y[n] and wr.positionsY[n]+(wrench:getHeight()/2) < sc.Y[n]+spycrab:getHeight() then
        table.remove(wr.positionsX, n)
        table.remove(wr.positionsY, n)
        table.remove(wr.rotations, n)
        nadd = nadd - 1

        table.remove(sc.X, n)
        table.remove(sc.Y, n)
        table.remove(sc.Rot, n)

        scAdd = scAdd - 1

        return #sc.X, #wr.positionsX
      end
    end
  end
end
In the above, you have a single for loop which iterates the counter n over each possible key in sc.X, but then use n as the index for both sc.X and wr.positionsX. That means that for each entry in sc, you're checking only against the matching entry in wr, rather than ALL entries in wr (so sc[1] is only checked against wr[1], sc[2] is only checked against wr[2], and so on). To check each entry in sc against every entry in wr, you'd want to use nested loops:

Code: Select all

if #sc.X ~= 0 and #wr.positionsX ~= 0 then
  for n = 1, #sc.X do
    --if n > #wr.positionsX then break else
    for m = 1,#wr.positionsX do
      if wr.positionsX[m]+wrench:getWidth() > sc.X[n] and wr.positionsX[m] < sc.X[n]+spycrab:getWidth() and wr.positionsY[m]+(wrench:getHeight()/2) > sc.Y[n] and wr.positionsY[m]+(wrench:getHeight()/2) < sc.Y[n]+spycrab:getHeight() then
        table.remove(wr.positionsX, m)
        table.remove(wr.positionsY, m)
        table.remove(wr.rotations, m)
        nadd = nadd - 1

        table.remove(sc.X, n)
        table.remove(sc.Y, n)
        table.remove(sc.Rot, n)

        scAdd = scAdd - 1

        return #sc.X, #wr.positionsX
      end
    end
  end
end
User avatar
Autophoenix
Prole
Posts: 40
Joined: Thu Mar 06, 2014 4:18 pm
Location: Rio de Janeiro, Brazil

Re: Error when killing enemies

Post by Autophoenix »

Thanks for you both! The code is working. And i'll clean my code.
a² = b² + c²
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Error when killing enemies

Post by davisdude »

Autopheonix wrote:I'm really sorry and I feel awful for what I've done with the rules.
How can I delete that post?
It's fine. You don't need to delete any posts. Jut though I would let you know. :)
Autopheonix wrote:And thanks for helping me.
You're welcome!
Autopheonix wrote:I'm new to programming (I started at November/2013) and I don't have so many pratice.
That's okay. We all were new at some point (even Robin, Rude, etc., as hard as that to believe ;) ).
Autophoenix wrote:It's hard for me finding good Lua and Love tutorials in portuguese. Well, I understand well americans speaking in the videos, but I cannot catch everything..
PS: If you don't know, brazillians don't speak spanish, and portuguese is not the same thing as spanish :ultrahappy:
Well, I can understand the challenge understanding people. That stinks (thankfully there seems to be a large number of Portuguese speaking people here on the forums, so I'm sure they wouldn't mind if you asked for some help occasionally).
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests