I’m developing a Pong game, just to learn Solard2D.
When the ball touches an invisible segment all over the right or left edge of the screen then I have a point.
So on ball collision OnEvent I have the choice whether or not I have reached the required score, in this case I stop the physical world, the ball, and close the game.
I read that in on event I can’t close the physical world so I set a timer.
The problem is, in any case, I can’t stop the world. Where am I wrong?
Here are the pieces of code:
local function onCollision( self, event )
if ( event.phase == "began" ) then
if (self.Name == "ball") and (event.other.Name == "edgeDx" ) then
if settingsTable["sound"] == true then audio.play(pointSnd) end
writeScreenPoint()
timer.performWithDelay( 25, stopBall, 1 )
timer.performWithDelay( 30, centerBall, 1 )
if someOneWins() == true then
-- someone wins, I go on starting game screen
composer.gotoScene( "welcome", { time=100, effect="crossFade" } )
end
end
return true
end
function scene:hide( event )
local phase = event.phase
if ( phase == "will" ) then
transition:pause()
physics.pause()
Runtime:removeEventListener(...) -- remove all EventListener
local result = function() return physicsStop( physics.stop() ) end
repeat
timer.performWithDelay( 25, result)
print("Waiting physics stops...")
until result == true
…
will never stops an loops forever.
Thanks!
Renato
I think you could create some flag in your collision function and then check this flag in the runtime.
timer.perforWithDelay() should work as well so something might be wrong with stopBall() or centerBall() probably.
Here’s code example maybe it’ll help:
local physics = require("physics")
physics.start()
physics.setDrawMode( "hybrid" )
local ball = display.newCircle(100, 100, 10)
ball.Name = "ball"
local lWall = display.newRect(0, 240, 10, 480)
local rWall = display.newRect(320, 240, 10, 480)
local uWall = display.newRect(160, 0, 320, 10)
local dWall = display.newRect(160, 480, 320, 10)
lWall.Name, rWall.Name, uWall.name, dWall.Name = "edgeDx", "edgeDx", "edgeDx", "edgeDx"
physics.addBody(ball, "dynamic", {radius = 10})
physics.addBody(lWall, "static")
physics.addBody(rWall, "static")
physics.addBody(uWall, "static")
physics.addBody(dWall, "static")
ball:applyForce( 0.2, 0.9, 0, 0 )
local function onCollision( self, event )
if event.phase == "began" then
if self.Name == "ball" and event.other.Name == "edgeDx" then
ball.hasCollided = true
-- this also works
--[[
timer.performWithDelay( 30, function()
physics.stop()
end, 1)
--]]
end
end
end
ball.collision = onCollision
ball:addEventListener( "collision" )
function onUpdate()
if ball.hasCollided then
physics.stop()
Runtime:removeEventListener( "enterFrame", onUpdate )
end
end
Runtime:addEventListener( "enterFrame", onUpdate )
This is happening because your composer.gotoScene() call will cause the current scene to hide before the onCollision() event has finished executing.
Using a flag is a good way of doing that or delay a call to a clean down function that will pause your game/world.
Thanks,
now works. But only if I close physics inside an eventListener.
If I call from eventListener a composer.gotoscene() without stop physics and I stop from a scene:hide i receive an error!
…and now going back on my “welcome” scene physics won’t start…
nightmare ;(
Renato