physics makes my hero never stand still.

Hi,

i have a little man walking at the bottom of the screen using physics and gravity. when he goes left i detect the position change and make him face left. if he goes right i make him face right. but if he stay immobile i want to show him standing them staring at the user.

because there is a fine line between left and right when the phone is straight i’ve put a timer that if it stops it will wait 3seconds (for testing) before going left or right again. it also display a msg 'waiting…"

it works fine on the simulator but on the device (Notes 8) it never ever NOT MOVE even if i dont touch the phone. so he keeps flipping between facing left and facing right.

is that a setting in physics ? 

How are you detecting if he’s moving or not? Maybe share that code with us?  

Don’t forget to use the blue <> button and copy/paste your code into the popup window.

Rob

function scene:create( event ) local sceneGroup = self.view -- init physics physics = require("physics") physics.start() physics.setDrawMode("hybrid") -- ( "hybrid") --"normal") "debug" -- load the physics data, scale factor is set to 1.0 physicsData = (require "charphys").physicsData(0.12) -- 0.15 -- create background image, buttons etc.. -- .. -- show character sheetInfo = require("char"..whichchar.."-menu") myImageSheet = graphics.newImageSheet( "assets/char"..whichchar.."-menu.png", sheetInfo:getSheet() ) sequenceData2 = { { name = "char"..whichchar, sheet=myImageSheet, frames={4,1,2,3,5,6,7}, time=1000, loopCount=0 } } char\_chosen = display.newSprite( myImageSheet, sequenceData2 ) char\_chosen.xScale = 0.2 ; char\_chosen.yScale = 0.2 char\_chosen.xScaleOrig = char\_chosen.xScale char\_chosen.xDir = "L" -- if the sprite is turned Left to start with. else "R" char\_chosen.yDir = "U" -- f the sprite is turned Left to start with. else "U" char\_chosen.x = display.contentCenterX ; char\_chosen.y = bottomline\_bot.y - char\_chosen.height /2 char\_chosen.prevX = char\_chosen.x ; char\_chosen.prevY = char\_chosen.y sceneGroup:insert( char\_chosen ) char\_chosen.alpha = 100 char\_chosen:setSequence("char"..whichchar ) char\_chosen:setFrame( 1 ) char\_chosen:toFront() -- if running on simulator comment out the physic.addBody below as accelerometer doesnt work. -- you can then drag the hero to test physics.addBody(char\_chosen,physicsData:get("char1phys")) char\_chosen.x = display.contentCenterX ; char\_chosen.y = 200 char\_chosen:play() char\_chosen.paused = false char\_chosen:addEventListener("touch",char\_chosen) -- text "waiting .." (for testing..) textW = display.newText( "waiting..", 0, 0, native.systemFontBold, 20 ) textW.x = 120; textW.y = 200 textW:setFillColor( 0, 0, 0 ) textW.alpha = 0 sceneGroup:insert( textW ) function char\_chosen:touch(event) if event.phase == "began" then self.markX = self.x -- store x location of object self.markY = self.y -- store x location of object elseif event.phase == "moved" then local x = (event.x - event.xStart) + self.markX local y = (event.y - event.yStart) + self.markY self.x, self.y = x,y -- move object based on calculations above end return true end local function heroMovex( event ) char\_chosen:setLinearVelocity( 750 \* event.xGravity, -500 \* event.yGravity ) end Runtime:addEventListener("accelerometer", heroMovex) end -- scene:create function scene:show( event ) local phase = event.phase if "will" == phase then Runtime:addEventListener("enterFrame",everyframe) Runtime:addEventListener("accelerometer", onaccelerate) elseif "did" == phase then local previous\_scene = composer.getSceneName("previous") if (previous\_scene == nil) then else composer.removeScene( previous\_scene ,false) end else print( "2: show event, phase ?",phase ) end end -- scene:show function everyframe() function noMoreWaiting(event) waitingStanding = false print "here is noMoreWaiting timer" textW.alpha = 0 end if waitingStanding == true then return true end -- we check that it's close to the ground (any ground line). also check that -- that the orientation of the hero matches where ever it's going and whatever the orientation of the screen -- local vx, vy = char\_chosen:getLinearVelocity() -- --print ("is char\_chosen.paused \>",char\_chosen.paused,"\<vx\>",vx,"\<vy\>",vy) -- if (math.abs(vx) == 0 and math.abs(vy) == 0) and char\_chosen.paused == false then -- note: on the device the velocity is never zero (or never stay at zero) if (char\_chosen.x == char\_chosen.prevX ) and (char\_chosen.y == char\_chosen.prevY) then char\_chosen:pause() char\_chosen:setFrame( 2 ) -- standing char\_chosen.paused = true waitingStanding = true local tm = timer.performWithDelay(3000, noMoreWaiting) print ("char\_chosen.pausing\>",char\_chosen.paused,"\<vx\>",vx,"\<vy\>",vy) textW.alpha = 1 elseif (char\_chosen.x \> 0 and char\_chosen.x \< w) and (char\_chosen.y \> 0 and char\_chosen.y \> h - 100 ) then if charCurrentOrientation ~= 0 then -- bottom char\_chosen.rotation = 0 charCurrentOrientation = 0 end if (char\_chosen.x \> char\_chosen.prevX) and char\_chosen.xDir ~= "R" then char\_chosen.xScale = char\_chosen.xScaleOrig \* -1 -- force him to look Right char\_chosen.xDir = "R" elseif (char\_chosen.x \< char\_chosen.prevX) and char\_chosen.xDir ~= "L" then char\_chosen.xScale = char\_chosen.xScaleOrig -- force him to look left char\_chosen.xDir = "L" end if char\_chosen.paused == true then char\_chosen:play() char\_chosen.paused = false end else end char\_chosen.prevX = char\_chosen.x ; char\_chosen.prevY = char\_chosen.y end -- everyframe function onaccelerate(event) -- Gravity is in portrait orientation on Android, iOS, and Windows Phone -- On tvOS, gravity is in the orientation of the device attached to the event if ( event.device ) then physics.setGravity( ( 9.8 \* event.xGravity ), ( -9.8 \* event.yGravity ) ) else physics.setGravity( ( -9.8 \* event.yGravity ), ( -9.8 \* event.xGravity ) ) end end -- onaccelerate --------------------------------------------------------------

