?!! Help applyLinearImpulse !!?

How can I let the ball goes sideways? So if I tap right on the ball, the ball goes left & if I tap left on the ball, the ball goes right.

It’s all about the 36th line:

[code]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require(“physics”)
physics.start()
physics.setGravity(0, 29.4)

–physics.setDrawMode(“hybrid”)

local background = display.newImage ( “road.jpg” )

local ball = display.newImageRect( “SkySoccer Ball.gif”, 100, 100 )
ball.x = display.contentCenterX
ball.y = display.contentCenterY

local leftWall = display.newRect(0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect(display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect(0, 0, display.contentWidth, 0.1 )

physics.addBody(leftWall, “static”, { bounce = 0.1} )
physics.addBody(rightWall, “static”, { bounce = 0.1} )
physics.addBody(ceiling, “static”, { bounce = 0.1} )

local white = display.newImageRect( “white.png”, 320, 0.1 )
white.x = display.contentCenterX
white.y = 480

physics.addBody(ball, { bounce = 0.5, radius = 40, friction = 1.0} )

physics.addBody(white, “static”, { bounce = 0.0, friction = 1.0})

function moveBall(event)
if event.phase == “began” then
ball:applyLinearImpulse( 0, -1.5, ball.x, ball.y )
return false
end
end

ball:addEventListener(“touch”, moveBall)[/code]

Can you please help me??? [import]uid: 203192 topic_id: 34116 reply_id: 334116[/import]

For the value of force, subtract the position of the ball from the location of the touch. [import]uid: 8271 topic_id: 34116 reply_id: 135672[/import]

What do you mean? Can you give an example? [import]uid: 203192 topic_id: 34116 reply_id: 135724[/import]

I would use a tap event, but that’s me. I would also use a local listener on the ball object. You should also return true from all event listeners when your listener handles the event because if you don’t the event will propagate down to the other display objects. Also, in your code you are passing 0 as the force to be applied on the X axis, meaning you were only applying a force vertically.

[lua]function ball:tap(event)
local x, y = ball.x-event.x, ball.y-event.y – calc values to be applied by subtracting touch from ball position values
ball:applyLinearImpulse( x, 0, ball.x, ball.y ) – apply only the horizontal force value (relative to the touch distance from the centre of the ball)
return true – always return true if you’ve handled the touch
end

ball:addEventListener(“tap”, ball) – local listener for performance and tap so that the various touch phases don’t need to be handled[/lua] [import]uid: 8271 topic_id: 34116 reply_id: 135727[/import]

Now I’ve this but the ball is vibrating on the floorr and the ball goes to much sideways.

[code]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 29.4 )

–physics.setDrawMode(“hybrid”)

local background = display.newImage ( “road.jpg” )

local ball = display.newImageRect( “SkySoccer Ball.gif”, 100, 100 )
ball.x = display.contentCenterX
ball.y = display.contentCenterY

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 480, display.contentWidth, 0.1 )

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.5, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “static”, { bounce = 0.0, friction = 1.0 } )

function moveBall( event )
if event.phase == “began” then
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -1.5, ball.x, ball.y )
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )[/code] [import]uid: 203192 topic_id: 34116 reply_id: 135730[/import]

I have found that using static bodies is a bad thing. This is because the old saying of “What happens when an irresistible force meets and immoveable object?” Basically, static objects impose their will on dynamic objects, meaning that your ball will continuously want to move away from the floor.

Make the floor dynamic and anchor it in place with a weld joint to an off screen (I used the left wall) static object and you’re good.

Also, you really want to try to use realistic world values - ie: walls and floors etc that are .1 thick are not really realistic. Box2D is a physics engine and the values used within it represent the real world, to as close an approximation as the engine developer could get (or so I’ve read.)

Keep the real world in mind when building your objects and try not to use too many static objects. Using this premise, the code below works fine for me - the ball doesn’t tremble and the force applied to it when tapping it is fairly effective but not too hard.

One last question, do you really want a touch event listener and isFixedRotation=true ?

[lua]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 29.4 )

