Computer Science Canada Many Balls bouncing

 Author: Paul [ Sun Feb 15, 2004 10:53 pm ] Post subject: Many Balls bouncing Can anyone show me an easy way to have many balls bouncing around in a box, preferably without using alot of different variables and not alot of flashing?

 Author: Homer_simpson [ Sun Feb 15, 2004 11:26 pm ] Post subject: check out my particle enegine with physics post...

Author:  Cervantes [ Mon Feb 16, 2004 3:52 pm ]
Post subject:

Well I think he wants something simpler than that
You need to learn to use arrays. If you can't understand them from this code and from the help file and any tutorials on here (You'll get it from all those I'm sude) PM me or ask in this thread.

 code: var howmany : int put "How many balls? : " .. get howmany var x, y, dx, dy : array 1 .. howmany of int for i : 1 .. howmany     dx (i) := Rand.Int (-4, 4)     dy (i) := Rand.Int (-4, 4)     x (i) := maxx div 2     y (i) := maxy div 2 end for setscreen ("offscreenonly") cls loop     cls     for k : 1 .. howmany         x (k) += dx (k)         y (k) += dy (k)         Draw.FillOval (x (k), y (k), 5, 5, brightred)     end for     View.Update     delay (5) end loop

Author:  zylum [ Mon Feb 16, 2004 4:03 pm ]
Post subject:

you forgot to add the bit of code which checks whether the ball has reached the screen...

 code: x (k) += dx (k) y (k) += dy (k) if x (k) < 0 or x (k) > maxx then     dx (k) *= -1 end if if y (k) < 0 or y (k) > maxy then     dx (k) *= -1 end if

 Author: Cervantes [ Mon Feb 16, 2004 4:08 pm ] Post subject: Paul is a very compitent programmer who can do that himself... All he needed to know was how to use an array.

Author:  we64 [ Mon Feb 16, 2004 6:37 pm ]
Post subject:

I changed it based on Cervantes' code... Now it really bouncing around screen...
 code: var howmany : int put "How many balls? : " .. get howmany var x, y, dx, dy : array 1 .. howmany of int for i : 1 .. howmany     dx (i) := Rand.Int (-4, 4)     dy (i) := Rand.Int (-4, 4)     x (i) := maxx div 2     y (i) := maxy div 2 end for setscreen ("offscreenonly") cls loop     cls     for k : 1 .. howmany         x (k) += dx (k)         y (k) += dy (k)         Draw.FillOval (x (k), y (k), 5, 5, brightred)         if x (k) >= maxx or x (k) <= 0 then             dx (k) := -dx (k)         elsif y (k) >= maxy or y (k) <= 0 then             dy (k) := -dy (k)         end if     end for     View.Update     delay (5) end loop

 Author: Paul [ Mon Feb 16, 2004 6:46 pm ] Post subject: Hehe, thanks, this kinda looks like the other guy's explosion don't you think? And if you use over 100 balls, it looks vaguely 3Dish.

 Author: jonos [ Mon Feb 16, 2004 6:51 pm ] Post subject: we64's thing looks crazy. its like a kaliedoscope. +bits jonos edit: nm, bits thing isn't workin.

Author:  Cervantes [ Mon Feb 16, 2004 7:02 pm ]
Post subject:

....
jonos why are you trying to give we64 bits for merging code that I wrote with a snippet that zylum wrote?