Hi Rob,

here it is, I’ve included the create_scene and show_scene in case the problem sits there. But basically i detect the movement in the everyframe function. as you will see (commented out) i’ve first tried to detect it with getLinearVelocity but couldnt never get it to zero either.

so i thought i’m gonna force it to wait half a second (3 seconds to test) once it gets through a standstill but it never does on the device.

On the simulator it does work (I have added a touch listener so i can test the ‘facing left or right’ on the simulator)  but of course the accelerometer doesnt work on the simulator.

thanks !

If you want your physics object (character) to come to rest,

  1. Remove all or nearly all bounce (bounce == 0 or at least close to zero)

https://docs.coronalabs.com/api/library/physics/addBody.html#params-optional

  1. Consider adding friction to the player and any bodies you wish it to slow upon.

https://docs.coronalabs.com/api/library/physics/addBody.html#params-optional

  1. Set linear damping above zero.

https://docs.coronalabs.com/api/type/Body/linearDamping.html
 

thanks roaminggamer but no luck.

bounce is already 0, i’ve put a linearDamping = 5 (as per example) and bumped up the friction from 0.5 to 1 but it’s still the same.

note: it’s not that my hero bounce (he doesnt) but that he flips left to right and back many times per second. And when visually he doesnt move left or right when the device is in a centre position, programmatically the x,y coordinate are never the same as the previous ones. Even if I keep the device perfectly still in a center position. (like without touching it at all)

What sort of values are you getting? Close to zero or strange, large values? If close to zero then just use math.floor and tiny movements will evaluate to zero.

