Removing Physics Off Screen

Hello there fellow developers,

This was a thread I started before but have lost the means of finding the post again

I was just wondering if it’s possible to remove an objects physics when off screen as I’m working up a sandbox game and require a large amount of objects to be on and off screen so I require to be able to make them active on screen and inactive offscreen…

Brent Sorrentino was a helper before hand but I now have no means of messaging him personally for some reason

Hi @jazzarssoul,

I can help you with this further. Can you post the current code that you’ve got in place now? I know we discussed various options like the usage of a screen-sized collision sensor that “follows” the player around as it moves around a bigger, scrolling world. If I recall, that was the latest potential solution, and hopefully you were able to test it out. If I (and others) can see your code, I think we can figure it out and put a nail in this. :slight_smile:

Thanks!

Brent

I kinda stumbled on the exact result I needed after trying to understand localToContent and contentToLocal.  I’ll be honest, I still don’t know the difference, but this code works swimmingly in my game, so I’m happy.

What’s great is that localToContent( 0, 0 ) gives the exact screen coordinates of the enemy, regardless if you’ve added it to some super-sized display group that you’re panning and zooming in/out with a virtual camera.  If it’s determining whether or not it’s on the actual physical screen that you care about, then the code below is what you might be looking for.

local enemyX, enemyY = enemy.localToContent( 0, 0 ) if ( enemyX \< 0 or enemyX \> display.contentWidth or enemyY \< 0 or enemyY \> display.contentHeight ) then -- enemy is off the screen else -- enemy is viewable by player end

Hey there fellow fellas,

here is the code that we’ve devised

<lua>

local Hero=display.newRect(0,0,heroSize,heroSize)

physics.addBody(Hero, “dynamic”,{density=5, bounce=0.1,friction=1})

Hero.x=guyXRand*blockSize-blockSize/2

    

physicsBox=display.newRect(0,0,display.contentWidth, display.contentHeight)

physicsBox.alpha=0.3

    

local function hitTestObjects(obj1, obj2)

    return obj1.contentBounds.xMin < obj2.contentBounds.xMax

        and obj1.contentBounds.xMax > obj2.contentBounds.xMin

        and obj1.contentBounds.yMin < obj2.contentBounds.yMax

        and obj1.contentBounds.yMax > obj2.contentBounds.yMin

end

    

function collisionCheck(obj)

    if hitTestObjects(physicsBox, obj) then

        physics.addBody(obj, “static”,{friction=1})

    else

        physics.removeBody(obj)            

    end

end

</lua>

basically by following that up we have a person placed over several individual boxes that require on and off collisions

I haven’t tried your method yet beyondTheTech I figured I’d go by Brents idea first and post the code we’ve got currently running

as you can see

-We have a player that moves

-a physics box that follows the player exactly

-we have a collision tester identifying in the function that the check will be between the individual blocks and the physics box

  • and the collisionCheck(obj) function is identifying which blocks require physics and which don’t

so BeyondTheTech you’re suggesting that using your method has helped with your app flawlessly? and with what you have suggested it could just be a matter of saying

–if they are in these bounds

make objects have physics

–if outside bounds

remove physics

does this work in the sense that if you were to have the player move around changing the group.x and y to follow the player that the content bounds will still work flawlessly?

Yes.  Take my current game, for example.  I have a space ship flying around a 5000x5000 grid.  I’m using the perspective.lua found in Code Exchange, and I have it focusing on the player at all times.

At closest zoom range, I’m seeing 960x640 pixel-for-pixel.  When I zoom out all the way, I see upwards of 3840x2160 worth of the grid crushed in my iPhone 5 display.

Depending on the range, some of the player’s enemies and obstacles are in view, some are out of view.  Using that localToContent function, I can quickly determine if the enemy or obstacle is within the gamer’s view and adjust the physics or change the gameplay accordingly.  One of the things I do is have an “outside view indicator” that points in the direction of an enemy.  I have it instantly showing up when an enemy leaves the view, and I turn it off when he is visible on the screen, regardless of the zoom level.

Prior to learning about localToContent, I was doing all sorts of calculations to figure out if the enemy was really in view by means of getting the position of the player, finding out the distance to the horizontal and vertical edges of the screen, divided by the zoomScale (at 1:1 scale, the distance from the player to the left/right edges of the screen was 480 pixels and to the top/bottom edges of the screen was 320 pixels, but at 0.5:0.5 scale, it was 960 and 640, and at 0.2:0.2, it was 2400 and 1600, etc.), and then calculate if the enemy’s X and Y distances were less than that amount, he must be in view.  It was taxing on the CPU at every frame, but this function happily took that all out.

Hi @jazzarssoul,

