Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Array Ball Question
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Thatguy




PostPosted: 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
Sponsor
sponsor
Zren




PostPosted: 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




PostPosted: 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




PostPosted: 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




PostPosted: 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




PostPosted: 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




PostPosted: 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




PostPosted: 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:

Posted Image, might have been reduced in size. Click Image to view fullscreen.

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
Sponsor
sponsor
evildaddy911




PostPosted: 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.



ball-box collision diagram.png
 Description:
Collision diagram
 Filesize:  2.65 KB
 Viewed:  2683 Time(s)

ball-box collision diagram.png


Dreadnought




PostPosted: 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
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 10 Posts ]
Jump to:   


Style:  
Search: