Bouncing ball

Hi all,

I’m trying to get a ball to bounce in a straight line, ie up or down, left or right - not diagonally.

I’ve tried 2 methods - one using physics and one without. Either way I’m not getting anywhere.

Using physics, I’m applying forces, but even then the ball does not necessarily move in a straight line, especially when it bounces off a wall.

Without physics it’s much harder as I’m doing a lot of other things with interactive objects so there would collisions everywhere.
I also need the ball to keep moving.

Can anyone help with this?
Thanks in advance! [import]uid: 40538 topic_id: 9216 reply_id: 309216[/import]

I wrote this while learning Corona about a week ago. Just pick out the pieces that you need (the moveBall function is really what you’re looking for).

[code]
module(…, package.seeall)

function new()
local localGroup = display.newGroup()
local touchBall = true
local speed = 2
xDir = 1
yDir = 1
move = true

local background = display.newImage(“world.png”, 0 , 225)
background.xScale = 2
background.yScale = 1.75

ball = display.newImage(“soccer_ball.png”)
ball:setReferencePoint(display.CenterReferencePoint)
ball.x = _W/2
ball.y = _H/2
local txt = display.newText(“Action Type”, 0, 0, native.systemFont, 32)
txt:setReferencePoint(display.CenterReferencePoint)

–txt.x = _W/2
–txt.y = _H/2

function ball:touch(e)
move = false
if (e.phase == “began” or e.phase == “moved”) then
–transition.to(ball, {x = e.x, time = 0})
–transition.to(ball, {y = e.y, time = 0})
–xDir =
end
–txt.text = e.phase
–normalizeDirection(ball.x, ball.y, e.x, e.y)
ball.x = e.x --math.random( 32, _W - 32 )
ball.y = e.y --math.random( 32, _H - 32 )
if (e.phase == “ended”) then
move = true
end
end

function background:touch(e)
–txt.text = e.phase
if (e.phase == “began”) then
transition.to(ball, {x = e.x, time = 500})
transition.to(ball, {y = e.y, time = 500})
local xOld = ball.x
local yOld = ball.y
normalizeDirection(ball.x, ball.y, e.x, e.y)
ball.x = e.x
ball.y = e.y
end
end

function normalizeDirection(x1, y1, x2, y2)
–txt.text = x1 … " " … y1 … " " … x2 … " " … y2
local xDif = x2 - x1
local yDif = y2 - y1
magnitude = math.sqrt(xDif*xDif + yDif*yDif)
if speed < 0 then
magnitude = magnitude * -1
end
–txt.text = magnitude
xDir = xDif / magnitude
yDir = yDif / magnitude
–txt.text = xDir … " " … yDir … " "
end

function moveBall(e)
if (move) then
ball.rotation = ball.rotation + 2.0 --* xDir
ball:translate(xDir * speed, yDir * speed)
–ball.x = ball.x + xDir * speed
–ball.y = ball.y + yDir * speed
end

if (ball.x + 32 >= _W) then
xDir = xDir * -1
end
if (ball.y + 32 >= _H) then
yDir = yDir * -1
end
if (ball.x - 32 <= 0) then
xDir = xDir * -1
end
if (ball.y - 32 <= 0) then
yDir = yDir * -1
end
end

local speedUp = display.newImage(“upArrow2.png”)
speedUp.x = display.contentWidth - 75
speedUp.y = 32
speedUp.xScale = 3.0
speedUp.yScale = 4.0
local speedDown = display.newImage(“downArrow.png”)
speedDown.x = display.contentWidth - 25
speedDown.y = 20
speedDown.xScale = 2.0
speedDown.yScale = 3.0

function speedUp:tap(e)
speed = speed + 2
if speed == 2 then
speedUp.y = 32
speedUp.rotation = 0.0
speedDown.rotation = 0.0
end
end

function speedDown:tap(e)
speed = speed - 2
if speed == -2 then
speedUp.y = 10
speedDown.rotation = 180.0
speedUp.rotation = 180.0
end
end

local button2 = display.newImage(“button.png”)
button2.x = display.contentWidth / 2
button2.y = 15

local menuButton = display.newImage(“pause.png”)
menuButton.x = display.contentWidth / 2 + 100
menuButton.y = 20
menuButton.xScale = 1.3
menuButton.yScale = 2.0
menuButton.scene = “menu”

function button2:tap(e)
if touchBall then
txt.text = “Background”
ball:removeEventListener(“touch”, ball)
background:addEventListener(“touch”, background)
touchBall = false
else
txt.text = “Ball”
ball:addEventListener(“touch”, ball)
background:removeEventListener(“touch”, background)
touchBall = true
end
end

local function changeScene(e)
if e.phase == “ended” then
Runtime:removeEventListener(“enterFrame”, moveBall)
director:changeScene(e.target.scene, “fade”)
end
end

speedDown:addEventListener(“tap”, speedDown)
speedUp:addEventListener(“tap”, speedUp)
button2:addEventListener(“tap”, button2)
menuButton:addEventListener(“touch”, changeScene)
ball:addEventListener(“touch”, ball)
Runtime:addEventListener(“enterFrame”, moveBall)
localGroup:insert(background)
localGroup:insert(txt)
localGroup:insert(ball)
localGroup:insert(speedUp)
localGroup:insert(speedDown)
localGroup:insert(menuButton)
localGroup:insert(button2)
return localGroup
end

function clean ( event )
print(“2 cleaned”)
end
[/code] [import]uid: 49205 topic_id: 9216 reply_id: 33627[/import]

Thanks for your help awinograd.

When I’ve tried your code, it moves the ball in a diagonal direction, similar to the animation demo.
Sorry if I didn’t make it clear in my original post, but I want to restrict the movement to right angles on rebound when the ball collides with another object, rather than the ball deflecting off at some random angle.

When the ball hits a wall, I’d like the ball to bounce back in the direction which it came from. [import]uid: 40538 topic_id: 9216 reply_id: 33698[/import]

If you want the ball to hit the wall and come back from where it came you should have your moveBall method flip the sign of both the x and y directions like this:

function moveBall(e)  
 if (move) then  
 ball.rotation = ball.rotation + 2.0 --\* xDir  
 ball:translate(xDir \* speed, yDir \* speed)  
 --ball.x = ball.x + xDir \* speed  
 --ball.y = ball.y + yDir \* speed  
 end  
  
 if (ball.x + 32 \>= \_W) then  
 xDir = xDir \* -1  
 yDir = yDir \* -1  
 end  
 if (ball.y + 32 \>= \_H) then  
 yDir = yDir \* -1  
 xDir = xDir \* -1   
 end   
 if (ball.x - 32 \<= 0) then  
 xDir = xDir \* -1  
 yDir = yDir \* -1  
 end  
 if (ball.y - 32 \<= 0) then  
 yDir = yDir \* -1  
 xDir = xDir \* -1   
 end   
end  
  

Is that what you’re looking for?

Edit:
I just reread your original post and realized that I completely misread it. It was getting late! The code I just posted should work if either the x or y component is 0. [import]uid: 49205 topic_id: 9216 reply_id: 33700[/import]

Still not working unfortunately - thanks though. [import]uid: 40538 topic_id: 9216 reply_id: 33719[/import]

Hmmm…that code made the ball bounce where it came from for me… [import]uid: 49205 topic_id: 9216 reply_id: 33724[/import]