Physics isnt working propery

Hello, I am creating a game and the physics engine doesn’t react on the object until the plane is halfway through it. What am I doing wrong?

local composer = require( "composer" ) local scene = composer.newScene() local physics = require "physics" physics.start(); physics.pause() local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth\*0.5 local player local score = 0 local displayScore local GAMESTATUS = "playing" --playing, paused function scene:create( event ) local sceneGroup = self.view -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*BACKGROUND INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local background = display.newRect(0, 0, screenW, screenH) background.anchorX, background.anchorY = 0, 0 background:setFillColor(black) -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*PLAYER INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local sheetData = { width=128, height=170, numFrames=10, sheetContentWidth=1390, sheetContentHeight=170 } local sequenceData = { { name="default", start=1, count=10, time=1800 } } local sheet = graphics.newImageSheet("3.png", sheetData) player = display.newSprite(sheet, sequenceData) player.x = 200 player.y = screenH / 2 player.rotation = 90 player:scale(0.5, 0.5) player.myName = "player" physics.addBody(player, "dynamic", { density=1, bounce=0.4, friction=0.3, radius=12 } ) player:play() -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*WALL INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local topWall = display.newRect(0, 0, screenW, 30) topWall:setFillColor(black) topWall.x = screenW - (topWall.width / 2) topWall.y = 0 physics.addBody(topWall, "static", { density=1, bounce=0.2, friction=0.2 } ) local bottomWall = display.newRect(0, screenH, screenW, 30) bottomWall:setFillColor(black) bottomWall.x = screenW - (bottomWall.width / 2) bottomWall.y = screenH physics.addBody( bottomWall, "static", { density=1, bounce=0.2, friction=0.2 } ) displayScore = display.newText(tostring(score), screenW / 2, 0) sceneGroup:insert ( background ) sceneGroup:insert ( topWall ) sceneGroup:insert ( bottomWall ) sceneGroup:insert ( player ) sceneGroup:insert ( displayScore ) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase physics = require "physics" if phase == "will" then elseif phase == "did" then physics.start() end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then physics.stop() elseif phase == "did" then end end function scene:destroy( event ) local sceneGroup = self.view package.loaded[physics] = nil physics = nil player:removeSelf() player = nil displayScore:removeSelf() displayScore = nil end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) function useJets(self, event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if player ~= nil then self:applyForce(0, -10, self.x, self.y) end end end function touchEvent(event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if event.phase == "began" then transition.to( player, { rotation= 86, time=math.random(100,200), transition=easing.inOutCubic } ) player.enterFrame = useJets Runtime:addEventListener("enterFrame", player) end if event.phase == "ended" then transition.to( player, { rotation= 94, time=math.random(100,200), transition=easing.inOutCubic } ) Runtime:removeEventListener("enterFrame", player) end end end Runtime:addEventListener("touch", touchEvent) function deleteAsteroid(self) display.remove(self) self = nil end function spawnAsteroid() if GAMESTATUS == "playing" then local res = math.floor(math.random(4, 7)) local asteroid if res == 4 then asteroid = display.newImage("planet4.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 5 then asteroid = display.newImage("planet5.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 6 then asteroid = display.newImage("planet6.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 7 then asteroid = display.newImage("planet7.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end asteroid:scale(0.25, 0.25) asteroid.myName = "asteroid" physics.addBody( asteroid, "static", { density=1, bounce=0.3, friction=0.1, radius=12 } ); transition.to( asteroid, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteAsteroid } ); transition.to( asteroid, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) score = score + 1 displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end end timer.performWithDelay( 2000, spawnAsteroid, 0 ) function generateGem() if GAMESTATUS == "playing" then local gemData = { width=155, height=195, numFrames=15, sheetContentWidth=155, sheetContentHeight=2925 } local gemSequenceData = { { name="default", start=1, count=15, time=2500 } } local switch = math.floor(math.random(1, 5)) local gemSheet if switch == 1 then gemSheet = graphics.newImageSheet("greenGem.png", gemData) -- + 5 score score = score + 5 end if switch == 2 then if math.random(1,10) then gemSheet = graphics.newImageSheet("blueGem.png", gemData) -- + 15 score score = score + 15 freezeWorld() timer.performWithDelay( math.random(8000,10000), unFreezeWorld, 0 ) else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 3 then if math.random(1, 3) == 1 then gemSheet = graphics.newImageSheet("whiteGem.png", gemData) -- + 30 score score = score + 30 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 4 then if math.random(1, 4) == 1 then gemSheet = graphics.newImageSheet("yellowGem.png", gemData) -- + 75 score score = score + 75 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 5 then if math.random(1, 5) == 1 then gemSheet = graphics.newImageSheet("redGem.png", gemData) -- + 150 score score = score + 150 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end local gem = display.newSprite(gemSheet, gemSequenceData) gem.x = screenW gem.y = math.random(0, screenH) gem:scale(0.5, 0.5) physics.addBody( gem, "dynamic", { density=1, bounce=0.3, friction=0.1, radius=12 } ) gem.myName = "gem" transition.to( gem, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) transition.to( gem, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteGem } ); gem:play() end end function deleteGem(self) display.remove(self) self = nil end function freezeWorld(self ) GAMESTATUS = "frozen" displayScore:removeSelf() displayScore = nil displayScore = display.newText("F R O Z E N", screenW / 2, 0) end function unFreezeWorld() GAMESTATUS = "playing" displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end timer.performWithDelay( math.random(3000,10000), generateGem, 0 ) function onCollision(event) if event.phase == "began" then --player gem collision if event.object1.myName == "player" then if event.object2.myName == "gem" then end end -- player asteroid collision if event.object1.myName == "player" then if event.object2.myName == "asteroid" then GAMESTATUS = "OVER" end end end if event.phase == "ended" then end end Runtime:addEventListener("collision", onCollision) function updateStatus() if GAMESTATUS == "OVER" then end end Runtime:addEventListener("enterFrame", updateStatus) return scene

Thank you.

Hi dan_pc,

You can’t scale physics bodies in Box2D. If you scale the object, it will visually appear at that scaled size, but the physics engine will regard its internal body as the original size you declared.

To see how bodies are actually being considered by the physics engine, set hybrid mode on:

[lua]

physics.setDrawMode( “hybrid” )

[/lua]

Take care,

Brent

Even after I took out the scaling, the objects only collide at the center.

Notice anything else?

Thanks!

local composer = require( "composer" ) local scene = composer.newScene() local physics = require "physics" physics.start(); physics.pause() local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth\*0.5 local player local score = 0 local displayScore local GAMESTATUS = "playing" --playing, paused function scene:create( event ) local sceneGroup = self.view -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*BACKGROUND INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local background = display.newRect(0, 0, screenW, screenH) background.anchorX, background.anchorY = 0, 0 background:setFillColor(black) -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*PLAYER INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local sheetData = { width=128, height=170, numFrames=10, sheetContentWidth=1390, sheetContentHeight=170 } local sequenceData = { { name="default", start=1, count=10, time=1800 } } local sheet = graphics.newImageSheet("3.png", sheetData) player = display.newSprite(sheet, sequenceData) player.x = 200 player.y = screenH / 2 player.rotation = 90 player.myName = "player" physics.addBody(player, "dynamic", { density=1, bounce=0.4, friction=0.3, radius=12 } ) player:play() physics.setDrawMode( "hybrid" ) -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*WALL INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local topWall = display.newRect(0, 0, screenW, 30) topWall:setFillColor(black) topWall.x = screenW - (topWall.width / 2) topWall.y = 0 physics.addBody(topWall, "static", { density=1, bounce=0.2, friction=0.2 } ) local bottomWall = display.newRect(0, screenH, screenW, 30) bottomWall:setFillColor(black) bottomWall.x = screenW - (bottomWall.width / 2) bottomWall.y = screenH physics.addBody( bottomWall, "static", { density=1, bounce=0.2, friction=0.2 } ) displayScore = display.newText(tostring(score), screenW / 2, 0) sceneGroup:insert ( background ) sceneGroup:insert ( topWall ) sceneGroup:insert ( bottomWall ) sceneGroup:insert ( player ) sceneGroup:insert ( displayScore ) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase physics = require "physics" if phase == "will" then elseif phase == "did" then physics.start() end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then physics.stop() elseif phase == "did" then end end function scene:destroy( event ) local sceneGroup = self.view package.loaded[physics] = nil physics = nil player:removeSelf() player = nil displayScore:removeSelf() displayScore = nil end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) function useJets(self, event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if player ~= nil then self:applyForce(0, -10, self.x, self.y) end end end function touchEvent(event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if event.phase == "began" then transition.to( player, { rotation= 86, time=math.random(100,200), transition=easing.inOutCubic } ) player.enterFrame = useJets Runtime:addEventListener("enterFrame", player) end if event.phase == "ended" then transition.to( player, { rotation= 94, time=math.random(100,200), transition=easing.inOutCubic } ) Runtime:removeEventListener("enterFrame", player) end end end Runtime:addEventListener("touch", touchEvent) function deleteAsteroid(self) display.remove(self) self = nil end function spawnAsteroid() if GAMESTATUS == "playing" then local res = math.floor(math.random(4, 7)) local asteroid if res == 4 then asteroid = display.newImage("planet4.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 5 then asteroid = display.newImage("planet5.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 6 then asteroid = display.newImage("planet6.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 7 then asteroid = display.newImage("planet7.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end asteroid.myName = "asteroid" physics.addBody( asteroid, "static", { density=1, bounce=0.3, friction=0.1, radius=12 } ); transition.to( asteroid, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteAsteroid } ); transition.to( asteroid, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) score = score + 1 displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end end timer.performWithDelay( 2000, spawnAsteroid, 0 ) function generateGem() if GAMESTATUS == "playing" then local gemData = { width=155, height=195, numFrames=15, sheetContentWidth=155, sheetContentHeight=2925 } local gemSequenceData = { { name="default", start=1, count=15, time=2500 } } local switch = math.floor(math.random(1, 5)) local gemSheet if switch == 1 then gemSheet = graphics.newImageSheet("greenGem.png", gemData) -- + 5 score score = score + 5 end if switch == 2 then if math.random(1,10) then gemSheet = graphics.newImageSheet("blueGem.png", gemData) -- + 15 score score = score + 15 freezeWorld() timer.performWithDelay( math.random(8000,10000), unFreezeWorld, 0 ) else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 3 then if math.random(1, 3) == 1 then gemSheet = graphics.newImageSheet("whiteGem.png", gemData) -- + 30 score score = score + 30 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 4 then if math.random(1, 4) == 1 then gemSheet = graphics.newImageSheet("yellowGem.png", gemData) -- + 75 score score = score + 75 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 5 then if math.random(1, 5) == 1 then gemSheet = graphics.newImageSheet("redGem.png", gemData) -- + 150 score score = score + 150 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end local gem = display.newSprite(gemSheet, gemSequenceData) gem.x = screenW gem.y = math.random(0, screenH) physics.addBody( gem, "dynamic", { density=1, bounce=0.3, friction=0.1, radius=12 } ) gem.myName = "gem" transition.to( gem, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) transition.to( gem, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteGem } ); gem:play() end end function deleteGem(self) display.remove(self) self = nil end function freezeWorld(self ) GAMESTATUS = "frozen" displayScore:removeSelf() displayScore = nil displayScore = display.newText("F R O Z E N", screenW / 2, 0) end function unFreezeWorld() GAMESTATUS = "playing" displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end timer.performWithDelay( math.random(3000,10000), generateGem, 0 ) function onCollision(event) if event.phase == "began" then --player gem collision if event.object1.myName == "player" then if event.object2.myName == "gem" then end end -- player asteroid collision if event.object1.myName == "player" then if event.object2.myName == "asteroid" then GAMESTATUS = "OVER" end end end if event.phase == "ended" then end end Runtime:addEventListener("collision", onCollision) function updateStatus() if GAMESTATUS == "OVER" then end end Runtime:addEventListener("enterFrame", updateStatus) return scene

Hi Dan,

When viewing in “hybrid” mode, are the bodies colliding correctly?

Brent

They are collliding correctly. The circles are at the very center of each object and when those circles collide then the physics event happens. The circles are small. So small that another object has to move to the very center of that object before the circles touch,

Hi Dan,

When using physics bodies so small, you’re likely going to get some overlap before the collision is detected. This is basically because the engine can only sense collisions on each app time step, and if an object moves quickly, it may visually overlap another before Box2D can “catch up” and detect the collision and take action.

There are ways to work with this, but all of them come with some performance penalty. You could make the object(s) into bullet types, which increases its sensitivity but taxes the physics engine a bit more. You could also increase the collision sensitivity across the board, but that also may have an impact. Finally, you could consider pre-collisions, but those should normally be used in moderation for the same reasons I’ve said.

All of that being said, “performance” is something of a grey area. If your scenario runs smoothly on most modern devices, then perhaps you could just proceed and forget about older devices. It’s up to you what kind of experience you want to deliver to your players.

Brent

Hi dan_pc,

You can’t scale physics bodies in Box2D. If you scale the object, it will visually appear at that scaled size, but the physics engine will regard its internal body as the original size you declared.

To see how bodies are actually being considered by the physics engine, set hybrid mode on:

[lua]

physics.setDrawMode( “hybrid” )

[/lua]

Take care,

Brent

Even after I took out the scaling, the objects only collide at the center.

Notice anything else?

Thanks!

local composer = require( "composer" ) local scene = composer.newScene() local physics = require "physics" physics.start(); physics.pause() local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth\*0.5 local player local score = 0 local displayScore local GAMESTATUS = "playing" --playing, paused function scene:create( event ) local sceneGroup = self.view -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*BACKGROUND INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local background = display.newRect(0, 0, screenW, screenH) background.anchorX, background.anchorY = 0, 0 background:setFillColor(black) -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*PLAYER INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local sheetData = { width=128, height=170, numFrames=10, sheetContentWidth=1390, sheetContentHeight=170 } local sequenceData = { { name="default", start=1, count=10, time=1800 } } local sheet = graphics.newImageSheet("3.png", sheetData) player = display.newSprite(sheet, sequenceData) player.x = 200 player.y = screenH / 2 player.rotation = 90 player.myName = "player" physics.addBody(player, "dynamic", { density=1, bounce=0.4, friction=0.3, radius=12 } ) player:play() physics.setDrawMode( "hybrid" ) -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*WALL INIT\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local topWall = display.newRect(0, 0, screenW, 30) topWall:setFillColor(black) topWall.x = screenW - (topWall.width / 2) topWall.y = 0 physics.addBody(topWall, "static", { density=1, bounce=0.2, friction=0.2 } ) local bottomWall = display.newRect(0, screenH, screenW, 30) bottomWall:setFillColor(black) bottomWall.x = screenW - (bottomWall.width / 2) bottomWall.y = screenH physics.addBody( bottomWall, "static", { density=1, bounce=0.2, friction=0.2 } ) displayScore = display.newText(tostring(score), screenW / 2, 0) sceneGroup:insert ( background ) sceneGroup:insert ( topWall ) sceneGroup:insert ( bottomWall ) sceneGroup:insert ( player ) sceneGroup:insert ( displayScore ) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase physics = require "physics" if phase == "will" then elseif phase == "did" then physics.start() end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then physics.stop() elseif phase == "did" then end end function scene:destroy( event ) local sceneGroup = self.view package.loaded[physics] = nil physics = nil player:removeSelf() player = nil displayScore:removeSelf() displayScore = nil end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) function useJets(self, event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if player ~= nil then self:applyForce(0, -10, self.x, self.y) end end end function touchEvent(event) if GAMESTATUS == "playing" or GAMESTATUS == "frozen" then if event.phase == "began" then transition.to( player, { rotation= 86, time=math.random(100,200), transition=easing.inOutCubic } ) player.enterFrame = useJets Runtime:addEventListener("enterFrame", player) end if event.phase == "ended" then transition.to( player, { rotation= 94, time=math.random(100,200), transition=easing.inOutCubic } ) Runtime:removeEventListener("enterFrame", player) end end end Runtime:addEventListener("touch", touchEvent) function deleteAsteroid(self) display.remove(self) self = nil end function spawnAsteroid() if GAMESTATUS == "playing" then local res = math.floor(math.random(4, 7)) local asteroid if res == 4 then asteroid = display.newImage("planet4.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 5 then asteroid = display.newImage("planet5.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 6 then asteroid = display.newImage("planet6.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end if res == 7 then asteroid = display.newImage("planet7.gif", screenW, math.random(0, screenH)); asteroid.rotation = math.floor(math.random(1, 360)) end asteroid.myName = "asteroid" physics.addBody( asteroid, "static", { density=1, bounce=0.3, friction=0.1, radius=12 } ); transition.to( asteroid, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteAsteroid } ); transition.to( asteroid, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) score = score + 1 displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end end timer.performWithDelay( 2000, spawnAsteroid, 0 ) function generateGem() if GAMESTATUS == "playing" then local gemData = { width=155, height=195, numFrames=15, sheetContentWidth=155, sheetContentHeight=2925 } local gemSequenceData = { { name="default", start=1, count=15, time=2500 } } local switch = math.floor(math.random(1, 5)) local gemSheet if switch == 1 then gemSheet = graphics.newImageSheet("greenGem.png", gemData) -- + 5 score score = score + 5 end if switch == 2 then if math.random(1,10) then gemSheet = graphics.newImageSheet("blueGem.png", gemData) -- + 15 score score = score + 15 freezeWorld() timer.performWithDelay( math.random(8000,10000), unFreezeWorld, 0 ) else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 3 then if math.random(1, 3) == 1 then gemSheet = graphics.newImageSheet("whiteGem.png", gemData) -- + 30 score score = score + 30 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 4 then if math.random(1, 4) == 1 then gemSheet = graphics.newImageSheet("yellowGem.png", gemData) -- + 75 score score = score + 75 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end if switch == 5 then if math.random(1, 5) == 1 then gemSheet = graphics.newImageSheet("redGem.png", gemData) -- + 150 score score = score + 150 else gemSheet = graphics.newImageSheet("greenGem.png", gemData) end end local gem = display.newSprite(gemSheet, gemSequenceData) gem.x = screenW gem.y = math.random(0, screenH) physics.addBody( gem, "dynamic", { density=1, bounce=0.3, friction=0.1, radius=12 } ) gem.myName = "gem" transition.to( gem, { rotation=360, time=math.random(2000,8000), transition=easing.inOutCubic } ) transition.to( gem, { time=math.random(2000,8000), x=0 , y=math.random(0, screenH), onComplete=deleteGem } ); gem:play() end end function deleteGem(self) display.remove(self) self = nil end function freezeWorld(self ) GAMESTATUS = "frozen" displayScore:removeSelf() displayScore = nil displayScore = display.newText("F R O Z E N", screenW / 2, 0) end function unFreezeWorld() GAMESTATUS = "playing" displayScore:removeSelf() displayScore = nil displayScore = display.newText(tostring(score), screenW / 2, 0) end timer.performWithDelay( math.random(3000,10000), generateGem, 0 ) function onCollision(event) if event.phase == "began" then --player gem collision if event.object1.myName == "player" then if event.object2.myName == "gem" then end end -- player asteroid collision if event.object1.myName == "player" then if event.object2.myName == "asteroid" then GAMESTATUS = "OVER" end end end if event.phase == "ended" then end end Runtime:addEventListener("collision", onCollision) function updateStatus() if GAMESTATUS == "OVER" then end end Runtime:addEventListener("enterFrame", updateStatus) return scene

Hi Dan,

When viewing in “hybrid” mode, are the bodies colliding correctly?

Brent

They are collliding correctly. The circles are at the very center of each object and when those circles collide then the physics event happens. The circles are small. So small that another object has to move to the very center of that object before the circles touch,

Hi Dan,

When using physics bodies so small, you’re likely going to get some overlap before the collision is detected. This is basically because the engine can only sense collisions on each app time step, and if an object moves quickly, it may visually overlap another before Box2D can “catch up” and detect the collision and take action.

There are ways to work with this, but all of them come with some performance penalty. You could make the object(s) into bullet types, which increases its sensitivity but taxes the physics engine a bit more. You could also increase the collision sensitivity across the board, but that also may have an impact. Finally, you could consider pre-collisions, but those should normally be used in moderation for the same reasons I’ve said.

All of that being said, “performance” is something of a grey area. If your scenario runs smoothly on most modern devices, then perhaps you could just proceed and forget about older devices. It’s up to you what kind of experience you want to deliver to your players.

Brent