(physics) Prevent objects from bouncing away and never returning

I have items dropping from the sky (like the crate example), and I have 3 sides of forcefields (left, right, bottom) so objects can’t leave the stage. Unfortunately, sometimes they bounce off the floor and up off the screen.

 --@start creating boundaries  
 local leftBoundary = display.newRect(-100,0,150,display.contentHeight + 800)  
 local rightBoundary = display.newRect(display.contentWidth-50,0,150,display.contentHeight + 800)  
 physics.addBody(leftBoundary,'static')  
 physics.addBody(rightBoundary,'static')  
 leftBoundary.alpha = 0.01  
 rightBoundary.alpha = 0.01  
  
 local ground = display.newRect(0,725,display.contentWidth,168)  
 ground:setFillColor(255,255,255)  
 ground.alpha = 0.01  
 physics.addBody(ground,"static")  
  
 screen:insert(leftBoundary)  
 screen:insert(rightBoundary)  
 screen:insert(ground)  

I tried to add a “roof”, but that prevented the items from dropping into the play area. So I tried adding 800 pix to the left and right walls height to prevent escape, but that didn’t work either. So I am looking for a real method to keep all game pieces in play without leaving. [import]uid: 132937 topic_id: 36215 reply_id: 336215[/import]

Hi there,

A quick question for you. When an object bounces very high, do you want it to (a) bounce off the top of the screen (like it hit a ceiling), or (b) disappear above the screen but eventually fall back down into the screen?

  • Andrew [import]uid: 109711 topic_id: 36215 reply_id: 143842[/import]

Andrew,
I want them to bounce off the ceiling and never leave the viewable area.

so it would be (a) as the answer to your question. I reduced the bounce, to keep them in stage, but they sometimes hit just right and leave anyway. A ceiling would work nice. [import]uid: 132937 topic_id: 36215 reply_id: 143844[/import]

Hello,
How about making a “one sided” ceiling? Every falling object begins as a sensor. When one hits the ceiling piece from above, you ignore the began phase but listen to the ended phase… and then you turn it into normal body again. Object is now “in bounds” and will bounce off everything, including the ceiling.

Brent [import]uid: 200026 topic_id: 36215 reply_id: 143859[/import]

So I added the roof /ceiling

 local roof = display.newRect(0,200,display.contentWidth,168) -- put at 200 so I can view/see effect during debugging  
 roof:setFillColor(255,255,255)  
 roof.alpha = 0.01  
 physics.addBody(roof,'static')  
  
local function onCollision(event)  
 if event.phase == 'began' then  
 print("I began hit event")  
 elseif event.phase == 'ended' then  
 physics.removeBody(event.target)  
 end  
 end  
 roof:addEventListener("collision", onCollision)   
  
 screen:insert(leftBoundary)  
 screen:insert(rightBoundary)  
 screen:insert(ground)  
 screen:insert(roof)  

But I get ERROR: physics.remove body cannot be called when the world is locked and in the middle of number crunching such as during a collision event. I guess I don’t know what makes the roof/ceiling one sided. [import]uid: 132937 topic_id: 36215 reply_id: 143937[/import]

Hi @ElectricDisk,
It’s not a special “trick” that’s making the ceiling “one sided”. The method is just to make your dropping objects into sensors when they start (above the ceiling and off screen), so they pass through it as they fall… but still trigger a collision event. Then on the “ended” of that collision event, as they pass below and outside the ceiling’s bounds, you change them into non-sensor objects so they can interact with your other boundaries and objects. Certainly, don’t remove the physics body in this case, it’s not necessary.

As for that error you’re getting, that’s fairly common and easily remedied. Basically, Box2D can’t perform some actions during while a collision is still “resolving itself”, so you just have to trigger some things using a tiny, never-will-be-detected timer of 10 milliseconds or so. This tells Box2D to resolve that event on the NEXT game cycle, and it will, safely.

Regards,
Brent [import]uid: 200026 topic_id: 36215 reply_id: 143941[/import]

Hi there,

A quick question for you. When an object bounces very high, do you want it to (a) bounce off the top of the screen (like it hit a ceiling), or (b) disappear above the screen but eventually fall back down into the screen?

  • Andrew [import]uid: 109711 topic_id: 36215 reply_id: 143842[/import]

Andrew,
I want them to bounce off the ceiling and never leave the viewable area.

so it would be (a) as the answer to your question. I reduced the bounce, to keep them in stage, but they sometimes hit just right and leave anyway. A ceiling would work nice. [import]uid: 132937 topic_id: 36215 reply_id: 143844[/import]

Hello,
How about making a “one sided” ceiling? Every falling object begins as a sensor. When one hits the ceiling piece from above, you ignore the began phase but listen to the ended phase… and then you turn it into normal body again. Object is now “in bounds” and will bounce off everything, including the ceiling.

Brent [import]uid: 200026 topic_id: 36215 reply_id: 143859[/import]

So I added the roof /ceiling

 local roof = display.newRect(0,200,display.contentWidth,168) -- put at 200 so I can view/see effect during debugging  
 roof:setFillColor(255,255,255)  
 roof.alpha = 0.01  
 physics.addBody(roof,'static')  
  
local function onCollision(event)  
 if event.phase == 'began' then  
 print("I began hit event")  
 elseif event.phase == 'ended' then  
 physics.removeBody(event.target)  
 end  
 end  
 roof:addEventListener("collision", onCollision)   
  
 screen:insert(leftBoundary)  
 screen:insert(rightBoundary)  
 screen:insert(ground)  
 screen:insert(roof)  

