Array Ball Question
Author |
Message |
Thatguy
|
Posted: Sat Jun 01, 2013 9:17 pm Post subject: Array Ball Question |
|
|
What is it you are trying to achieve?
To get some help my ball array so that all balls will hit the left side of the screen and bounce off the right side
What is the problem you are having?
Well in my code, it shows that each time one ball will hit the right side, another ball will be randomly placed onto the screen and start moving from left to right, i want the balls to move individually after each new addition from right to left, the problem is that if one ball hits the left hand side, then all the other balls will change direction as well; I really want all individual balls to make contact and bounce off the left side
Describe what you have tried to solve this problem
I tried doing for loops to model the movement of all balls but the boundry condition only works for one ball
Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
Turing: |
View.Set ("graphics:1000;500,buttonbar,offscreenonly")
var BallRadius : int
BallRadius := 12
var BallX : array 1 .. 10 of int % Array of 10 Balls for x position
var BallY : array 1 .. 10 of int % Array of 10 Balls, for y position
var NumBall : int := 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
loop
for i : 1 .. NumBall
drawfilloval (BallX (i ), BallY (i ), BallRadius, BallRadius, black)
BallX (i ) := BallX (i ) - 1
end for
View.Update
cls
if BallX (NumBall ) = BallRadius
then
loop
for d : 1 .. NumBall
drawfilloval (BallX (d ), BallY (d ), BallRadius, BallRadius, black)
BallX (d ) := BallX (d ) + 1
end for
View.Update
cls
if BallX (NumBall ) = maxx - BallRadius
then
NumBall := NumBall + 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
exit
end if
end loop
end if
end loop
|
Please specify what version of Turing you are using
<Answer Here>
Mod Edit:
Make sure to put your code between the code tags in order to preserve whitespace (indentation) and to highlight the syntax.
code: |
[syntax="turing"] ... code ... [/syntax]
|
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
Zren

|
Posted: Sat Jun 01, 2013 11:07 pm Post subject: Re: Array Ball Question |
|
|
Right now, you only have two areas you are applying "movement" or velocity to the ball positions. The first is in the first for loop, when you move everything left 1 pixel. Once. Then once after a new ball is made. The second time is to move everything right until it hits the right wall.
To have each ball move independantly, each ball must have it's own variable(s) in order to represent what direction it is going. So you'd need another array to represent the horizontal velocity of each ball.
Then you'd do: ballPositionX += ballVelocityX on each frame.
Since you're about to use more arrays to represent a single object. I should introduce you to records which can help you simplify it all into a single array. Here's an example taken from a simplified particle engine. Note that each "particle" is essentially a "ball".
Turing: |
type Vector2D :
record
x, y : int
end record
var point : Vector2D
point.x := 124
point.y := 534
type Particle :
record
pos : Vector2D % position
vel : Vector2D % velocity
end record
var particle : Particle
particle.pos.x := 0
particle.pos.y := 0
particle.vel.x := +1 % Right
particle.vel.y := 0
|
Basically, we define our own data type by using records. In the case above, I went beyond that and used our new datatype in another custom datatype. We can even create an array of our new datatype.
Turing: |
var particles : array 1 .. 10 of Particle
% Init
for i : lower (particles ) .. upper (particles )
particles (i ).pos.x := Rand.Int (0, maxx)
% ...
end for
View.Set ("graphics;offscreenonly")
loop
% Update
for i : lower (particles ) .. upper (particles )
% ...
particles (i ).pos.y + = particles (i ).vel.y
end for
end loop
|
If you didn't understand any of that, just ask.
|
|
|
|
|
 |
Thatguy
|
Posted: Sat Jun 01, 2013 11:52 pm Post subject: RE:Array Ball Question |
|
|
I appreciate your help Zren but I am quite a noob at turing. Essentially, I don't really know what record is but I'll look into the tutorials, thanks for your suggestion. If i would need a new array for each position for the ball, would I put that array line of code into both for loops going left and going right? I think I am understanding the general concept, just now sure how to approach it, perhaps you could elaborate a bit more?
Thank You all the same!
|
|
|
|
|
 |
