bouncing balls
Author |
Message |
this_guy
|
Posted: Sun Jul 25, 2004 3:53 pm Post subject: 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
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
Paul
|
|
|
|
|
Cervantes
|
Posted: Mon Jul 26, 2004 6:49 am Post subject: (No subject) |
|
|
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:
code: |
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
|
Posted: Mon Jul 26, 2004 6:35 pm Post subject: (No subject) |
|
|
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
|
Posted: Tue Jul 27, 2004 3:06 pm Post subject: (No subject) |
|
|
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
|
Posted: Fri Jul 30, 2004 6:42 am Post subject: (No subject) |
|
|
code: |
% 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.
code: |
% 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
|
Posted: Fri Jul 30, 2004 8:55 pm Post subject: (No subject) |
|
|
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.
Description: |
|
Filesize: |
414.06 KB |
Viewed: |
6454 Time(s) |
|
|
|
|
|
|
|
this_guy
|
Posted: Tue Aug 03, 2004 4:02 pm Post subject: (No subject) |
|
|
oh! i c...
kinda cheap, and fake
especially if u hav a lot of diff circles.
but its so much easier:D
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
DanShadow
|
Posted: Tue Aug 03, 2004 6:57 pm Post subject: (No subject) |
|
|
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?
|
|
|
|
|
|
Delta
|
Posted: Thu Aug 05, 2004 11:36 am Post subject: (No subject) |
|
|
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
|
Posted: Thu Aug 05, 2004 3:42 pm Post subject: (No subject) |
|
|
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.
|
|
|
|
|
|
|
|