-----------------------------------
this_guy
Sun Jul 25, 2004 3:53 pm
bouncing balls
-----------------------------------
i've been trying to get two balls to bounce off each other
i tried using math.distnc to c whether 2 balls r touching, den hav dem change directions but dat didnt look real
-----------------------------------
Paul
Sun Jul 25, 2004 4:21 pm
-----------------------------------
http://www.compsci.ca/v2/viewtopic.php?t=5246
-----------------------------------
Cervantes
Mon Jul 26, 2004 6:49 am
-----------------------------------
note that my approach to circular collision does not work very well for top down views, though it is excellent for a side view, like slime-volleyball.
for top-down, try thoughtful's approach:
setscreen ("position:centre;centre,graphics:300;300,title:Bouncing Balls,nobuttonbar,offscreenonly")
var totalballs : int := 4
var x, y, dx, dy : array 1 .. totalballs of real
for i : 1 .. totalballs
x (i) := Rand.Int (50, maxx - 50)
y (i) := Rand.Int (50, maxy - 50)
dx (i) := Rand.Int (-3, 3)
dy (i) := Rand.Int (-3, 3)
end for
var collangle, mass, a1, a2, nX, nY, optimisedP : real
const ballradius := 8
const highestspeed := 5
proc drawscreen
for i : 1 .. maxx by 20
Draw.FillStar (i, 0, i + 20, 20, 2)
Draw.FillStar (i, maxy - 20, i + 20, maxy, 2)
end for
for k : 20 .. maxy - 20 by 20
Draw.FillStar (0, k, 20, k + 20, 2)
Draw.FillStar (maxx - 20, k, maxx, k + 20, 2)
end for
end drawscreen
proc ball_movement
for i : 1 .. totalballs
%wall bouncing
if x (i) > maxx - 20 - ballradius then
dx (i) := -dx (i)
x (i) := maxx - 20 - ballradius
x (i) += dx (i)
end if
if x (i) < 20 + ballradius then
dx (i) := -dx (i)
x (i) := 20 + ballradius
x (i) += dx (i)
end if
if y (i) > maxy - 20 - ballradius then
dy (i) := -dy (i)
y (i) := maxy - 20 - ballradius
y (i) += dy (i)
end if
if y (i) < 20 + ballradius then
dy (i) := -dy (i)
y (i) := 20 + ballradius
y (i) += dy (i)
end if
x (i) += dx (i)
y (i) += dy (i)
if dx (i) > highestspeed then
dx (i) := highestspeed
elsif dx (i) < -highestspeed then
dx (i) := -highestspeed
end if
if dy (i) > highestspeed then
dy (i) := highestspeed
elsif dy (i) < -highestspeed then
dy (i) := -highestspeed
end if
drawfilloval (round (x (i)), round (y (i)), ballradius, ballradius, blue)
end for
end ball_movement
proc balls_collide
for i : 1 .. totalballs
for k : i .. totalballs
if k not= i then
if Math.Distance (x (i), y (i), x (k), y (k)) < ballradius * 2 then
%CREDIT : THOUGHTFUL
if y (k) - y (i) not= 0 and x (k) - x (i) not= 0 then
collangle := arctand ((y (k) - y (i)) / ((x (k) - x (i))))
nX := cosd (collangle)
nY := sind (collangle)
a1 := dx (i) * nX + dy (i) * nY
a2 := dx (k) * nX + dy (k) * nY
optimisedP := (a1 - a2)
dx (i) -= (optimisedP * nX)
dy (i) -= (optimisedP * nY)
dx (k) += (optimisedP * nX)
dy (k) += (optimisedP * nY)
% moves the balls forward 2 steps so they dont get stuck with each other as often
x (i) += dx (i)
y (i) += dy (i)
x (k) += dx (k)
y (k) += dy (k)
end if
end if
end if
end for
end for
end balls_collide
loop
cls
drawscreen
ball_movement
balls_collide
View.Update
delay (12)
end loop
-----------------------------------
DanShadow
Mon Jul 26, 2004 6:35 pm
-----------------------------------
or as done in many programs, create a cute, simple collision detection.
Create a square with slightly smaller parameters than the circle, and make its center the same as the circles. If one of the immediate sides, or edges, or even the middle hits the other circle, write a procedure that checks which general direction (top_right,top_left,bottom_right,bottom_middle,etc. etc.) the opposing circle hits, and change the opposing balls direction to the opposite direction of its original direction, and maybe change its speed a bit. Lol, cheap, but it works.
-----------------------------------
this_guy
Tue Jul 27, 2004 3:06 pm
-----------------------------------
wow thnx guys...except for danshadow...didnt get wut u said
1 problem, i looked at cervantes, but sometimes 2 balls would get stuck together and rotate around each other.
that happened with smthg i tried 2, but dunno wut da prob is
-----------------------------------
Cervantes
Fri Jul 30, 2004 6:42 am
-----------------------------------
% moves the balls forward 2 steps so they dont get stuck with each other as often
x (i) += dx (i)
y (i) += dy (i)
x (k) += dx (k)
y (k) += dy (k)
That is the part that tries to prevent the balls from sticking together. If you find that they are sticking together, do it again.
% moves the balls forward 2 steps so they dont get stuck with each other as often
x (i) += (2 * dx (i))
y (i) += (2 * dy (i))
x (k) += (2 * dx (k))
y (k) += (2 * dy (k))
-----------------------------------
DanShadow
Fri Jul 30, 2004 8:55 pm
-----------------------------------
This is an example of what I meant.(the picture attached)
[Open the file for this example]
See the light blue square behind the circle? That is the offset for the radius
in each corner. Now if a part of the second square around the second circle enters inside the first square of the first circle, it initiates a "collision" procedure which repels the second circle (and/or the first) in the opposite direction. If this clears up what I mean, my intention is fufilled.
-----------------------------------
this_guy
Tue Aug 03, 2004 4:02 pm
-----------------------------------
oh! i c...
kinda cheap, and fake
especially if u hav a lot of diff circles.
but its so much easier:D
-----------------------------------
DanShadow
Tue Aug 03, 2004 6:57 pm
-----------------------------------
hehe, true, true. But a lot of people seem to use that! Its kind of weird, but if so many people do it, why not? :wink:
-----------------------------------
Delta
Thu Aug 05, 2004 11:36 am
-----------------------------------
Because it's inefficient... use cervantes method which is about a hundred times better... I like how you have the engery transfer goin' on there cervantes real smooth use of physics lol... but ya... will balls... don't use a box for collisions... it's common sense...
-----------------------------------
DanShadow
Thu Aug 05, 2004 3:42 pm
-----------------------------------
Im not saying you SHOULD use box collision detection, im just saying that quite a few people use it, and its easier if you dont understand physics.