evildaddy911
|
Posted: Sun Jun 02, 2013 8:30 am Post subject: RE:Array Ball Question |
|
|
you already have arrays for position. what you don't have is arrays defining direction and speed (x and y velocities), which you would declare right after (or before if you wanted) you declare the position arrays. next you want to change this
code: | for i : 1 .. NumBall
drawfilloval (BallX (i), BallY (i), BallRadius, BallRadius, black)
BallX (i) := BallX (i) - 1
end for |
to
code: | for i : 1 .. NumBall
drawfilloval (BallX (i), BallY (i), BallRadius, BallRadius, black)
BallX (i) := BallX (i) + BallX_V (i) % instead of hardcoding "-1"
end for
|
this allows you to set which direction the individual ball is travelling without changing any of the other balls' direction. if you want it to move left, set BallX_V(i) <0. if moving right, BallX_V(i) >0. basicly how you do this is through one big for loop:
code: |
% NOTE: this is not working code. this simply explains the steps
numBalls : int = 5
Ballx, Bally, BallxV, BallyV : 1 .. numBalls of int
%
% initialize ball variables
%
loop
for 1 <= i <= numBalls
drawBall (i) % procedure for drawing ball
Ballx (i) = Ballx (i) + ballxV (i) % move ball horizontally
% move ball vertically
if ballHitsLeft (i) then % if the ball hits the left wall
ballxV (i) = +1 % ball now moves right
end if
%
% check if balls hits right, bottom and top here, using same formula
%
end for
end loop
|
|
|
|
|
|
 |
Thatguy
|
Posted: Sun Jun 02, 2013 12:18 pm Post subject: Re: Array Ball Question |
|
|
evildaddy911, thanks for your suggestion. I made the x velocity an array and used that instead of the -1 . However, my code has not yet changed. I know that this is because my condition for the ball bouncing left and right is only for "NumBall", not all the balls up to NumBall; I am not sure how to set the array of all the balls to be in the condition, but thanks for the velocity array tip, it will be easier to make adjustments if needed. My Code :
Turing: |
View.Set ("graphics:1000;500,buttonbar,offscreenonly")
var BallRadius : int
BallRadius := 12
var BallX : array 1 .. 10 of int % Array of 10 Balls for x position
var BallY : array 1 .. 10 of int % Array of 10 Balls, for y position
var NumBall : int := 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
var BallXV : array 1 .. 10 of int
loop
for i : 1 .. NumBall
drawfilloval (BallX (i ), BallY (i ), BallRadius, BallRadius, black)
BallXV (i ) := - 1
BallX (i ) := BallX (i ) + BallXV (i )
end for
View.Update
cls
if BallX (NumBall ) = BallRadius
then
loop
for d : 1 .. NumBall
drawfilloval (BallX (d ), BallY (d ), BallRadius, BallRadius, black)
BallXV (d ) := 1
BallX (d ) := BallX (d ) + BallXV (d )
end for
View.Update
cls
if BallX (NumBall ) = maxx - BallRadius
then
NumBall := NumBall + 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
exit
end if
end loop
end if
end loop
|
Mod Edit:
Please wrap you code in either of the following in order to preserve whitespace (indentation) and to highlight the syntax.
code: |
[syntax="turing"] ... code ... [/syntax]
[code] ... code ... [/code ]
|
|
|
|
|
|
 |
Zren

