Dynamic Object Sometimes Sticks to Static Wall

I have gravity (-9.8, 0). There is a dynamic object that when it hits the right wall, (a static line), about 5% of the time will stick to it. It then ignores the gravity, and nothing I do in the code seems to resolve this. 

I’ve tried checking if the object is awake, reseting the gravity, checking to make sure that the event causing the rightward movement has stopped…

Any suggestions on how to fix this?

Hi @robertsonmdavid,

There’s no logical reason why it should be doing this, but we’d have to see some of your code to determine what’s going on. It’s probably a very simple fix… we just don’t know what you’ve programmed.

Best regards,

Brent

I tried to trim it down a bit. I think this is the offending code.

[lua]

local composer = require( “composer” )

local scene = composer.newScene()

– include Corona’s “physics” library

local physics = require “physics”

local surrey=nil

local leftWall

local rightWall

local function applyMovementLoop ()

surrey:applyLinearImpulse(.005,0)

end

function movement (event)

if event.phase == “began” then

moveLoopTimer = timer.performWithDelay( 10, applyMovementLoop, 0 )

elseif event.phase == “ended” or event.phase == “cancelled”  then

timer.cancel( moveLoopTimer )

end

return true

end

function scene:create( event )

local sceneGroup = self.view

physics.start()

physics.setGravity( -9.8, 0 )

physics.pause()

surrey= display.newImageRect(sceneGroup, “surrey.png”, 60,75)

surrey.x= halfW

surrey.y=screenH-100

physics.addBody( surrey,“dynamic”, {radius=22, bounce=0, } )

surrey.myName=“surrey”

surrey.isFixedRotation=true

surrey:setLinearVelocity(0,0)

leftWall = display.newLine(sceneGroup,10,0,10, display.contentHeight )

rightWall = display.newLine (sceneGroup,display.contentWidth-10, 0, display.contentWidth-10, display.contentHeight)

–leftWall.alpha=0

–rightWall.alpha=0

physics.addBody (leftWall, “static”, { bounce = 0} )

physics.addBody (rightWall, “static”, { bounce = 0} )

end

function scene:show( event )

local sceneGroup = self.view

local phase = event.phase

if phase == “will” then

elseif phase == “did” then

physics.start()

physics.setGravity(-9.8,0)

surrey:setLinearVelocity(0,0)

surrey.y=screenH-100

Runtime:addEventListener(“touch”, movement)

end

end

[/lua]

Hmmm… can you try changing the walls from “newLine” objects to very thin rectangles (display.newRect())? There have historically been issues when using physics on “line” objects and I generally don’t recommend doing so (there are other potential reasons why not to, as well).

Brent

The thicker the wall the better.

You can also set your object “isBullet” setting to true.  *This is processor intensive so use sparingly.

[lua]

object.isBullet = true

[/lua]

 That forces the physics engine to check for collisions continuously.

The problem isn’t with the collision detection; it’s doing a good job with this. It’s also registering all of the taps and releases, and calling the appropriate methods at the correct time. The problem is that for some reason gravity stops impacting the object after it hits the wall about 5%of the time. I tried making thick walls, it doesn’t change this. I also tried changing the lines to rectangles using this code:

[lua]leftWall = display.newRect(sceneGroup,10,display.contentHeight/2,1, display.contentHeight )

rightWall = display.newRect(sceneGroup,display.contentWidth-10, display.contentHeight/2, 1, display.contentHeight)[/lua]

I believe I’ve fixed the problem, although i’m not entirely sure why this works. I noticed that touching the screen again unsticks the object from the wall, so I now check on release if the object is touching the right wall. If it is, then I make a touch event happen immediately so that the object doesn’t have a chance to stick, but the user doesn’t notice that anything unusual happened.

Hi @robertsonmdavid,

If I look at your game logic (assuming you haven’t changed it radically since the earlier post), it looks like the user can continue holding down the touch point and the timer will forever run, pushing the object to the right with little impulses. Is that the behavior you want? Because in theory somebody could just keep holding down and the object would just keep getting pushed up against the wall until they let the touch go.

If you want that action to basically stop when the object collides with the wall, you should just cancel the timer upon collision “began”.

Best regards,

Brent

