Page 3 of 3
Re: Tables or Inheritance
Posted: Sun Nov 25, 2012 7:18 am
by Knaimhe
Knaimhe wrote:Hey! I figured it out!
I was wrong.
Very, very, wrong.
That system apparently finds any random shot and destroys it. Not the shot that actually hit.
Big problem when there are multiple shots on screen.
So I changed to this:
It gets a bit rough. I've heavily ramped up the heatMax and firerate of the main weapon, for testing purposes. Shoot about two or three overheats worth and you should get an error message.
I believe you can directly access the code just by renaming the .love to a .zip. It's in a N++ file.
Re: Tables or Inheritance
Posted: Sun Nov 25, 2012 6:36 pm
by ivan
Hi again. I looked at the code but it was quite a bit of a challenge because everything is packed in a single 1000-line file. Things are made considerably more complicated by the fact that you have a large number of globals that are accessed from everywhere. You may want to consider breaking your code in separate files (one for drawing, another for physics, etc) and cut down on the globals.
Ok, anyways, there are several things that could be wrong:
1. You are destroying shapes/bodies during a collision callback
Note: Using Shape:destroy when there is an active remove callback can lead to a crash. It is possible to work around this issue by only destroying object that are not in active contact with anything.
2. Destroying a body automatically destroys all relevant shapes, fixtures and joints. You are destroying a body then destroying one of its fixtures. Not sure how this is handled by Love2D but I would recommend destroying the fixture first.
Code: Select all
hitF:getBody():destroy()
hitF:destroy()
3. You don't need to search the table if you already know the index:
Code: Select all
shotT[searchTable(shotT, hitF)] = nil
Could become:
Re: Tables or Inheritance
Posted: Mon Nov 26, 2012 9:06 pm
by Knaimhe
*shrug*
I never learned to split code into separate files.
In terms of performance, does it make a big difference?
1. I'm actually destroying those bodies/fixtures in a function separate from the collision callback. And there is no remove callback.
Code: Select all
world:setCallbacks(beginContact, nil, nil, nil)
2. I checked with the changed order just to be safe, but I don't think it makes a difference.
3. That actually makes more sense, but for some reason doesn't really remove the target fixture from the table. It ends up creating an error in the draw().
Code: Select all
for k,v in pairs(shotT) do
love.graphics.polygon("fill", v:getBody():getWorldPoints(v:getShape():getPoints()))
end
Apparently it still leaves the fixture's reference in the table, but the fixture has been destroyed and therefore can provide no data to draw with.
Re: Tables or Inheritance
Posted: Mon Nov 26, 2012 9:26 pm
by Robin
Knaimhe wrote:*shrug*
I never learned to split code into separate files.
In terms of performance, does it make a big difference?
In terms of maintainability, it makes a big difference.
If the maintainability is poor, other people will have trouble helping you, because they will have trouble understanding what you already have.
If the maintainability is poor, future you will have trouble fixing bugs and adding features, because you will have trouble understanding what you already have.
Re: Tables or Inheritance
Posted: Tue Nov 27, 2012 6:48 am
by ivan
Knaimhe wrote:1. I'm actually destroying those bodies/fixtures in a function separate from the collision callback. And there is no remove callback.
There is a collision callback during the time you are destroying shapes, it doesn't matter if you put the code in an outside function. Earlier versions of Box2D did not allow destroying/creating shapes and bodies at all during any callback, you may want to look into this. Let's hope this limitation has been relegated to "remove" callbacks.
Like Robit said, sloppy code shows that you don't care about it. So yeah, that's a good starting point if you plan on finding those bugs.
Re: Tables or Inheritance
Posted: Tue Nov 27, 2012 8:06 am
by Knaimhe
Iirc, as far as Love 0.7 was concerned, all that mattered was whether or not the creation/destruction was in an outside function.
How complicated would splitting my code be? I've never done it before, so there's a bit of apprehension.
Would it be as simple as just creating another .lua file and cutting some of the functions into that?
I expect I'd also have to do some importing in the main.
Re: Tables or Inheritance
Posted: Tue Nov 27, 2012 8:36 am
by ivan
Just want to point out how callbacks are executed:
Code: Select all
function outside ( )
-- destroy shape
end
function callback ( )
-- callback begins
outside()
-- callback ends
end
It doesn't matter where the code is located, callbacks aren't "finished" until the callback function has returned.
Re: Tables or Inheritance
Posted: Wed Nov 28, 2012 5:56 am
by Knaimhe
No, I know how it works, it's just...
I had code that destroyed shapes within the collisions callback. It crashed.
I moved the code to an outside function and called that with the collisions callback. It did not crash.
(For Love 0.7.)
Re: Tables or Inheritance
Posted: Wed Nov 28, 2012 9:54 pm
by Knaimhe
Whoops! Sorry guys.
I figured out that this bug occurs when a shot strikes a corner, thereby creating two collisions.
I solved it by adding a return nil statement at the end of searchTable() and adding another check for nil within hitShot().
Re: Tables or Inheritance
Posted: Thu Nov 29, 2012 8:14 am
by Robin
Knaimhe wrote:I solved it by adding a return nil statement at the end of searchTable() and adding another check for nil within hitShot().
Fun fact! If you don't return anything, you automatically return nil, so you technically could have made only the second change and it would still have worked.