|
Posted: Sun Jun 02, 2013 4:47 pm Post subject: RE:Array Ball Question |
|
|
To get collision detection to work for each ball, you need to check each collideable object (each wall), for each ball.
Why not just use a for loop over all ball indexes?
~
code: | if BallX (NumBall) = BallRadius then |
This code works right now as you only have a velocity of 1. However, if you ever end up having the ball velocity be 2 or some other number, you might skip over where that comparison would ring true.
So for future proofing, you'd do:
ball.x <= leftWallX + ball.radius
or since leftWallX is equivalent to 0:
ball.x <= ball.radius
~
Right now, you are breaking out of your game loop to assign the velocity of all the balls. Why not just move that into your game loop like so:
Turing: |
View.Set ("graphics:1000;500,buttonbar,offscreenonly")
var BallRadius : int
BallRadius := 12
var BallX : array 1 .. 10 of int % Array of 10 Balls for x position
var BallY : array 1 .. 10 of int % Array of 10 Balls, for y position
var NumBall : int := 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
var BallXV : array 1 .. 10 of int
loop
%...
%View.Update
%cls
%if BallX (NumBall) = BallRadius
% then
loop
for d : 1 .. NumBall
drawfilloval (BallX (d ), BallY (d ), BallRadius, BallRadius, black)
BallXV (d ) := 1
BallX (d ) := BallX (d ) + BallXV (d )
end for
View.Update
cls
if BallX (NumBall ) = maxx - BallRadius
then
NumBall := NumBall + 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
% exit
%
for i : 1 .. NumBall
drawfilloval (BallX (i ), BallY (i ), BallRadius, BallRadius, black)
BallXV (i ) := - 1
BallX (i ) := BallX (i ) + BallXV (i )
end for
%
end if
end loop
%end if
end loop
|
The above logic is almost equivalent to what you're doing now.
|
|
|
|
|
 |