Yeah, that’s the behavior I was looking for. I want the user to be able to stay on the wall if they hold down the press, and come off of the wall again if they release. It does this correctly most of the time, but every once in a while stays on the wall even when the release processes correctly. Though kind of a rough patch, the method I spoke about earlier seemed to fix it.

Hi @robertsonmdavid,

There’s no logical reason why it should be doing this, but we’d have to see some of your code to determine what’s going on. It’s probably a very simple fix… we just don’t know what you’ve programmed.

Best regards,

Brent

I tried to trim it down a bit. I think this is the offending code.

[lua]

local composer = require( “composer” )

local scene = composer.newScene()

– include Corona’s “physics” library

local physics = require “physics”

local surrey=nil

local leftWall

local rightWall

local function applyMovementLoop ()

surrey:applyLinearImpulse(.005,0)

end

function movement (event)

if event.phase == “began” then

moveLoopTimer = timer.performWithDelay( 10, applyMovementLoop, 0 )

elseif event.phase == “ended” or event.phase == “cancelled”  then

timer.cancel( moveLoopTimer )

end

return true

end

function scene:create( event )

local sceneGroup = self.view

physics.start()

physics.setGravity( -9.8, 0 )

physics.pause()

surrey= display.newImageRect(sceneGroup, “surrey.png”, 60,75)

surrey.x= halfW

surrey.y=screenH-100

physics.addBody( surrey,“dynamic”, {radius=22, bounce=0, } )

surrey.myName=“surrey”

surrey.isFixedRotation=true

surrey:setLinearVelocity(0,0)

leftWall = display.newLine(sceneGroup,10,0,10, display.contentHeight )

rightWall = display.newLine (sceneGroup,display.contentWidth-10, 0, display.contentWidth-10, display.contentHeight)

–leftWall.alpha=0

–rightWall.alpha=0

physics.addBody (leftWall, “static”, { bounce = 0} )

physics.addBody (rightWall, “static”, { bounce = 0} )

end

function scene:show( event )

local sceneGroup = self.view

local phase = event.phase

if phase == “will” then

elseif phase == “did” then

physics.start()

physics.setGravity(-9.8,0)

surrey:setLinearVelocity(0,0)

surrey.y=screenH-100

Runtime:addEventListener(“touch”, movement)

end

end

[/lua]

Hmmm… can you try changing the walls from “newLine” objects to very thin rectangles (display.newRect())? There have historically been issues when using physics on “line” objects and I generally don’t recommend doing so (there are other potential reasons why not to, as well).

Brent

The thicker the wall the better.

You can also set your object “isBullet” setting to true.  *This is processor intensive so use sparingly.

[lua]

object.isBullet = true

[/lua]

 That forces the physics engine to check for collisions continuously.

The problem isn’t with the collision detection; it’s doing a good job with this. It’s also registering all of the taps and releases, and calling the appropriate methods at the correct time. The problem is that for some reason gravity stops impacting the object after it hits the wall about 5%of the time. I tried making thick walls, it doesn’t change this. I also tried changing the lines to rectangles using this code:

[lua]leftWall = display.newRect(sceneGroup,10,display.contentHeight/2,1, display.contentHeight )

rightWall = display.newRect(sceneGroup,display.contentWidth-10, display.contentHeight/2, 1, display.contentHeight)[/lua]

I believe I’ve fixed the problem, although i’m not entirely sure why this works. I noticed that touching the screen again unsticks the object from the wall, so I now check on release if the object is touching the right wall. If it is, then I make a touch event happen immediately so that the object doesn’t have a chance to stick, but the user doesn’t notice that anything unusual happened.

Hi @robertsonmdavid,

If I look at your game logic (assuming you haven’t changed it radically since the earlier post), it looks like the user can continue holding down the touch point and the timer will forever run, pushing the object to the right with little impulses. Is that the behavior you want? Because in theory somebody could just keep holding down and the object would just keep getting pushed up against the wall until they let the touch go.

If you want that action to basically stop when the object collides with the wall, you should just cancel the timer upon collision “began”.

Best regards,

Brent

Yeah, that’s the behavior I was looking for. I want the user to be able to stay on the wall if they hold down the press, and come off of the wall again if they release. It does this correctly most of the time, but every once in a while stays on the wall even when the release processes correctly. Though kind of a rough patch, the method I spoke about earlier seemed to fix it.