dragging object too fast

Hello,

i have a problem with the collision detection when the object is moving too fast

require("physics") physics.start() physics.setDrawMode("normal") physics.setGravity(0,0)  local wall  local player  local groupLine = display.newGroup() function onTouch( event )    local target = event.target     local phase = event.phase     if event.phase == "began" then         target.x0 = event.x - target.x         target.y0 = event.y - target.y         target.xStart = target.x         target.yStart = target.y     elseif event.phase == "moved" then              local line = display.newLine( target.x, target.y, event.x,  event.y)         line:setStrokeColor( 1, 1, 1 )         line.strokeWidth = 1         physics.addBody(line, "kinematic", { bounce = 0, density=0 ,friction=10})         line.myname ="player"         line.isSensor = true         groupLine:insert(line)         target.x = event.x - target.x0         target.y = event.y - target.y0      elseif event.phase=="ended"then        target.x, target.y = event.x, event.y               end  return true  end    function onCollision( event )    if(event.other.myname=="player")then    wall:setFillColor(1,0,0)    end  return true  end player = display.newRect( 100, 100, 20, 20 ) player.myname ="player" physics.addBody(player, "dynamic", { bounce = 0, density=1 ,friction=1}) player:addEventListener( "touch", onTouch ) player.isBullet=true wall = display.newRect( 200, 100, 5, 100 ) wall.myname ="wall" wall:setFillColor(0,1,0) physics.addBody(wall, "static", { bounce = 0, density=1 ,friction=1}) wall:addEventListener( "collision", onCollision ) function resetFunction() for i=groupLine.numChildren,1,-1 do display.remove(groupLine[i]) end wall:setFillColor(0,1,0) return true end local reset =   display.newRect( 100, 200, 20, 20 ) reset:addEventListener( "tap", resetFunction )

i tried to use the lines to detect collision better but it dont work.

Hello, Using lines in a collision is a pain… Why don’y you using a newRect? Just make sure it 3 or more pixels thick or the fast objects that collide with it tend to fly right through.

Good Luck!

oh thanks. here is the new version, i changed the touch system because it cant follow the speed well.

require("physics") physics.start() physics.setDrawMode("hybrid") physics.setGravity(0,0) local wall local dontTouchWall local player local activate = false local groupLine = display.newGroup() local noCollision = true function onCollision( event ) if(event.other.myname=="wall")then noCollision = false print("collision") wall:setFillColor(1,0,0) elseif(event.other.myname=="dontTouchWall")then if(noCollision == true)then dontTouchWall:setFillColor(1,0,0) print("dont Touch") end end return true end function onTouch( event ) local target = event.target local phase = event.phase if(activate==true)then if event.phase == "began" then player.x = event.x player.y = event.y elseif event.phase == "moved" then local line = display.newRect( player.x, player.y, 5,5) line:setStrokeColor( 1, 1, 1 ) line.strokeWidth = 1 physics.addBody(line, "dynamic", { bounce = 0, density=0 ,friction=10}) line.myname ="player" line.isSensor = true line:addEventListener( "collision", onCollision ) groupLine:insert(line) player.x = event.x player.y = event.y elseif event.phase=="ended"then player.x, player.y = event.x, event.y end end return true end function activateOnTouch( event ) if ( event.phase == "began" ) then activate = true elseif(event.phase == "ended")then activate=false end return true end player = display.newRect( 100, 100, 20, 20 ) player.myname ="player" --physics.addBody(player, "dynamic", { bounce = 0, density=1 ,friction=1}) player:addEventListener( "touch", activateOnTouch ) player.isBullet=true display.currentStage:addEventListener( "touch", onTouch ) wall = display.newRect( 200, 100, 5, 100 ) wall.myname ="wall" wall:setFillColor(0,1,0) physics.addBody(wall, "static", { bounce = 0, density=1 ,friction=1}) dontTouchWall = display.newRect( 250, 100, 5, 100 ) dontTouchWall.myname ="dontTouchWall" dontTouchWall:setFillColor(0,1,0) physics.addBody(dontTouchWall, "static", { bounce = 0, density=1 ,friction=1}) function resetFunction() for i=groupLine.numChildren,1,-1 do display.remove(groupLine[i]) end wall:setFillColor(0,1,0) return true end local reset = display.newRect( 100, 200, 20, 20 ) reset:addEventListener( "tap", resetFunction )

mmmmmh new problem, i added a wall and now, im trying to make when it collide with the first wall, the object cant collide with the second wall but when it move at high speed, there is a collision with the second wall and then with the first wall.

  1. You can’t expect collisions to work properly if you’re manually updating the position of objects, which is what you’re doing in your touch handler.  That is wrong and will fail as often as it (accidentally) works.

Use a touch joint to drag with instead: https://docs.coronalabs.com/guide/physics/physicsJoints/index.html#touch 

  • The touch tells the joint where to move.

  • The joint moves the body.  This way movement is controlled by physics and the collisions can work

  1. Even then, fast moving objects will penetrate and not collide with thin objects.  So, set the  ‘isBullet’ flag to ‘true’ on the fast moving object, after adding the body.

Example of dragging:

