can't add body to new spawn image

Hi y’all,
I have this ball (let’s call it Ball A) that I’m using to hit walls and it has a collision listener.
Then, there’s another ball (call it Ball B) that I’m using to “collide” with ball A that needs to convert it to Ball C.

Here’s the code:

local bCollides = function(self, event )  
 if (event.phase == "began" and event.other.myName == "ballB") then  
 -- remove ballA  
 event.other:removeSelf()  
  
 -- convert ballA into ballC and position at ball's b x/y  
 local ballC = display.newImage("ballC.png", self.x, self.y)   
 physics.addBody( ballC, { bounce=0.6, radius=18 } )  
 ballC.myName = "ballC"  
 transToBallC = transition.to(ballC, {time=3000, y=72})  
  
 localGroup:insert(ballC)  
 end  
end  

As soon as ballA is removed and ballC appears, I bring the simulator to its knees and the whole thing craps out with an “assertion” error.

I have another listener that checks if BallC is near the top to remove it, but it won’t work unless I give BallC a body, which I can’t :frowning:

Any tips/ideas on how to go about it will be greatly appreciated.

Thanks,
RD [import]uid: 7856 topic_id: 5402 reply_id: 305402[/import]

I actually had a somewhat similar issue recently, with crashes when adding a body.

I cannot remember exactly how I fixed it, but it had to do with changing the order of things, I believe - maybe try that?

Sorry I can’t be more help, I’ll read through my file again later and see if I can remember exactly what I did.

Peach [import]uid: 10144 topic_id: 5402 reply_id: 18069[/import]

don’t add a body in your collision. you can’t. the specific reason is that you can’t change the physics simulation inside the box2d physics time “step”. we don’t have access to this step() function as such, but what we do know is that this occurs before the next enterframe.

so in your collision function set a flag that says eg

[lua]spawnBall=“C”[/lua]

and then in your enterframe function check this flag

[lua]if(spawnBall ~= nil)
spawnBallOfType(“C”) – call function to add the new ball
spawnBall = nil
end[/lua] [import]uid: 6645 topic_id: 5402 reply_id: 18196[/import]

Hi Peach and J,

I have tried moving things around and adding different variables to “trap”, but still no go :frowning:

this is pretty much the entire code:

------------------------------------------------------------------  
-- interception -- game over   
------------------------------------------------------------------  
local fnGameOver = function(self,event)  
 if event.phase == "began" then  
 self:removeSelf()  
 self = nil  
 isGameOver = true  
 end  
end  
  