anyways here is a game that I made using thoughtful's collision from his pool tutorial.

 code: View.Set ("position:centre;centre,graphics:300;300,title:Bouncing Balls,nobuttonbar") var totalballs : int := 15 %NOTE : to increase how many balls will spawn this number must be at least equal to the max number of balls var x, y, dx, dy : array 1 .. totalballs of int var dx_temp, dy_temp : array 1 .. totalballs of real var movedist1, movedist2, collangle, mass, a1, a2, nX, nY, optimisedP : real var px, py : int px := maxx div 2 py := maxy div 2 var keys : array char of boolean var hit : boolean := false var respawn : boolean := true var respawnx, respawny : int var lives : int := 3 const ballradius := 8 const ballcollidedistance := ballradius * 2 var timer : int setscreen ("offscreenonly") mass := 1 for i : 1 .. totalballs     x (i) := Rand.Int (20 + ballradius, maxx - 20 - ballradius)     y (i) := Rand.Int (20 + ballradius, maxy - 20 - ballradius)     dx (i) := Rand.Int (-3, 3)     dy (i) := Rand.Int (-3, 3) end for 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     locate (3, 3) end drawscreen proc ball_movement     for i : 1 .. totalballs         %wall bouncing         if x (i) > maxx - 20 - ballradius then             dx (i) := -dx (i)             x (i) += dx (i)         end if         if x (i) < 20 + ballradius then             dx (i) := -dx (i)             x (i) += dx (i)         end if         if y (i) > maxy - 20 - ballradius then             dy (i) := -dy (i)             y (i) += dy (i)         end if         if y (i) < 20 + ballradius then             dy (i) := -dy (i)             y (i) += dy (i)         end if         x (i) += dx (i)         y (i) += dy (i)         drawfilloval (x (i), 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)) < ballcollidedistance 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 := x (i) * nX + y (i) * nY                         a2 := x (k) * nX + y (k) * nY                         optimisedP := (2.0 * (a1 - a2)) / (mass + mass)                         x (i) := x (i) - (round (optimisedP) * round (mass) * round (nX))                         y (i) := y (i) - (round (optimisedP) * round (mass) * round (nY))                         x (k) := x (k) + (round (optimisedP) * round (mass) * round (nX))                         y (k) := y (k) + (round (optimisedP) * round (mass) * round (nY))                         % moves the balls forward a step so they dont get stuck with each other( but the balls will still stick)                         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 proc player_control     Input.KeyDown (keys)     if keys (KEY_UP_ARROW) then         py += 2     end if     if keys (KEY_DOWN_ARROW) then         py -= 2     end if     if keys (KEY_RIGHT_ARROW) then         px += 2     end if     if keys (KEY_LEFT_ARROW) then         px -= 2     end if     drawfilloval (px, py, ballradius, ballradius, brightred) end player_control proc player_boundaries     if px > maxx - 50 - ballradius then         px := maxx - 50 - ballradius     end if     if px < 50 + ballradius then         px := 50 + ballradius     end if     if py > maxy - 50 - ballradius then         py := maxy - 50 - ballradius     end if     if py < 50 + ballradius then         py := 50 + ballradius     end if end player_boundaries proc relocate     lives -= 1     delay (1000)     px := 20 + ballradius     py := 20 + ballradius end relocate loop     timer := Time.Elapsed     totalballs := round (timer / 5000)     exit when totalballs > 20 or hit = true     cls     drawscreen     player_control     player_boundaries     ball_movement     balls_collide     for k : 1 .. totalballs         if Math.Distance (px, py, x (k), y (k)) < ballcollidedistance then             hit := true         end if     end for     View.Update     delay (10) end loop delay (500) cls locate (7, 5) put "Thanks for playing,\n       -Cervantes"

its not nearly done but w/e just for fun

 Author: Paul [ Mon Feb 16, 2004 7:06 pm ] Post subject: Very nice, bahaha, you slow ninja's will never catch me. Grr... it took 10 of them. Have you realized that the player can't reach the corners?

 Author: Cervantes [ Mon Feb 16, 2004 7:08 pm ] Post subject: yes I have I did that to prevent those cheap players from hiding in the corner. Takes a long time for you to die when you hide in the corners

 Author: jonos [ Mon Feb 16, 2004 7:10 pm ] Post subject: i believe that i can give bits who anyone who i think deserves them, and my opinion on who deserves them does not have to be the same as your. i liked what he did with it, so i thought that i would give him bits.

 Author: Cervantes [ Mon Feb 16, 2004 7:15 pm ] Post subject: Jonos you are totally entitled to you're opinion and your beliefs. As for my beliefs oh who deserves bits, I think no one here. That's really and truly not a hard program to make But while you're enjoying your freedom of opinion allow me to enjoy mine: le cut... le paste.

 Author: jonos [ Mon Feb 16, 2004 7:26 pm ] Post subject: the code was not difficult compared to your skill level, but to mine it was.

 Author: Paul [ Mon Feb 16, 2004 7:33 pm ] Post subject: No, I don't think the code is difficult, or complicated, it just takes experience plus intelligence to come up with it

