Page 1 of 1

weird behavior witth lot's of objects on screen

Posted: Tue Jun 07, 2011 8:17 pm
by sentry
I'm having a weird problem when having lot's of stuff on screen.
I am at the point where i want to add some wicked bullet patterns to my game but i start to see weird issues with object removal.

I added an example. It's really basic and not an actual bullet pattern but it illustrates the problem:
When the screen is full of bullet spam you'll start to see the objects being removed premature in the corners of the screen.

Can anyone explain to me why this happens?
It's totally not what i was expecting and i can't think of a way why it would behave like this.

Re: weird behavior witth lot's of objects on screen

Posted: Tue Jun 07, 2011 8:36 pm
by nevon
I think it has to do with how you remove your bullets. Once you remove a bullet from the bullets table, the indexes saved in rem_bullets aren't valid anymore. I'm slightly inebriated, but I think this is how you would do it.

Code: Select all

for i, v in ipairs(rem_bullets) do
	table.remove(bullets, v-(i-1))
end

Re: weird behavior witth lot's of objects on screen

Posted: Tue Jun 07, 2011 8:45 pm
by bartbes
Or, a commonly used trick is a reverse traversal:

Code: Select all

for i = #rem_bullets, 1, -1 do
    table.remove(bullets, rem_bullets[i])
end
(this only works if rem_bullets is sorted from low to high, this trick has several variants).

Another thing, which would basically be the same as the reverse traversal, is sorting the removal table highest-first.

Re: weird behavior witth lot's of objects on screen

Posted: Tue Jun 07, 2011 10:41 pm
by vrld
Yet another way would be to store the bullets in a set instead of an array. To get a set, simply use the object itself as index:

Code: Select all

function love.update(dt)
    local rem_bullets = {}
    if timer >= 0.01 then
        -- as before ...
        bullets[b] = b -- instead of table.insert(bullets, b)
    end

    for _, b in pairs(bullets) do -- notice the pairs instead of ipairs
        b.update(dt)
        if b.is_off_screen() then
            rem_bullets[#rem_bullets+1] = b
        end
    end

    for _, b in ipairs(rem_bullets) do bullets[b] = nil end -- instead of table.remove
end

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 10:05 am
by sentry
Thanks for all the help!

@nevon: Such a simple fix, adding only -(i-1) :awesome:

I have no idea why the order at which i remove the bullets is important. Can someone explain?

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 10:06 am
by bartbes
Because if you remove an entry with table.remove all others (after that) shift down, so their indices are now pointing to the wrong value.

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 10:26 am
by nevon
sentry wrote:Thanks for all the help!

@nevon: Such a simple fix, adding only -(i-1) :awesome:

I have no idea why the order at which i remove the bullets is important. Can someone explain?
To expand on what Bartbes said, you can visualize it kind of like this:

Code: Select all

ourFirstTable = {
    1 : 'Value 1',
    2 : 'Value 2',
    3 : 'Value 3',
    4 : 'Value 4',
    5 : 'Value 5'
}

removeTable = {
    1 : 3, --We want to remove 'Value 3' from ourFirstTable ('Value 3' has the index 3)
    2 : 4 -- We also want to remove 'Value 4'
}
When we first remove the first element in our removeTable, ourFirstTable will look like this:

Code: Select all

ourFirstTable = {
    1 : 'Value 1',
    2 : 'Value 2',
    3 : 'Value 4',
    4 : 'Value 5'
}
Now remember, in our removeTable, we also wanted to remove 'Value 4', which previously had the index 4. Now that ourFirstTable has lost an entry, 'Value 4' actually has the index 3. However, since we're not accounting for that, during the next iteration, we're removing whatever value has the index 4. Meaning ourFirstTable now looks like this.

Code: Select all

ourFirstTable = {
    1 : 'Value 1',
    2 : 'Value 2',
    3 : 'Value 4'
}
Because we didn't account for the shift in indexes, we accidentally removed 'Value 5' when we meant to remove 'Value 4'.

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 12:50 pm
by Robin
nevon wrote:<blah>
FYI, that's Python. Except for the comments.

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 2:57 pm
by nevon
Robin wrote:
nevon wrote:<blah>
FYI, that's Python. Except for the comments.
Or Javascript.

Re: weird behavior witth lot's of objects on screen

Posted: Wed Jun 08, 2011 10:18 pm
by Robin
Pah. Speak not of that language!