------------------------------------------------------------------  
-- remove self if reached the top --  
------------------------------------------------------------------  
local removeSelfTop = function( self, event )  
if (event.phase == "began" and event.other.myName == "topWall" then   
 self.parent:remove( self )  
 self = nil  
 score = score+1  
end  
end  
------------------------------------------------------------------  
-- A collision listener to combine ballA and ballB --  
------------------------------------------------------------------  
local bCollidesA = function(self, event )  
 if (event.phase == "began" and event.other.myName == "ballB") then  
 audio.play( hitSound )  
 -- convert ballA into ballC and position at ball's b x/y  
 local ballC = display.newImage("ballC.png", self.x, self.y)   
 --physics.addBody( ballC, { bounce=0.1, radius=18 } )  
 ballC.myName = "ballC"  
 -- remove ballA  
 event.other:removeSelf()  
 event.other = nil  
 --remove ballA  
 self:removeSelf()  
 self = nil  
 -- move ball up  
 transToballC = transition.to(ballC, {time=3000, y=72})  
 -- collision detection  
 ballCObject.collision = removeSelfTop  
 ballCObject:addEventListener( "collision", ballCObject)  
  
 localGroup:insert(ballC)  
 end  
end  
  
------------------------------------------------------------------  
-- SPAWN SETUP --  
------------------------------------------------------------------  
--\> BallA spawn  
local fnBallA = function()  
  
 local fnRemoveA = function (ballAObject)  
 if (ballAObject ~= nil) or (ballAObject.transToballA ~= nil) then  
 transition.cancel(transToballA)  
 ballAObject:removeSelf()  
 end  
 end  
  
 local ballAObject = display.newImage( "ballA.png" )  
 ballAObject.x = math.random(40,400); ballAObject.y = 300  
 physics.addBody( ballAObject, { bounce=0.6, radius=16 } )  
 ballAObject.myName = "ballA"  
 ballAObject.isHit = false  
 ballAObject.alpha = 0.1  
 transition.to(ballAObject, { time=1000, alpha=1.0 })  
 ballAObject.transToballA = transition.to(ballAObject, {time=6000, x=240, y=72, onComplete=fnRemoveA})  
  
 -- touch event listener  
 ballAObject:addEventListener( "touch", fnGameOver )  
  
 -- collision detection  
 ballAObject.collision = bCollidesA  
 ballAObject:addEventListener( "collision", ballAObject)  
  
 localGroup:insert(ballAObject)  
end  
tmrBallA = timer.performWithDelay( 17000, fnBallA, 0 )  
--\> BallB spawn  
local fnBallB = function()  
 local ballBObject = display.newImage( "ballB.png" )  
 ballBObject.x = math.random(40,400); ballBObject.y = 300  
 physics.addBody( ballBObject, { bounce=0.6, radius=14 } )  
 ballBObject.myName = "ballB"  
 ballBObject.isHit = false  
 ballBObject.alpha = 0.1  
 transition.to(ballBObject, { time=1000, alpha=1.0 })  
 ballBObject.transToballB = transition.to(ballAObject, {time=6000, y=72})  
  
 -- collision detection  
 ballBObject.collision = removeSelfTop  
 ballBObject:addEventListener( "collision", ballBObject)  
  
 localGroup:insert(ballBObject)  
end  
tmrBallB = timer.performWithDelay( 1000, fnBallB, 0 )  
  

I tried the ‘nil’ check but now I’m getting errors about “removeSelf”.
cuz the onComplete never happens :frowning:

Hope you can provide additional feedback.

Thanks,
RD [import]uid: 7856 topic_id: 5402 reply_id: 18214[/import]

a few issues I can see here:

* [lua]transition.cancel(transToballA)[/lua]

transToBallA does not exist
ballAObject.transToBallA does though

* fnRemoveA is local to fnBallA, so i doubt your transition oncomplete can even see it

*you’re trying to use collisions without using physics. that’s not going to work i’m sure

(also note you cant add physics bodies inside a collision event, you’ll need to set a flag, that you can check and add the body in the next enterframe)
j

[import]uid: 6645 topic_id: 5402 reply_id: 18215[/import]

Hi J,
I am using physics at top of file

------------------------------------------------------------------  
-- PHYSICS --  
------------------------------------------------------------------  
local physics = require "physics"  
physics.start()  
physics.setGravity(0,0)  
  

I didn’t included the whole file cuz it’s getting pretty big and I have comments all over…that’s probably why I must’ve removed “ballAObject” from “ballAObject.transToBallA”, I put it back though and still the same “nil” problem.

I did however, created a new function as you suggested to “spawn” the new ballC, but I need to pass the x/y so I’m calling:

local bCollidesA = function(self, event )  
 if (event.phase == "began" and event.other.myName == "ballB") then  
 audio.play( hitSound )  
 -- remove ballB  
 event.other:removeSelf()  
 fnBallC(self.x,self.y)  
 self:removeSelf()  
 self = nil  
 end  
  
end  

And now I’m getting the “assertion” error back again bringing the simulator down to it’s knees :frowning:

Although “fnRemoveA” it’s local to fnBallA, it’s been seeing and process onComplete as long as the collision doesn’t happen. [import]uid: 7856 topic_id: 5402 reply_id: 18218[/import]

OK, I have confirmed it is the ‘onComplete’ transition that is causing all hell to break loose.
I have move the function outside and move it around and it still has the same issue.

Adding a check if it’s true and/or nil doesn’t fix a thing.

It’s a shame cuz the whole purpose of having an oncomplete function is so you don’t have to add additional event listeners.

for the moment, I removed and added another check to “topwall” for when they collide.

If anybody else knows how to “trap” and/or properly make the onComplete function work, I would much appreciate it.

Thanks,
RD [import]uid: 7856 topic_id: 5402 reply_id: 18415[/import]

I made a blog post about this pretty recently, here is the fix (regarding assertion errors on collision events):

http://jonbeebe.tumblr.com/post/2515495262/corona-collision-no-no

Hope that helps! [import]uid: 7849 topic_id: 5402 reply_id: 18444[/import]

WTF??? Can’t believe that did the trick.
In case anybody runs into this the only thing I did was add ‘delay’ to ballAObject:

transition.to(ballAObject, { time=1000, alpha=1.0 })  
 ballAObject.transToballA = transition.to(ballAObject, {time=6000, x=240, y=72, delay=1, onComplete=fnRemoveA})  
  

thanks jon, u freaking rule! [import]uid: 7856 topic_id: 5402 reply_id: 18729[/import]

@rdcube: Glad that helped!

And the ‘delay’ parameter in transition.to is very useful for avoiding extra timers/functions, so thanks for pointing that out :slight_smile: [import]uid: 7849 topic_id: 5402 reply_id: 18735[/import]