Howdy. Apologies for the length of this, my first, post. I’ve searched the forums for an answer, but all that’s led me to are multiple ways to tackle this problem, and I’m wondering which would be the most appropriate.
I’m currently building a game with several different, simple, characters. These characters are active within the physics system, and when they collide with certain other terrain objects, they trigger an animation and then attempt to remove themselves from the game. Since all these characters are the same size & shape, and only differ in their display graphic and the sound they play when they blow up, I created a simple class to produce them.
(I did this after reading about a handful of OOP approaches to Lua/Corona- I don’t need anything too complex, so I went with what seemed to be the simplest prescribed route). So, the character file:
[lua]game_character = {}
function game_character:new(x,y, inType)
local theImage = “graphics/” … inType … “.png”
local game_character_instance = display.newImageRect( theImage, 22 , 22)
game_character_instance.x = x
game_character_instance.y = y
local puCollisionFilter = {categoryBits =4, maskBits = 31}
local puBodyElement = {filter=puCollisionFilter, radius=10, density=1, bounce=.6}
game_character_instance.physicsBody = puBodyElement
game_character_instance.isBullet = true
game_character_instance.isSleepingAllowed = false
game_character_instance.objectType = inType;
physics.addBody(game_character_instance, “dynamic”, game_character_instance.physicsBody)
function game_character_instance:destroy(inAudio)
print(self)
audio.play(inAudio)
self:removeSelf()
self = nil
end
return game_character_instance
end
return game_character
[/lua]
Notice the destroy method- I’ve stripped the animation code out of it, but that’s where I had that coded.
Now, in the main game file, I create a character instance like this:
[lua]
local game_character_A= game_character:new(display.contentCenterX-50,display.contentCenterY-50, “characterA”)
game_character_A.collision = onCollision
game_character_A:addEventListener(‘collision’, game_character_A)
[/lua]
And then in the method which is triggered by the collision:
[lua]
function onCollision(self, event)
local theObj = event.other.objectType
if (self.objectType ==‘characterA’) then
if (theObj==“wall” and event.phase==“began”) then
local closureFxn = function()
self:destroy(wallHitSound)
end
timer.performWithDelay( 1, closureFxn )
end
end
end
[/lua]
So, this works 85% of the time. However, it often throws the following error (truncated for brevity):
character.lua:31: attempt to call method ‘removeSelf’ (a nil value)
message
stack traceback:
?: in function <?:218>
[C]: in function ‘removeSelf’
character.lua:31: in function ‘destroy’
scene_game.lua:506: in function ‘_listener’
?: in function <?:141>
?: in function <?:218>
I notice that when this occurs, the table name of the character is printed twice to the log, so it looks like the collision continues after the object has been removed.
Now, I know that you’re not supposed to remove objects during a collision; however, some of the literature out there says that you can circumvent this by catching it only at the “began” phase, and then setting a delay to the call for removal.
Some questions:
-
I noticed that in another slightly similar thread, the user was urged to check out the pre-collision event. Would that make more sense for me? Listen for pre-collision, then disable contact when the event is triggered, and then run the explosion animation and remove the character?
-
Is the mildly OOP way I have this set up botched, or preventing this from running correctly? Would it make more sense to include the removeSelf call right in the collision listener?
-
Or, am I just wildly off base here, and not even close to the correct solution?
Any insight would be greatly appreciated. This is my first large project with Lua- I’m coming from an actionscript 3/2 background, so I might not just be thinking “right” yet, especially in regards to scope and the way classes or event handling should be structured.
Thanks!