I can help you with this further. Can you post the current code that you’ve got in place now? I know we discussed various options like the usage of a screen-sized collision sensor that “follows” the player around as it moves around a bigger, scrolling world. If I recall, that was the latest potential solution, and hopefully you were able to test it out. If I (and others) can see your code, I think we can figure it out and put a nail in this. :slight_smile:

Thanks!

Brent

I kinda stumbled on the exact result I needed after trying to understand localToContent and contentToLocal.  I’ll be honest, I still don’t know the difference, but this code works swimmingly in my game, so I’m happy.

What’s great is that localToContent( 0, 0 ) gives the exact screen coordinates of the enemy, regardless if you’ve added it to some super-sized display group that you’re panning and zooming in/out with a virtual camera.  If it’s determining whether or not it’s on the actual physical screen that you care about, then the code below is what you might be looking for.

local enemyX, enemyY = enemy.localToContent( 0, 0 ) if ( enemyX \< 0 or enemyX \> display.contentWidth or enemyY \< 0 or enemyY \> display.contentHeight ) then -- enemy is off the screen else -- enemy is viewable by player end

Hey there fellow fellas,

here is the code that we’ve devised

<lua>

local Hero=display.newRect(0,0,heroSize,heroSize)

physics.addBody(Hero, “dynamic”,{density=5, bounce=0.1,friction=1})

Hero.x=guyXRand*blockSize-blockSize/2

    

physicsBox=display.newRect(0,0,display.contentWidth, display.contentHeight)

physicsBox.alpha=0.3

    

local function hitTestObjects(obj1, obj2)

    return obj1.contentBounds.xMin < obj2.contentBounds.xMax

        and obj1.contentBounds.xMax > obj2.contentBounds.xMin

        and obj1.contentBounds.yMin < obj2.contentBounds.yMax

        and obj1.contentBounds.yMax > obj2.contentBounds.yMin

end

    

function collisionCheck(obj)

    if hitTestObjects(physicsBox, obj) then

        physics.addBody(obj, “static”,{friction=1})

    else

        physics.removeBody(obj)            

    end

end

</lua>

basically by following that up we have a person placed over several individual boxes that require on and off collisions

I haven’t tried your method yet beyondTheTech I figured I’d go by Brents idea first and post the code we’ve got currently running

as you can see

-We have a player that moves

-a physics box that follows the player exactly

-we have a collision tester identifying in the function that the check will be between the individual blocks and the physics box

  • and the collisionCheck(obj) function is identifying which blocks require physics and which don’t

so BeyondTheTech you’re suggesting that using your method has helped with your app flawlessly? and with what you have suggested it could just be a matter of saying

–if they are in these bounds

make objects have physics

–if outside bounds

remove physics

does this work in the sense that if you were to have the player move around changing the group.x and y to follow the player that the content bounds will still work flawlessly?

Yes.  Take my current game, for example.  I have a space ship flying around a 5000x5000 grid.  I’m using the perspective.lua found in Code Exchange, and I have it focusing on the player at all times.

At closest zoom range, I’m seeing 960x640 pixel-for-pixel.  When I zoom out all the way, I see upwards of 3840x2160 worth of the grid crushed in my iPhone 5 display.

Depending on the range, some of the player’s enemies and obstacles are in view, some are out of view.  Using that localToContent function, I can quickly determine if the enemy or obstacle is within the gamer’s view and adjust the physics or change the gameplay accordingly.  One of the things I do is have an “outside view indicator” that points in the direction of an enemy.  I have it instantly showing up when an enemy leaves the view, and I turn it off when he is visible on the screen, regardless of the zoom level.

Prior to learning about localToContent, I was doing all sorts of calculations to figure out if the enemy was really in view by means of getting the position of the player, finding out the distance to the horizontal and vertical edges of the screen, divided by the zoomScale (at 1:1 scale, the distance from the player to the left/right edges of the screen was 480 pixels and to the top/bottom edges of the screen was 320 pixels, but at 0.5:0.5 scale, it was 960 and 640, and at 0.2:0.2, it was 2400 and 1600, etc.), and then calculate if the enemy’s X and Y distances were less than that amount, he must be in view.  It was taxing on the CPU at every frame, but this function happily took that all out.

where can I get my hand on finding this perspective.lua business? I try searching up things to find in the search bar and come up with no results

Here you go. http://developer.coronalabs.com/code/perspective

thank you for the link provided Tech,

I’ve implemented this concept in a side project to fully grasp the understanding here and came across in the comments someone has devised up a pointToZoom function.

I have the camera following crate.x and y in the physics based game sample and the camera follows fine.

I’ve used the pointToZoom function straight up in runtime and it zooms to the crate just fine then the crate drops as there is a delay.
I’ve now since then created 2 buttons, one for zooming in and one for zooming out. however when I zoom in it zooms in to to the top left corner no longer following the crates position anymore. continuing to zoom in it now zooms to bottom right (still not following the crate)