physics.setDrawMode(“hybrid”) – to see what is happening in the physics world

local background = display.newGroup() – because I don’t have your images

local ball = display.newCircle(0,0,40)
ball.x = display.contentCenterX
ball.y = display.contentCenterY-100 – to correctly position the ball at the start

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 500, display.contentWidth, 10 ) – dynamic bodies should not be very thin

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.5, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “dynamic”, { bounce = 0.0, friction = 1.0, density=1 } ) – dynamic bodies should have a reasonable density (all physics properties should be ‘reasonable’)

local lock = physics.newJoint( “weld”, leftWall, floorr, floorr.x, floorr.y ) – keep the floor in place

function moveBall( event ) – it would be better as a local listener
if event.phase == “began” then – why not a ‘tap’ event listener?
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -1.5, ball.x, ball.y ) – do you really want to apply a vertical (upwards) force?
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )[/lua] [import]uid: 8271 topic_id: 34116 reply_id: 135737[/import]

Thank you for all the support! A touch event works for me the best and the ball must not rotate so “ball.isFixedRotation = true”
A vertical is needed because otherwise the ball can’t go in the air. I want that the ball is going in the air if I tap it at the bottom.
One last question: The ball is going to much sideways. How can I let de ball goes just a tiny little bit sideways if I tap it right or left??? [import]uid: 203192 topic_id: 34116 reply_id: 135758[/import]

If you apply the original calculation I provided, you’ll see that the distance of the touch from centre of the ball is equal to the amount of force applied in both the horizontal and vertical planes. That means that if the user taps on the bottom right, the ball will have force applied which pushes it up and left, etc.

To throttle the motion of the ball you could either set the linearDamping value (which suppresses the linear motion - angularDamping suppresses rotational motion) or you could have a timer which fires every (for example) 100 milliseconds, checks the horizontal velocity and reduces it by calling getLinearVelocity and setLinearVelocity functions. [import]uid: 8271 topic_id: 34116 reply_id: 135760[/import]

I have actually no idea how to set this in my file. I am only 15 years old so can you please help me where to put it in?

Here is the file:

[code]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 19.6 )

–physics.setDrawMode(“hybrid”)

local background = display.newImage ( “road.jpg” )

local pauseBtn = display.newImageRect ( “pausebtn.gif”, 50, 50 )
pauseBtn.x = 20
pauseBtn.y = 20

local resumeBtn = display.newImageRect ( “resumebtn.gif”, 50, 50 )
resumeBtn.x = 20
resumeBtn.y = 20

resumeBtn.isVisible = false

local ball = display.newImageRect( “SkySoccer Ball.gif”, 100, 100 )
ball.x = display.contentCenterX
ball.y = display.contentCenterY-100

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 480, display.contentWidth, 1 )

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.1, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “dynamic”, { bounce = 0.0, friction = 1.0, density = 1 } )

local lock = physics.newJoint( “weld”, leftWall, floorr, floorr.x, floorr.y ) – keep the floor in place

function moveBall( event )
if event.phase == “began” then
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -2, ball.x, ball.y )
return true
end
end

function pauseGame( event )
–if end of touch event
if(event.phase == “ended”) then
–pause the physics
physics.pause()
–make pause button invisible
pauseBtn.isVisible = false
–make resume button visible
resumeBtn.isVisible = true
– indicates successful touch
return true
end
end

function resumeGame( event )
–if end of touch event
if(event.phase == “ended”) then
–resume physics
physics.start()
–make pause button visible
pauseBtn.isVisible = true
–make resume button invisible
resumeBtn.isVisible = false
– indicates successful touch
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )

pauseBtn:addEventListener( “touch”, pauseGame )

resumeBtn:addEventListener( “touch”, resumeGame ) [/code] [import]uid: 203192 topic_id: 34116 reply_id: 135762[/import]

Let’s go with linearDamping…

[lua]Line 38: ball.linearDamping = .5[/lua] [import]uid: 8271 topic_id: 34116 reply_id: 135763[/import]

The ball goes simply slower down, but it doesn’t reduce the speed to the left or right [import]uid: 203192 topic_id: 34116 reply_id: 135764[/import]