Author:  Cervantes [ Mon Feb 16, 2004 7:56 pm ]
Post subject:

It's kinda like thinking in another dimension.. I guess
Everyone how has spoken in this thread so far could do that with one ball. Two balls? Yes, just have 2 x vars and 2 y vars etc. 100 balls? It's harder, but it really isn't that hard.

When you've got the for loops going 100 balls is basically simplified into 1 ball. Wherever you would say something like
 code: ballx += balldx bally += balldy

you actually have
 code: for i : 1 .. howmanyballs ballx (i) += balldx (i) bally (i) += balldy (i) end for

Author:  xmen [ Fri Mar 26, 2004 7:16 pm ]
Post subject:  "array subscript is out of range" ERROR!!!!!!

Cervantes wrote:
....

 code: View.Set ("position:centre;centre,graphics:300;300,title:Bouncing Balls,nobuttonbar") var totalballs : int := 15 %NOTE : to increase how many balls will spawn this number must be at least equal to the max number of balls var x, y, dx, dy : array 1 .. totalballs of int var dx_temp, dy_temp : array 1 .. totalballs of real var movedist1, movedist2, collangle, mass, a1, a2, nX, nY, optimisedP : real var px, py : int px := maxx div 2 py := maxy div 2 var keys : array char of boolean var hit : boolean := false var respawn : boolean := true var respawnx, respawny : int var lives : int := 3 const ballradius := 8 const ballcollidedistance := ballradius * 2 var timer : int setscreen ("offscreenonly") mass := 1 for i : 1 .. totalballs     x (i) := Rand.Int (20 + ballradius, maxx - 20 - ballradius)     y (i) := Rand.Int (20 + ballradius, maxy - 20 - ballradius)     dx (i) := Rand.Int (-3, 3)     dy (i) := Rand.Int (-3, 3) end for 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     locate (3, 3) end drawscreen proc ball_movement     for i : 1 .. totalballs         %wall bouncing         if x (i) > maxx - 20 - ballradius then             dx (i) := -dx (i)             x (i) += dx (i)         end if         if x (i) < 20 + ballradius then             dx (i) := -dx (i)             x (i) += dx (i)         end if         if y (i) > maxy - 20 - ballradius then             dy (i) := -dy (i)             y (i) += dy (i)         end if         if y (i) < 20 + ballradius then             dy (i) := -dy (i)             y (i) += dy (i)         end if         x (i) += dx (i)         y (i) += dy (i)         drawfilloval (x (i), 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)) < ballcollidedistance 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 := x (i) * nX + y (i) * nY                         a2 := x (k) * nX + y (k) * nY                         optimisedP := (2.0 * (a1 - a2)) / (mass + mass)                         x (i) := x (i) - (round (optimisedP) * round (mass) * round (nX))                         y (i) := y (i) - (round (optimisedP) * round (mass) * round (nY))                         x (k) := x (k) + (round (optimisedP) * round (mass) * round (nX))                         y (k) := y (k) + (round (optimisedP) * round (mass) * round (nY))                         % moves the balls forward a step so they dont get stuck with each other( but the balls will still stick)                         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 proc player_control     Input.KeyDown (keys)     if keys (KEY_UP_ARROW) then         py += 2     end if     if keys (KEY_DOWN_ARROW) then         py -= 2     end if     if keys (KEY_RIGHT_ARROW) then         px += 2     end if     if keys (KEY_LEFT_ARROW) then         px -= 2     end if     drawfilloval (px, py, ballradius, ballradius, brightred) end player_control proc player_boundaries     if px > maxx - 50 - ballradius then         px := maxx - 50 - ballradius     end if     if px < 50 + ballradius then         px := 50 + ballradius     end if     if py > maxy - 50 - ballradius then         py := maxy - 50 - ballradius     end if     if py < 50 + ballradius then         py := 50 + ballradius     end if end player_boundaries proc relocate     lives -= 1     delay (1000)     px := 20 + ballradius     py := 20 + ballradius end relocate loop     timer := Time.Elapsed     totalballs := round (timer / 5000)     exit when totalballs > 20 or hit = true     cls     drawscreen     player_control     player_boundaries     ball_movement     balls_collide     for k : 1 .. totalballs         if Math.Distance (px, py, x (k), y (k)) < ballcollidedistance then             hit := true         end if     end for     View.Update     delay (10) end loop delay (500) cls locate (7, 5) put "Thanks for playing,\n       -Cervantes"

