Grumble… grumble… OK, this really is my last response as I do have to get back to work.
I see a number of issues with your code. However these are all good things. You’re exploring and you will learn by doing this.
The issues are:
-
Over-Complex - This is a side-effect of two things:
- You started by using a global event listener. This messed you up.
- You’re new and trying to be exact when you some things you are checking for are actually explicit in a local listener.
-
Next Stumble - Once you get past this ‘nil’ issue, you will find that the engine complains about you setting linear velocity during the collision listener. You must wait one frame before doing any box2D work during a collision listener. This is simply how the box2D physics engine works.
-
Manual Direction Changing - Your collision listener is effectively changing the direction of the ball manually. This is wrong. My guess is, you are doing this because you tried to let physics handle the bouncing and found that you were losing velocity or the bounces seemed weird. Anyways, this is a semi-advanced phenomenon and is related to how the box2D engine works and to your expectations. I simply can’t address this here.
I will address the first two issues.
Over-Complex
Again. Your code is super complicated and it doesn’t need to be. Study this basic framework and I think you will see it is both clean and accounts for all the things you’re trying to resolve in your code:
function ball.collision( self, event ) local phase = event.phase local other = event.other.id if( phase == "began" ) then if( other == "player") then elseif( other == "enemy" ) then elseif( other == "topBarrier" ) then elseif( other == "bottomBarrier" ) then else print("WHAT?") end end return false end
Next Stumble
You are not allowed to make box2D changes in the middle of a collision event because the box2D engine is in the middle of processing this FRAME’s physics data. Calling any box2D function would change the state of the engine in this moment and that is not allowed.
Fortunately, there is an easy way to resolve this. Wait 1 millisecond. This effectively defers your code till the beginning of the next frame and before the next physics processing loop.
timer.performWithDelay( 1, function() self:setLinearVelocity( -vx, vy ) end )
SSK2 To The Rescue?
I want you to know, I am glad you’re working on this, but you should know I’ve decided to help SSK2 owners out.
I will be adding a number of ‘fundamental’ game examples to SSK2 over the next couple of weeks and PONG will be one of them.
Note: I have not yet decided if this will be an SSK2 PRO only thing, or if some will also be available to lite users.