here’s what I’ve devised:

[lua]


– level1.lua


local storyboard = require( “storyboard” )

local scene = storyboard.newScene()

local perspective = require(“perspective”)

– include Corona’s “physics” library

local physics = require “physics”

physics.start(); physics.pause()


– forward declarations and other locals

local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth*0.5


– BEGINNING OF YOUR IMPLEMENTATION

– 

– NOTE: Code outside of listener functions (below) will only be executed once,

–         unless storyboard.removeScene() is called.

– 


– Called when the scene’s view does not exist:

function scene:createScene( event )

    local group = self.view

    – creating a camera

    local camera = perspective.createView()

    camera.x, camera.y = 0,0

    

    – create a grey rectangle as the backdrop

    local background = display.newRect( 0, 0, screenW, screenH )

    background:setFillColor( 128 )

    camera:add(background, 8, false)

    

    – make a crate (off-screen), position it, and rotate slightly

    local crate = display.newImageRect( “crate.png”, 90, 90 )

    crate.x, crate.y = 160, -100

    crate.rotation = 15

    

    – add physics to the crate

    physics.addBody( crate, { density=1.0, friction=0.3, bounce=0.3 } )

    camera:add(crate, 1, true)

    – create a grass object and add physics (with custom shape)

    local grass = display.newImageRect( “grass.png”, screenW, 82 )

    grass:setReferencePoint( display.BottomLeftReferencePoint )

    grass.x, grass.y = 0, display.contentHeight

    

    – define a shape that’s slightly shorter than image bounds (set draw mode to “hybrid” or “debug” to see)

    local grassShape = { -halfW,-34, halfW,-34, halfW,34, -halfW,34 }

    physics.addBody( grass, “static”, { friction=0.3, shape=grassShape } )

    camera:add(grass, 2, false)

    – all display objects must be inserted into group

    

    camera.damping = 0

    

    – 1 is default zoom

    zAmount = 1

    

    local zoomOut = display.newRect(15, 25, 25, 25)

    

    function zMinus()

        zAmount = zAmount / 1.1

        

        camera:pointAndZoom(camera.x, camera.y, zAmount, 500, function() print(zAmount) end, nil)

        

    end

    

    zoomOut:addEventListener(“tap”, zMinus)

    local zoomIn = display.newRect(40, 25, 25, 25)

    

    function zPlus()

        zAmount = zAmount * 1.1

        camera:pointAndZoom(camera.x, camera.y, zAmount, 500, function() print(zAmount) end, nil)

    end

    zoomIn:addEventListener(“tap”, zPlus)

    

    

    camera:track()

    

    

    --Params:

    --x - number, the x of the point

    --y - number, the y of the point

    --xScale and yScale, assumes aspect ratio is locked

    --time - number, how long it takes to get to the point

    --onComplete - function, what happens when it’s at the point

    --ease - function, the easing effect for the transition

end

– Called immediately after scene has moved onscreen:

function scene:enterScene( event )

    local group = self.view

    

    physics.start()

    

end

– Called when scene is about to move offscreen:

function scene:exitScene( event )

    local group = self.view

    

    physics.stop()

    

end

– If scene’s view is removed, scene:destroyScene() will be called just prior to:

function scene:destroyScene( event )

    local group = self.view

    

    package.loaded[physics] = nil

    physics = nil

end


– END OF YOUR IMPLEMENTATION


– “createScene” event is dispatched if scene’s view does not exist

scene:addEventListener( “createScene”, scene )

– “enterScene” event is dispatched whenever scene transition has finished

scene:addEventListener( “enterScene”, scene )

– “exitScene” event is dispatched whenever before next scene’s transition begins

scene:addEventListener( “exitScene”, scene )

– “destroyScene” event is dispatched before view is unloaded, which can be

– automatically unloaded in low memory situations, or explicitly via a call to

– storyboard.purgeScene() or storyboard.removeScene().

scene:addEventListener( “destroyScene”, scene )


return scene

[/lua]

and this is the pointToZoom function provided by comments that is required to go in the perspective.lua file (I assume you are familiar with)

[lua]

–point and zoom

    function view:pointAndZoom(x, y, zoom, time, onComplete, t)

     local x=x or display.contentWidth/2

     local y=y or display.contentHeight/2

     local zoom=zoom or 1

     local time=time or 1000

     local onComplete=onComplete or nil

     local t=t or nil

[/lua]

long story short, how have you sorted out a zoom in function that focuses on the player?

where can I get my hand on finding this perspective.lua business? I try searching up things to find in the search bar and come up with no results

Here you go. http://developer.coronalabs.com/code/perspective

thank you for the link provided Tech,

I’ve implemented this concept in a side project to fully grasp the understanding here and came across in the comments someone has devised up a pointToZoom function.

I have the camera following crate.x and y in the physics based game sample and the camera follows fine.