but of course … instead of checking if (diffX == 0 and diffY == 0)  I had to do

if math.floor(math.abs(char_chosen.prevX - char_chosen.x )) == 0 and math.floor(math.abs(char_chosen.prevY -  char_chosen.y)) == 0  then

just getting back into corona after more than a year and still a bit sleepy …

thank you all !

How are you detecting if he’s moving or not? Maybe share that code with us?  

Don’t forget to use the blue <> button and copy/paste your code into the popup window.

Rob

function scene:create( event ) local sceneGroup = self.view -- init physics physics = require("physics") physics.start() physics.setDrawMode("hybrid") -- ( "hybrid") --"normal") "debug" -- load the physics data, scale factor is set to 1.0 physicsData = (require "charphys").physicsData(0.12) -- 0.15 -- create background image, buttons etc.. -- .. -- show character sheetInfo = require("char"..whichchar.."-menu") myImageSheet = graphics.newImageSheet( "assets/char"..whichchar.."-menu.png", sheetInfo:getSheet() ) sequenceData2 = { { name = "char"..whichchar, sheet=myImageSheet, frames={4,1,2,3,5,6,7}, time=1000, loopCount=0 } } char\_chosen = display.newSprite( myImageSheet, sequenceData2 ) char\_chosen.xScale = 0.2 ; char\_chosen.yScale = 0.2 char\_chosen.xScaleOrig = char\_chosen.xScale char\_chosen.xDir = "L" -- if the sprite is turned Left to start with. else "R" char\_chosen.yDir = "U" -- f the sprite is turned Left to start with. else "U" char\_chosen.x = display.contentCenterX ; char\_chosen.y = bottomline\_bot.y - char\_chosen.height /2 char\_chosen.prevX = char\_chosen.x ; char\_chosen.prevY = char\_chosen.y sceneGroup:insert( char\_chosen ) char\_chosen.alpha = 100 char\_chosen:setSequence("char"..whichchar ) char\_chosen:setFrame( 1 ) char\_chosen:toFront() -- if running on simulator comment out the physic.addBody below as accelerometer doesnt work. -- you can then drag the hero to test physics.addBody(char\_chosen,physicsData:get("char1phys")) char\_chosen.x = display.contentCenterX ; char\_chosen.y = 200 char\_chosen:play() char\_chosen.paused = false char\_chosen:addEventListener("touch",char\_chosen) -- text "waiting .." (for testing..) textW = display.newText( "waiting..", 0, 0, native.systemFontBold, 20 ) textW.x = 120; textW.y = 200 textW:setFillColor( 0, 0, 0 ) textW.alpha = 0 sceneGroup:insert( textW ) function char\_chosen:touch(event) if event.phase == "began" then self.markX = self.x -- store x location of object self.markY = self.y -- store x location of object elseif event.phase == "moved" then local x = (event.x - event.xStart) + self.markX local y = (event.y - event.yStart) + self.markY self.x, self.y = x,y -- move object based on calculations above end return true end local function heroMovex( event ) char\_chosen:setLinearVelocity( 750 \* event.xGravity, -500 \* event.yGravity ) end Runtime:addEventListener("accelerometer", heroMovex) end -- scene:create function scene:show( event ) local phase = event.phase if "will" == phase then Runtime:addEventListener("enterFrame",everyframe) Runtime:addEventListener("accelerometer", onaccelerate) elseif "did" == phase then local previous\_scene = composer.getSceneName("previous") if (previous\_scene == nil) then else composer.removeScene( previous\_scene ,false) end else print( "2: show event, phase ?",phase ) end end -- scene:show function everyframe() function noMoreWaiting(event) waitingStanding = false print "here is noMoreWaiting timer" textW.alpha = 0 end if waitingStanding == true then return true end -- we check that it's close to the ground (any ground line). also check that -- that the orientation of the hero matches where ever it's going and whatever the orientation of the screen -- local vx, vy = char\_chosen:getLinearVelocity() -- --print ("is char\_chosen.paused \>",char\_chosen.paused,"\<vx\>",vx,"\<vy\>",vy) -- if (math.abs(vx) == 0 and math.abs(vy) == 0) and char\_chosen.paused == false then -- note: on the device the velocity is never zero (or never stay at zero) if (char\_chosen.x == char\_chosen.prevX ) and (char\_chosen.y == char\_chosen.prevY) then char\_chosen:pause() char\_chosen:setFrame( 2 ) -- standing char\_chosen.paused = true waitingStanding = true local tm = timer.performWithDelay(3000, noMoreWaiting) print ("char\_chosen.pausing\>",char\_chosen.paused,"\<vx\>",vx,"\<vy\>",vy) textW.alpha = 1 elseif (char\_chosen.x \> 0 and char\_chosen.x \< w) and (char\_chosen.y \> 0 and char\_chosen.y \> h - 100 ) then if charCurrentOrientation ~= 0 then -- bottom char\_chosen.rotation = 0 charCurrentOrientation = 0 end if (char\_chosen.x \> char\_chosen.prevX) and char\_chosen.xDir ~= "R" then char\_chosen.xScale = char\_chosen.xScaleOrig \* -1 -- force him to look Right char\_chosen.xDir = "R" elseif (char\_chosen.x \< char\_chosen.prevX) and char\_chosen.xDir ~= "L" then char\_chosen.xScale = char\_chosen.xScaleOrig -- force him to look left char\_chosen.xDir = "L" end if char\_chosen.paused == true then char\_chosen:play() char\_chosen.paused = false end else end char\_chosen.prevX = char\_chosen.x ; char\_chosen.prevY = char\_chosen.y end -- everyframe function onaccelerate(event) -- Gravity is in portrait orientation on Android, iOS, and Windows Phone -- On tvOS, gravity is in the orientation of the device attached to the event if ( event.device ) then physics.setGravity( ( 9.8 \* event.xGravity ), ( -9.8 \* event.yGravity ) ) else physics.setGravity( ( -9.8 \* event.yGravity ), ( -9.8 \* event.xGravity ) ) end end -- onaccelerate --------------------------------------------------------------