Thatguy
|
Posted: Mon Jun 03, 2013 4:02 pm Post subject: Re: Array Ball Question |
|
|
My Code now works thank you for your help. As you have said before this will be for a game, however i am having trouble for collisions. In my game you control a box and you are supposed to avoid the balls. My condition for collision is basically if any of the balls in the array hits the x or y position of the ball, then the game would exit, But it is not working, My code:
Turing: | View.Set ("graphics:1000;500,buttonbar,offscreenonly")
var BoxX1, BoxX2, BoxY1, BoxY2, BallRadius, move, BallRand, Color, font1, font2, font3 : int
var chars : array char of boolean
var chars1, chars2 : char
BoxX1 := maxx div 2
BoxX2 := maxx div 2. 1
BoxY1 := maxy div 10
BoxY2 := maxy div 8
BallRadius := 12
move := 1
BallRand := Rand.Int (10, 1000)
Color := 30
font1 := Font.New ("Comic Sans:30:bold,underline")
font2 := Font.New ("Comic Sans:10:underline")
font3 := Font.New ("Comic Sans :30:bold")
BallRadius := 12
var BallX : array 1 .. 100 of int % Array of 10 Balls for x position
var BallY : array 1 .. 100 of int % Array of 10 Balls, for y position
var NumBall : int := 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
var BallXV : array 1 .. 100 of int
BallXV (1) := - 1
procedure GameMenu %Creates Game Menu
loop
drawfillbox (0, 0, maxx, maxy, 103)
Font.Draw ("Welcome To The World's Hardest Game", maxx div 7, maxy div 2, font1, red)
Font.Draw ("To Start, Press 'S' ", maxx div 2, maxy div 4, font2, red)
Font.Draw ("To View Controls, Press 'C' ", maxx div 2, maxy div 6, font2, red)
get chars1
if chars1 = ('S')
then
exit
elsif chars1 = ('C')
then
drawfillbox (0, 0, maxx, maxy, 103)
Font.Draw ("Controls", maxx div 7, maxy div 1. 13, font3, red)
Font.Draw ("The controls are rather simple: Use the cursor keys to move.", 100, 401, font2, red)
Font.Draw ("Avoid any bouncing balls as you will lose one of your 3 lives.", 100, 351, font2, red)
Font.Draw ("Reach The 'CheckPoint' and you will progress into harder levels.", 100, 301, font2, red)
Font.Draw ("If you progress far enough, you will gain the ability to shoot, at which point the 'SPACEBAR' will be the shoot button.", 100, 251, font2, red)
Font.Draw ("Good Luck and Have Fun!", 100, 201, font2, red)
% Font.Draw ("To Return, press 'R'", maxx div 1.5, maxy div 7, font2, red)
Font.Draw ("To Start Press, 'S' ", maxx div 2. 3, maxy div 13, font2, red)
View.Update
end if
get chars2
if chars2 = ('S')
then
exit
elsif chars2 = ('R')
then
% end if
end if
end loop
end GameMenu
GameMenu
loop
drawfillbox (0, 0, maxx, maxy, 149)
drawfillbox (BoxX1, BoxY1, BoxX2, BoxY2, 31)
for d : 1 .. NumBall
drawfilloval (BallX (d ), BallY (d ), BallRadius, BallRadius, 31)
BallX (d ) := BallX (d ) + BallXV (d )
if BallX (d ) = maxx - BallRadius
then
NumBall := NumBall + 1
BallXV (NumBall ) := - 1
randint (BallX (NumBall ), 0, maxx) %X Position
randint (BallY (NumBall ), 0, maxy) %Y Position
BallXV (d ) := - 1
elsif
BallX (d ) = BallRadius
then
BallXV (d ) := 1
elsif
BallX (d ) = BoxX1 or BallX (d ) = BoxY1 or BallX (d ) = BoxX2 or BallX (d ) = BoxY2 and BallY (d )=BoxX1 or BallY (d )=BoxX2 or BallY (d )=BoxY1 or BallY (d )=BoxY2
then
exit
cls
put "You Lose"
end if
end for
View.Update
cls
%CONTROLS
Input.KeyDown (chars )
if chars (KEY_UP_ARROW) and BoxY2 <= maxy
then
BoxY1 := BoxY1 + 1
BoxY2 := BoxY2 + 1
elsif chars (KEY_DOWN_ARROW) and BoxY1 >= 0
then
BoxY1 := BoxY1 - 1
BoxY2 := BoxY2 - 1
elsif chars (KEY_RIGHT_ARROW) and BoxX1 <= maxx
then
BoxX1 := BoxX1 + 1
BoxX2 := BoxX2 + 1
elsif chars (KEY_LEFT_ARROW) and BoxX2 >= 0
then
BoxX2 := BoxX2 - 1
BoxX1 := BoxX1 - 1
end if
if chars (KEY_LEFT_ARROW) and chars (KEY_UP_ARROW) and BoxX2 >= 0 and BoxY2 <= maxy
then
delay (2)
BoxX2 := BoxX2 - 1
BoxX1 := BoxX1 - 1
BoxY1 := BoxY1 + 1
BoxY2 := BoxY2 + 1
end if
if chars (KEY_RIGHT_ARROW) and chars (KEY_UP_ARROW) and BoxY2 <= maxy and BoxX1 <= maxx
then
delay (2)
BoxX2 := BoxX2 + 1
BoxX1 := BoxX1 + 1
BoxY1 := BoxY1 + 1
BoxY2 := BoxY2 + 1
end if
if chars (KEY_RIGHT_ARROW) and chars (KEY_DOWN_ARROW) and BoxX1 <= maxx and BoxY1 >= 0
then
delay (2)
BoxX2 := BoxX2 + 1
BoxX1 := BoxX1 + 1
BoxY1 := BoxY1 - 1
BoxY2 := BoxY2 - 1
end if
if chars (KEY_LEFT_ARROW) and chars (KEY_DOWN_ARROW) and BoxY1 >= 0 and BoxX2 >= 0
then
delay (2)
BoxX2 := BoxX2 - 1
BoxX1 := BoxX1 - 1
BoxY1 := BoxY1 - 1
BoxY2 := BoxY2 - 1
end if
end loop |
|
|
|
|
|
 |