its not nearly done but w/e just for fun

at first when i was running this program it went fine. but after awhile, an error suddenly pops up saying "array subscript is out of range" for:
Cervantes wrote:
....
if x (i) > maxx - ballradius then

do any of u kno why??
i also notice when i change the # of balls n the radius of balls this error appears earlier.....plzz show me how to fix this

 Author: xmen [ Fri Mar 26, 2004 7:57 pm ] Post subject: ALSO how come sometimes the balls move very slowly while sometimes very fast?? how can i fix the problem where the ball get stuck on one of the sides (kinda start shaking)

Author:  Hackster [ Sat Mar 27, 2004 12:44 am ]
Post subject:

Here's a bouncy ball program that is in a totally random pattern
 code: % The "Jumble" program. setscreen ("offscreenonly") colorback (42) cls % Place some circles around the screen const radius : int := 30 const ball : int := 20 var x, y, dx, dy, clr : array 1 .. ball of int for i : 1 .. ball     x (i) := Rand.Int (radius, maxx - radius)     y (i) := Rand.Int (radius, maxy - radius)     dx (i) := Rand.Int (-3, 3)     dy (i) := Rand.Int (-3, 3)     clr (i) := Rand.Int (16, 32) end for loop     cls         % Clear the offscreen window     for i : 1 .. ball         if x (i) + dx (i) < radius or                 x (i) + dx (i) > maxx - radius then             dx (i) := -dx (i)         end if         if y (i) + dy (i) < radius or                 y (i) + dy (i) > maxy - radius then             dy (i) := -dy (i)         end if         x (i) := x (i) + dx (i)         y (i) := y (i) + dy (i)         Draw.FillOval (x (i), y (i), radius, radius, clr (i))     end for     View.Update     delay (1) end loop

hope you like!

Author:  Cervantes [ Sat Mar 27, 2004 10:13 am ]
Post subject:

[quote=xmen][quote=Cervantes]....
if x (i) > maxx - ballradius then[/quote]
do any of u kno why??[/quote]

That would be because that line of code is not actually part of my program no idea how you got that, but its:
 code: if x (i) > maxx - 20 - ballradius then

that code simply tells if the x position of ball (i) has hit the wall or not.

xmen, how did you last long enough to notice that things speed up or slow down!! you must have made some alterations on my code, because I can't get past 7 of those guys I guess it does depend on the speed of your computer though. I'm on 1.6ghz 512 mb of ram. What do you have? If your on a relatively slow computer it probably explains why the speed of the balls change: because as more balls are added the program has to go through the for loops more times, taking up more time.

 Author: xmen [ Sat Mar 27, 2004 7:03 pm ] Post subject: my computer is 1.8 P4 / 256 ram.....well all i did was decrease the # of max balls (in the beginning of program) to like 4, n take out the red ball, everytime i run the program its different sometimes the first blue ball goes very slow, then the second ball goes very fast, n if any of the balls hit the slow one, the slow one turns fast while the fast one turn slow.....etc also if i make the size of the ball bigger, once they collide there are some bugs there too, n sometimes these balls just slide along the sides for some reason i kno these are pretty simple n stupid questions but i reli need answers for them......cuz later on im gonna change the balls into happy faces n make this as screensaver (as one of my assignment).........thnx

Author:  Cervantes [ Sat Mar 27, 2004 7:42 pm ]
Post subject:

You can use my code as a reference, but don't cut and paste and change a few things to make it look like your own code. Just a warning, I don't know if you were planning on doing that or not.
Anyways, take a look at this part of the program:
 code: for i : 1 .. totalballs     x (i) := Rand.Int (20 + ballradius, maxx - 20 - ballradius)     y (i) := Rand.Int (20 + ballradius, maxy - 20 - ballradius)     dx (i) := Rand.Int (-3, 3)     dy (i) := Rand.Int (-3, 3) end for