But I get ERROR: physics.remove body cannot be called when the world is locked and in the middle of number crunching such as during a collision event. I guess I don’t know what makes the roof/ceiling one sided. [import]uid: 132937 topic_id: 36215 reply_id: 143937[/import]

Hi @ElectricDisk,
It’s not a special “trick” that’s making the ceiling “one sided”. The method is just to make your dropping objects into sensors when they start (above the ceiling and off screen), so they pass through it as they fall… but still trigger a collision event. Then on the “ended” of that collision event, as they pass below and outside the ceiling’s bounds, you change them into non-sensor objects so they can interact with your other boundaries and objects. Certainly, don’t remove the physics body in this case, it’s not necessary.

As for that error you’re getting, that’s fairly common and easily remedied. Basically, Box2D can’t perform some actions during while a collision is still “resolving itself”, so you just have to trigger some things using a tiny, never-will-be-detected timer of 10 milliseconds or so. This tells Box2D to resolve that event on the NEXT game cycle, and it will, safely.

Regards,
Brent [import]uid: 200026 topic_id: 36215 reply_id: 143941[/import]

Hi there,

A quick question for you. When an object bounces very high, do you want it to (a) bounce off the top of the screen (like it hit a ceiling), or (b) disappear above the screen but eventually fall back down into the screen?

  • Andrew [import]uid: 109711 topic_id: 36215 reply_id: 143842[/import]

Andrew,
I want them to bounce off the ceiling and never leave the viewable area.

so it would be (a) as the answer to your question. I reduced the bounce, to keep them in stage, but they sometimes hit just right and leave anyway. A ceiling would work nice. [import]uid: 132937 topic_id: 36215 reply_id: 143844[/import]

Hello,
How about making a “one sided” ceiling? Every falling object begins as a sensor. When one hits the ceiling piece from above, you ignore the began phase but listen to the ended phase… and then you turn it into normal body again. Object is now “in bounds” and will bounce off everything, including the ceiling.

Brent [import]uid: 200026 topic_id: 36215 reply_id: 143859[/import]

So I added the roof /ceiling

 local roof = display.newRect(0,200,display.contentWidth,168) -- put at 200 so I can view/see effect during debugging  
 roof:setFillColor(255,255,255)  
 roof.alpha = 0.01  
 physics.addBody(roof,'static')  
  
local function onCollision(event)  
 if event.phase == 'began' then  
 print("I began hit event")  
 elseif event.phase == 'ended' then  
 physics.removeBody(event.target)  
 end  
 end  
 roof:addEventListener("collision", onCollision)   
  
 screen:insert(leftBoundary)  
 screen:insert(rightBoundary)  
 screen:insert(ground)  
 screen:insert(roof)  

But I get ERROR: physics.remove body cannot be called when the world is locked and in the middle of number crunching such as during a collision event. I guess I don’t know what makes the roof/ceiling one sided. [import]uid: 132937 topic_id: 36215 reply_id: 143937[/import]

Hi @ElectricDisk,
It’s not a special “trick” that’s making the ceiling “one sided”. The method is just to make your dropping objects into sensors when they start (above the ceiling and off screen), so they pass through it as they fall… but still trigger a collision event. Then on the “ended” of that collision event, as they pass below and outside the ceiling’s bounds, you change them into non-sensor objects so they can interact with your other boundaries and objects. Certainly, don’t remove the physics body in this case, it’s not necessary.

As for that error you’re getting, that’s fairly common and easily remedied. Basically, Box2D can’t perform some actions during while a collision is still “resolving itself”, so you just have to trigger some things using a tiny, never-will-be-detected timer of 10 milliseconds or so. This tells Box2D to resolve that event on the NEXT game cycle, and it will, safely.

Regards,
Brent [import]uid: 200026 topic_id: 36215 reply_id: 143941[/import]

Hi there,

A quick question for you. When an object bounces very high, do you want it to (a) bounce off the top of the screen (like it hit a ceiling), or (b) disappear above the screen but eventually fall back down into the screen?

  • Andrew [import]uid: 109711 topic_id: 36215 reply_id: 143842[/import]

Andrew,
I want them to bounce off the ceiling and never leave the viewable area.

so it would be (a) as the answer to your question. I reduced the bounce, to keep them in stage, but they sometimes hit just right and leave anyway. A ceiling would work nice. [import]uid: 132937 topic_id: 36215 reply_id: 143844[/import]

Hello,
How about making a “one sided” ceiling? Every falling object begins as a sensor. When one hits the ceiling piece from above, you ignore the began phase but listen to the ended phase… and then you turn it into normal body again. Object is now “in bounds” and will bounce off everything, including the ceiling.

Brent [import]uid: 200026 topic_id: 36215 reply_id: 143859[/import]

So I added the roof /ceiling

 local roof = display.newRect(0,200,display.contentWidth,168) -- put at 200 so I can view/see effect during debugging  
 roof:setFillColor(255,255,255)  
 roof.alpha = 0.01  
 physics.addBody(roof,'static')  
  
local function onCollision(event)  
 if event.phase == 'began' then  
 print("I began hit event")  
 elseif event.phase == 'ended' then  
 physics.removeBody(event.target)  
 end  
 end  
 roof:addEventListener("collision", onCollision)   
  
 screen:insert(leftBoundary)  
 screen:insert(rightBoundary)  
 screen:insert(ground)  
 screen:insert(roof)  

But I get ERROR: physics.remove body cannot be called when the world is locked and in the middle of number crunching such as during a collision event. I guess I don’t know what makes the roof/ceiling one sided. [import]uid: 132937 topic_id: 36215 reply_id: 143937[/import]