Hi Rob,

here it is, I’ve included the create_scene and show_scene in case the problem sits there. But basically i detect the movement in the everyframe function. as you will see (commented out) i’ve first tried to detect it with getLinearVelocity but couldnt never get it to zero either.

so i thought i’m gonna force it to wait half a second (3 seconds to test) once it gets through a standstill but it never does on the device.

On the simulator it does work (I have added a touch listener so i can test the ‘facing left or right’ on the simulator)  but of course the accelerometer doesnt work on the simulator.

thanks !

If you want your physics object (character) to come to rest,

  1. Remove all or nearly all bounce (bounce == 0 or at least close to zero)

https://docs.coronalabs.com/api/library/physics/addBody.html#params-optional

  1. Consider adding friction to the player and any bodies you wish it to slow upon.

https://docs.coronalabs.com/api/library/physics/addBody.html#params-optional

  1. Set linear damping above zero.

https://docs.coronalabs.com/api/type/Body/linearDamping.html
 

thanks roaminggamer but no luck.

bounce is already 0, i’ve put a linearDamping = 5 (as per example) and bumped up the friction from 0.5 to 1 but it’s still the same.

note: it’s not that my hero bounce (he doesnt) but that he flips left to right and back many times per second. And when visually he doesnt move left or right when the device is in a centre position, programmatically the x,y coordinate are never the same as the previous ones. Even if I keep the device perfectly still in a center position. (like without touching it at all)

What sort of values are you getting? Close to zero or strange, large values? If close to zero then just use math.floor and tiny movements will evaluate to zero.

but of course … instead of checking if (diffX == 0 and diffY == 0)  I had to do

if math.floor(math.abs(char_chosen.prevX - char_chosen.x )) == 0 and math.floor(math.abs(char_chosen.prevY -  char_chosen.y)) == 0  then

just getting back into corona after more than a year and still a bit sleepy …

thank you all !