This explains why certain balls begin at a faster pace then others. dx represents the balls speed along the x axis, and dy represents the balls speed along the y axis.
later, this code appears:
 code: x (i) += dx (i) y (i) += dy (i)

that code is inside the main loop, so every time that code executes, the value of dx is added to x, and dy to y.
Because dx and dy are created using Rand.Int, the balls begin with different speeds.
As for when they collide, the balls transfer energy between each other, speeding one up and slowing the other down.
you should note though that the collision data in this is rather messed up though.

 Author: xmen [ Sat Mar 27, 2004 11:10 pm ] Post subject: Cervantes hav u tried letting ur program run for awhile (with like 6 balls, delete the red one) n get this error saying "array subscript is out of range" ?? how do i fix that??

 Author: Cervantes [ Sun Mar 28, 2004 10:30 am ] Post subject: you fix that by increasing the totalballs variable at the top of the program.

 Author: xmen [ Sun Mar 28, 2004 11:58 am ] Post subject: but wut if i only want 6 balls appearin in total?? well wut ive tried was set the totalballs to a large nuber (like 50, so that the program can continue longer) n then i put exit when i=7 to the part of actually drawin the balls this worked completely fine (only 6 balls appeared) BUT if i was to leave the program on longer, it'll laaaaaaaaaaaaaaaggggggg like crazy, not cuz of my system, it was bcuz of the colliding part of this program was still calculating stuffs using the totalballs ive set (50) so is there any way i can hav this program run forever with only like 6 balls but no lag afterwards??

 Author: Cervantes [ Sun Mar 28, 2004 12:32 pm ] Post subject: uh-huh. all you do is set totalballs to 6 and comment out the bit about the timer.

 Author: xmen [ Sun Mar 28, 2004 2:01 pm ] Post subject: ok thnx sry but one last question.......u see rite now im making screensaverS for an assignment. it starts with a "menu" (just simply with GUI buttons) for viewing the 5 screensavers, so the first button is screen 1 n etc but the problem is, if i was to copynpaste all 5 screensavers' codes and complie them into one program for this assignment, im thinking that i'll lag quite alot (especially with school computers). so i justwanna ask u if theres a command (for GUI button procedure) to read n run another turing file/program once i click GUI button 1,2,3...... so i'll hav 6 programs with 5 screensavers and one "menu" page

 Author: Cervantes [ Sun Mar 28, 2004 6:57 pm ] Post subject: F10 on include

Author:  Homer_simpson [ Mon Mar 29, 2004 2:57 am ]
Post subject:

we64 wrote:
I changed it based on Cervantes' code... Now it really bouncing around screen...
 code: var howmany : int put "How many balls? : " .. get howmany var x, y, dx, dy : array 1 .. howmany of int for i : 1 .. howmany     dx (i) := Rand.Int (-4, 4)     dy (i) := Rand.Int (-4, 4)     x (i) := maxx div 2     y (i) := maxy div 2 end for setscreen ("offscreenonly") cls loop     cls     for k : 1 .. howmany         x (k) += dx (k)         y (k) += dy (k)         Draw.FillOval (x (k), y (k), 5, 5, brightred)         if x (k) >= maxx or x (k) <= 0 then             dx (k) := -dx (k)         elsif y (k) >= maxy or y (k) <= 0 then             dy (k) := -dy (k)         end if     end for     View.Update     delay (5) end loop

here's a little something to make that look better:
 code: var howmany : int put "How many balls? : " .. get howmany var x, y, dx, dy,a : array 1 .. howmany of real for i : 1 .. howmany     dx (i) := Rand.Int (-4, 4)     dy (i) := Rand.Int (-4, 4)     a (i) := Rand.Int (0, 100)/100     x (i) := maxx div 2     y (i) := maxy div 2 end for setscreen ("offscreenonly") cls loop     cls     for k : 1 .. howmany         x (k) += dx (k)*a(k)         y (k) += dy (k)*a(k)         Draw.FillOval (round(x (k)), round(y (k)), 5, 5, brightred)         if x (k) >= maxx or x (k) <= 0 then             dx (k) := -dx (k)         elsif y (k) >= maxy or y (k) <= 0 then             dy (k) := -dy (k)         end if     end for     View.Update     delay (5) end loop

 :