I’ve used the pointToZoom function straight up in runtime and it zooms to the crate just fine then the crate drops as there is a delay.
I’ve now since then created 2 buttons, one for zooming in and one for zooming out. however when I zoom in it zooms in to to the top left corner no longer following the crates position anymore. continuing to zoom in it now zooms to bottom right (still not following the crate)

here’s what I’ve devised:

[lua]


– level1.lua


local storyboard = require( “storyboard” )

local scene = storyboard.newScene()

local perspective = require(“perspective”)

– include Corona’s “physics” library

local physics = require “physics”

physics.start(); physics.pause()


– forward declarations and other locals

local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth*0.5


– BEGINNING OF YOUR IMPLEMENTATION

– 

– NOTE: Code outside of listener functions (below) will only be executed once,

–         unless storyboard.removeScene() is called.

– 


– Called when the scene’s view does not exist:

function scene:createScene( event )

    local group = self.view

    – creating a camera

    local camera = perspective.createView()

    camera.x, camera.y = 0,0

    

    – create a grey rectangle as the backdrop

    local background = display.newRect( 0, 0, screenW, screenH )

    background:setFillColor( 128 )

    camera:add(background, 8, false)

    

    – make a crate (off-screen), position it, and rotate slightly

    local crate = display.newImageRect( “crate.png”, 90, 90 )

    crate.x, crate.y = 160, -100

    crate.rotation = 15

    

    – add physics to the crate

    physics.addBody( crate, { density=1.0, friction=0.3, bounce=0.3 } )

    camera:add(crate, 1, true)

    – create a grass object and add physics (with custom shape)

    local grass = display.newImageRect( “grass.png”, screenW, 82 )

    grass:setReferencePoint( display.BottomLeftReferencePoint )

    grass.x, grass.y = 0, display.contentHeight

    

    – define a shape that’s slightly shorter than image bounds (set draw mode to “hybrid” or “debug” to see)

    local grassShape = { -halfW,-34, halfW,-34, halfW,34, -halfW,34 }

    physics.addBody( grass, “static”, { friction=0.3, shape=grassShape } )

    camera:add(grass, 2, false)

    – all display objects must be inserted into group

    

    camera.damping = 0

    

    – 1 is default zoom

    zAmount = 1

    

    local zoomOut = display.newRect(15, 25, 25, 25)

    

    function zMinus()

        zAmount = zAmount / 1.1

        

        camera:pointAndZoom(camera.x, camera.y, zAmount, 500, function() print(zAmount) end, nil)

        

    end

    

    zoomOut:addEventListener(“tap”, zMinus)

    local zoomIn = display.newRect(40, 25, 25, 25)

    

    function zPlus()

        zAmount = zAmount * 1.1

        camera:pointAndZoom(camera.x, camera.y, zAmount, 500, function() print(zAmount) end, nil)

    end

    zoomIn:addEventListener(“tap”, zPlus)

    

    

    camera:track()

    

    

    --Params:

    --x - number, the x of the point

    --y - number, the y of the point

    --xScale and yScale, assumes aspect ratio is locked

    --time - number, how long it takes to get to the point

    --onComplete - function, what happens when it’s at the point

    --ease - function, the easing effect for the transition

end

– Called immediately after scene has moved onscreen:

function scene:enterScene( event )

    local group = self.view

    

    physics.start()

    

end

– Called when scene is about to move offscreen:

function scene:exitScene( event )

    local group = self.view

    

    physics.stop()

    

end

– If scene’s view is removed, scene:destroyScene() will be called just prior to:

function scene:destroyScene( event )

    local group = self.view

    

    package.loaded[physics] = nil

    physics = nil

end


– END OF YOUR IMPLEMENTATION


– “createScene” event is dispatched if scene’s view does not exist

scene:addEventListener( “createScene”, scene )

– “enterScene” event is dispatched whenever scene transition has finished

scene:addEventListener( “enterScene”, scene )

– “exitScene” event is dispatched whenever before next scene’s transition begins

scene:addEventListener( “exitScene”, scene )

– “destroyScene” event is dispatched before view is unloaded, which can be

– automatically unloaded in low memory situations, or explicitly via a call to

– storyboard.purgeScene() or storyboard.removeScene().

scene:addEventListener( “destroyScene”, scene )


return scene

[/lua]

and this is the pointToZoom function provided by comments that is required to go in the perspective.lua file (I assume you are familiar with)

[lua]

–point and zoom

    function view:pointAndZoom(x, y, zoom, time, onComplete, t)

     local x=x or display.contentWidth/2

     local y=y or display.contentHeight/2

     local zoom=zoom or 1

     local time=time or 1000

     local onComplete=onComplete or nil

     local t=t or nil

[/lua]

long story short, how have you sorted out a zoom in function that focuses on the player?