linearDamping slows the ball, as if it is moving through something, like golden syrup. Fine tune the value to get the right effect. It reduces the speed in all directions.

If you want to reduce the amount of force applied to the ball, just adjust the first parameter on line 47. Maybe divide by 3 or something?

Are you really sure you always want to apply a -ve value for the y force? The upwards force will not be relative to the touch location if you don’t use the local y value.

[lua]ball:applyLinearImpulse( x / 3, -math.abs(y), ball.x, ball.y )[/lua]

The line above reduces the horizontal force and always ensures the vertical force is upwards, but still relative to the vertical distance of the touch from the centre of the ball. [import]uid: 8271 topic_id: 34116 reply_id: 135770[/import]

For the value of force, subtract the position of the ball from the location of the touch. [import]uid: 8271 topic_id: 34116 reply_id: 135672[/import]

What do you mean? Can you give an example? [import]uid: 203192 topic_id: 34116 reply_id: 135724[/import]

I would use a tap event, but that’s me. I would also use a local listener on the ball object. You should also return true from all event listeners when your listener handles the event because if you don’t the event will propagate down to the other display objects. Also, in your code you are passing 0 as the force to be applied on the X axis, meaning you were only applying a force vertically.

[lua]function ball:tap(event)
local x, y = ball.x-event.x, ball.y-event.y – calc values to be applied by subtracting touch from ball position values
ball:applyLinearImpulse( x, 0, ball.x, ball.y ) – apply only the horizontal force value (relative to the touch distance from the centre of the ball)
return true – always return true if you’ve handled the touch
end

ball:addEventListener(“tap”, ball) – local listener for performance and tap so that the various touch phases don’t need to be handled[/lua] [import]uid: 8271 topic_id: 34116 reply_id: 135727[/import]

Now I’ve this but the ball is vibrating on the floorr and the ball goes to much sideways.

[code]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 29.4 )

–physics.setDrawMode(“hybrid”)

local background = display.newImage ( “road.jpg” )

local ball = display.newImageRect( “SkySoccer Ball.gif”, 100, 100 )
ball.x = display.contentCenterX
ball.y = display.contentCenterY

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 480, display.contentWidth, 0.1 )

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.5, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “static”, { bounce = 0.0, friction = 1.0 } )

function moveBall( event )
if event.phase == “began” then
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -1.5, ball.x, ball.y )
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )[/code] [import]uid: 203192 topic_id: 34116 reply_id: 135730[/import]

I have found that using static bodies is a bad thing. This is because the old saying of “What happens when an irresistible force meets and immoveable object?” Basically, static objects impose their will on dynamic objects, meaning that your ball will continuously want to move away from the floor.

Make the floor dynamic and anchor it in place with a weld joint to an off screen (I used the left wall) static object and you’re good.

Also, you really want to try to use realistic world values - ie: walls and floors etc that are .1 thick are not really realistic. Box2D is a physics engine and the values used within it represent the real world, to as close an approximation as the engine developer could get (or so I’ve read.)

Keep the real world in mind when building your objects and try not to use too many static objects. Using this premise, the code below works fine for me - the ball doesn’t tremble and the force applied to it when tapping it is fairly effective but not too hard.

One last question, do you really want a touch event listener and isFixedRotation=true ?

[lua]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 29.4 )

physics.setDrawMode(“hybrid”) – to see what is happening in the physics world

local background = display.newGroup() – because I don’t have your images

local ball = display.newCircle(0,0,40)
ball.x = display.contentCenterX
ball.y = display.contentCenterY-100 – to correctly position the ball at the start

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 500, display.contentWidth, 10 ) – dynamic bodies should not be very thin

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.5, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “dynamic”, { bounce = 0.0, friction = 1.0, density=1 } ) – dynamic bodies should have a reasonable density (all physics properties should be ‘reasonable’)

local lock = physics.newJoint( “weld”, leftWall, floorr, floorr.x, floorr.y ) – keep the floor in place