local touchJointForce = 20000 -- == -- dragPart() -- == local function dragPart( self, event ) local phase = event.phase if( phase == "began" ) then display.getCurrentStage():setFocus(self,event.id) self.isFocus = true self.tempJoint = physics.newJoint( "touch", self, self.x, self.y ) self.tempJoint.maxForce = touchJointForce elseif( self.isFocus ) then if( phase == "moved" ) then self.tempJoint:setTarget( event.x, event.y ) elseif( phase == "ended" ) then display.getCurrentStage():setFocus( self, nil ) self.isFocus = false display.remove( self.tempJoint ) end end return true end local function addDragger( obj ) obj.touch = dragPart obj:addEventListener( "touch", obj ) end

Used later like this:

local tmp = display.newCircle( 100, 100, 20 ) physics.addBody( tmp ) tmp.isBullet = true addDragger( tmp )

Now you can touch and drag the circle.

I extracted the above from my Physics Fun examples:

http://github.com/roaminggamer/CoronaGeek/raw/master/Hangouts/ICanMakeThat/PhysicsFun.zip

from a prior Corona Geek Hangout.

thank you

Hello, Using lines in a collision is a pain… Why don’y you using a newRect? Just make sure it 3 or more pixels thick or the fast objects that collide with it tend to fly right through.

Good Luck!

oh thanks. here is the new version, i changed the touch system because it cant follow the speed well.

require("physics") physics.start() physics.setDrawMode("hybrid") physics.setGravity(0,0) local wall local dontTouchWall local player local activate = false local groupLine = display.newGroup() local noCollision = true function onCollision( event ) if(event.other.myname=="wall")then noCollision = false print("collision") wall:setFillColor(1,0,0) elseif(event.other.myname=="dontTouchWall")then if(noCollision == true)then dontTouchWall:setFillColor(1,0,0) print("dont Touch") end end return true end function onTouch( event ) local target = event.target local phase = event.phase if(activate==true)then if event.phase == "began" then player.x = event.x player.y = event.y elseif event.phase == "moved" then local line = display.newRect( player.x, player.y, 5,5) line:setStrokeColor( 1, 1, 1 ) line.strokeWidth = 1 physics.addBody(line, "dynamic", { bounce = 0, density=0 ,friction=10}) line.myname ="player" line.isSensor = true line:addEventListener( "collision", onCollision ) groupLine:insert(line) player.x = event.x player.y = event.y elseif event.phase=="ended"then player.x, player.y = event.x, event.y end end return true end function activateOnTouch( event ) if ( event.phase == "began" ) then activate = true elseif(event.phase == "ended")then activate=false end return true end player = display.newRect( 100, 100, 20, 20 ) player.myname ="player" --physics.addBody(player, "dynamic", { bounce = 0, density=1 ,friction=1}) player:addEventListener( "touch", activateOnTouch ) player.isBullet=true display.currentStage:addEventListener( "touch", onTouch ) wall = display.newRect( 200, 100, 5, 100 ) wall.myname ="wall" wall:setFillColor(0,1,0) physics.addBody(wall, "static", { bounce = 0, density=1 ,friction=1}) dontTouchWall = display.newRect( 250, 100, 5, 100 ) dontTouchWall.myname ="dontTouchWall" dontTouchWall:setFillColor(0,1,0) physics.addBody(dontTouchWall, "static", { bounce = 0, density=1 ,friction=1}) function resetFunction() for i=groupLine.numChildren,1,-1 do display.remove(groupLine[i]) end wall:setFillColor(0,1,0) return true end local reset = display.newRect( 100, 200, 20, 20 ) reset:addEventListener( "tap", resetFunction )

mmmmmh new problem, i added a wall and now, im trying to make when it collide with the first wall, the object cant collide with the second wall but when it move at high speed, there is a collision with the second wall and then with the first wall.

  1. You can’t expect collisions to work properly if you’re manually updating the position of objects, which is what you’re doing in your touch handler.  That is wrong and will fail as often as it (accidentally) works.

Use a touch joint to drag with instead: https://docs.coronalabs.com/guide/physics/physicsJoints/index.html#touch 

  • The touch tells the joint where to move.

  • The joint moves the body.  This way movement is controlled by physics and the collisions can work

  1. Even then, fast moving objects will penetrate and not collide with thin objects.  So, set the  ‘isBullet’ flag to ‘true’ on the fast moving object, after adding the body.

Example of dragging:

local touchJointForce = 20000 -- == -- dragPart() -- == local function dragPart( self, event ) local phase = event.phase if( phase == "began" ) then display.getCurrentStage():setFocus(self,event.id) self.isFocus = true self.tempJoint = physics.newJoint( "touch", self, self.x, self.y ) self.tempJoint.maxForce = touchJointForce elseif( self.isFocus ) then if( phase == "moved" ) then self.tempJoint:setTarget( event.x, event.y ) elseif( phase == "ended" ) then display.getCurrentStage():setFocus( self, nil ) self.isFocus = false display.remove( self.tempJoint ) end end return true end local function addDragger( obj ) obj.touch = dragPart obj:addEventListener( "touch", obj ) end

Used later like this:

local tmp = display.newCircle( 100, 100, 20 ) physics.addBody( tmp ) tmp.isBullet = true addDragger( tmp )

Now you can touch and drag the circle.

I extracted the above from my Physics Fun examples:

http://github.com/roaminggamer/CoronaGeek/raw/master/Hangouts/ICanMakeThat/PhysicsFun.zip

from a prior Corona Geek Hangout.

thank you