The code below:
-
creates a static physics object at bottom of screen (“bottomWall”)
-
creates a static physics object in the lower part of screen (“platform”)
-
creates a ball as a dynamic physics object and gives it an initial linear velocity
-
the ball then moves straight down, it passes thru the platform from above, then bounces back at the bottom wall and then also bounces back at the platform as it hits it from below
The intention of the code is to move a physics object thru another physics object but only one way. Thus, the ball passes thru the platform from above, but bounces back from below.
The code works, having arrived at it by trial and error.
My question is: is there a better / cleaner way to code this, particularly the removing of the event listener?
-
Are those two nested performWithDelay really necessary when removing the event listener?
-
And is it good practice to use event.contact.isEnabled = false here to allow the ball to pass through the platform from one direction?
display.setStatusBar(display.HiddenStatusBar) displayHeight = display.contentHeight displayWidth = display.contentWidth local physics = require “physics” physics.start() physics.setGravity(0,0) local bottomWall= display.newRect(displayWidth*0.5, displayHeight+25, displayWidth, 50) physics.addBody(bottomWall, ‘static’, {density=1, friction=0, bounce=1}) local platform = display.newRect( 0, 0, 280, 30 ) platform.x, platform.y = display.contentCenterX, display.contentCenterY+200 platform.collType = “passthru” physics.addBody( platform, “static”, { density=1, friction=0, bounce=1 } ) local ball = display.newCircle( 0, 0, 15 ) ball.x, ball.y = display.contentCenterX, display.contentCenterY-40 physics.addBody( ball, “dynamic”, { bounce=1, radius=20 } ) function removePreCollisionEventListener () timer.performWithDelay(10, ball:removeEventListener(“preCollision”), removePreCollisionEvent) end local function preCollisionEvent( self, event ) local collideObject = event.other local ballLinearVelocityX, ballLinearVelocityY = ball:getLinearVelocity() if ( collideObject.collType == “passthru” and ballLinearVelocityY > 0) then event.contact.isEnabled = false --disable this specific collision timer.performWithDelay(100, removePreCollisionEventListener) end end ball.preCollision = preCollisionEvent ball:addEventListener( “preCollision” ) ball:setLinearVelocity( 0, 300)