Nathan4102
|
Posted: Mon Jun 03, 2013 4:28 pm Post subject: RE:Array Ball Question |
|
|
Your method to find collisions is flawed. Take this image for example:
These two circles are colliding, but their x/y coordinates are not the same. You'll need to find another way to detect collisions.
Hint: If the balls have collided, how close are the two points from each other?
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
evildaddy911
|
Posted: Tue Jun 04, 2013 3:12 pm Post subject: Re: Array Ball Question |
|
|
Nathan, he's using a box for the player. that means that he needs a much more complex collision-checking algorithm than the simple "if distance < radSum".
The simplest way to check if a circle is colliding with a rectangle is to check if any of the corners of the rectangle is colliding with the circle. the easiest way to do that is to pretend that the corner is another circle with radius zero. then you use circle-circle collision detection (see situation #1)
Unfortunately, what if the ball is fully inside the square, like in situation #2? what will the method above say?
Note that the center of the circle is fully inside the square. and i'm sure you can figure out how to tell when a point is inside a rectangle
This leads us to situation #3. what if the circle is touching the side of the box, but none of the corners are inside the circle and the center of the circle isn't inside the box either? This is by far the hardest check of the three. There are many ways to solve this problem, but I think that the simplest way is to treat the centerpoint of each side as another corner and use the first method outlined.
The only problem with this solution is what if the ball just touches the rectangle, not getting near enough to any of the 8 "corners?" unfortunately, this method isn't perfect, but is very accurate with smaller rectangles. if the circle's diameter is the same (or larger) as the square's side length, this method will work pretty much all the time.
So, to sum up, first you want to create 8 "collision points." you check if each of these points are within the circle, then, if false, you want to check if the circle's center is inside of the rectangle. The 8-point method does have flaws, but odds are that the collision is going to be caught is the next frame or two, or you won't notice that the collision occurred in the first place.
Description: |
|
Filesize: |
2.65 KB |
Viewed: |
2683 Time(s) |

|
|
|
|
|
|
 |
Dreadnought
|
Posted: Tue Jun 04, 2013 8:09 pm Post subject: Re: Array Ball Question |
|
|
evildaddy911 wrote: Nathan, he's using a box for the player. that means that he needs a much more complex collision-checking algorithm than the simple "if distance < radSum".
Not very much more complex...
Take the point in the rectangle with x and y coordinates that are closest to the x and y coordinates of the center of the circle. Check if this point is within the circle.
Here's an example:
Turing: | const DEBUG := true % Set to false to hide the blue dot
const RADIUS := 20
const BOX_X1 := 200
const BOX_Y1 := 220
const BOX_X2 := 280
const BOX_Y2 := 260
fcn mid (a, b, c : int) : int
if a > b then
if b > c then
result b
else
result min (a, c )
end if
elsif a > c then
result a
else
result min (b, c )
end if
end mid
fcn check (cx, cy, r, bx1, by1, bx2, by2 : int) : boolean
var x : int := mid (bx1, cx, bx2 )
var y : int := mid (by1, cy, by2 )
if DEBUG then
Draw.FillOval (x, y, 3, 3, 9)
end if
result Math.Distance (cx, cy, x, y ) <= r
end check
View.Set ("offscreenonly")
loop
var circle_x, circle_y, dummy : int
Mouse.Where (circle_x, circle_y, dummy )
Draw.Box (BOX_X1, BOX_Y1, BOX_X2, BOX_Y2, 7)
if check (circle_x, circle_y, RADIUS, BOX_X1, BOX_Y1, BOX_X2, BOX_Y2 ) then
Draw.Oval (circle_x, circle_y, RADIUS, RADIUS, 10)
else
Draw.Oval (circle_x, circle_y, RADIUS, RADIUS, 12)
end if
View.Update
cls
end loop
|
|
|
|
|
|
 |
|
|