function moveBall( event ) – it would be better as a local listener
if event.phase == “began” then – why not a ‘tap’ event listener?
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -1.5, ball.x, ball.y ) – do you really want to apply a vertical (upwards) force?
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )[/lua] [import]uid: 8271 topic_id: 34116 reply_id: 135737[/import]

Thank you for all the support! A touch event works for me the best and the ball must not rotate so “ball.isFixedRotation = true”
A vertical is needed because otherwise the ball can’t go in the air. I want that the ball is going in the air if I tap it at the bottom.
One last question: The ball is going to much sideways. How can I let de ball goes just a tiny little bit sideways if I tap it right or left??? [import]uid: 203192 topic_id: 34116 reply_id: 135758[/import]

If you apply the original calculation I provided, you’ll see that the distance of the touch from centre of the ball is equal to the amount of force applied in both the horizontal and vertical planes. That means that if the user taps on the bottom right, the ball will have force applied which pushes it up and left, etc.

To throttle the motion of the ball you could either set the linearDamping value (which suppresses the linear motion - angularDamping suppresses rotational motion) or you could have a timer which fires every (for example) 100 milliseconds, checks the horizontal velocity and reduces it by calling getLinearVelocity and setLinearVelocity functions. [import]uid: 8271 topic_id: 34116 reply_id: 135760[/import]

I have actually no idea how to set this in my file. I am only 15 years old so can you please help me where to put it in?

Here is the file:

[code]local storyboard = require “storyboard”
local scene = storyboard.newScene()
local widget = require “widget”
display.setStatusBar( display.HiddenStatusBar )

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 19.6 )

–physics.setDrawMode(“hybrid”)

local background = display.newImage ( “road.jpg” )

local pauseBtn = display.newImageRect ( “pausebtn.gif”, 50, 50 )
pauseBtn.x = 20
pauseBtn.y = 20

local resumeBtn = display.newImageRect ( “resumebtn.gif”, 50, 50 )
resumeBtn.x = 20
resumeBtn.y = 20

resumeBtn.isVisible = false

local ball = display.newImageRect( “SkySoccer Ball.gif”, 100, 100 )
ball.x = display.contentCenterX
ball.y = display.contentCenterY-100

local leftWall = display.newRect( 0, 0, 0.1, display.contentHeight )
local rightWall = display.newRect( display.contentWidth, 0, 0.1, display.contentHeight )
local ceiling = display.newRect( 0, 0, display.contentWidth, 0.1 )
local floorr = display.newRect( 0, 480, display.contentWidth, 1 )

physics.addBody( leftWall, “static”, { bounce = 0.1 } )
physics.addBody( rightWall, “static”, { bounce = 0.1 } )
physics.addBody( ceiling, “static”, { bounce = 0.1 } )

physics.addBody( ball, { bounce = 0.1, radius = 40, friction = 1.0 } )

physics.addBody( floorr, “dynamic”, { bounce = 0.0, friction = 1.0, density = 1 } )

local lock = physics.newJoint( “weld”, leftWall, floorr, floorr.x, floorr.y ) – keep the floor in place

function moveBall( event )
if event.phase == “began” then
local x, y = ball.x-event.x, ball.y-event.y
ball:applyLinearImpulse( x, -2, ball.x, ball.y )
return true
end
end

function pauseGame( event )
–if end of touch event
if(event.phase == “ended”) then
–pause the physics
physics.pause()
–make pause button invisible
pauseBtn.isVisible = false
–make resume button visible
resumeBtn.isVisible = true
– indicates successful touch
return true
end
end

function resumeGame( event )
–if end of touch event
if(event.phase == “ended”) then
–resume physics
physics.start()
–make pause button visible
pauseBtn.isVisible = true
–make resume button invisible
resumeBtn.isVisible = false
– indicates successful touch
return true
end
end

ball.isFixedRotation = true

ball:addEventListener( “touch”, moveBall )

pauseBtn:addEventListener( “touch”, pauseGame )

resumeBtn:addEventListener( “touch”, resumeGame ) [/code] [import]uid: 203192 topic_id: 34116 reply_id: 135762[/import]