Thread: Ball keeps bouncing off paddle in same direction

  1. #1
    Registered User
    Join Date
    Apr 2014
    Posts
    21

    Ball keeps bouncing off paddle in same direction

    Hello I am working on a problem for the cs50 class through edx. I am creating a version breakout. My ball keeps bouncing off the paddle to the left no matter where it hits the paddle at. It uses the standford portable library. If some one could just take a look at my code and let me know where i went wrong.

    Code:
    #define _XOPEN_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    
    // Stanford Portable Library
    #include "gevents.h"
    #include "gobjects.h"
    #include "gwindow.h"
    
    
    // height and width of game's window in pixels
    #define WINDOW_HEIGHT 600
    #define WINDOW_WIDTH 400
    
    
    // number of rows of bricks
    #define ROWS 5
    
    
    // number of columns of bricks
    #define COLS 10
    
    
    // radius of ball in pixels
    #define RADIUS 10
    
    
    // width of paddle
    #define PADDLE_WIDTH 60
    
    
    //height of paddle
    #define PADDLE_HEIGHT 10
    
    
    // lives
    #define LIVES 3
    
    
    // Width of bricks
    #define BRICK_WIDTH 35
    
    
    //height of bricks
    #define BRICK_HEIGHT 10
    
    
    
    
    // prototypes
    void initBricks(GWindow window);
    GOval initBall(GWindow window);
    GRect initPaddle(GWindow window);
    GLabel initScoreboard(GWindow window);
    void updateScoreboard(GWindow window, GLabel label, int points);
    GObject detectCollision(GWindow window, GOval ball);
    string assignColor(int row);
    void bounce_ball_wall(GObject window , GObject ball, double *velocity, double *x_point, double *y_point);
    
    
    int main(void)
    {
        // seed pseudorandom number generator
        srand48(time(NULL));
    
    
        // instantiate window
        GWindow window = newGWindow(WINDOW_WIDTH, WINDOW_HEIGHT);
    
    
        // instantiate bricks
        initBricks(window);
    
    
        // instantiate ball, centered in middle of window
        GOval ball = initBall(window);
    
    
        // instantiate paddle, centered at bottom of window
        GRect paddle = initPaddle(window);
    
    
        // instantiate scoreboard, centered in middle of window, just above ball
        GLabel label = initScoreboard(window);
    
    
        // number of bricks initially
        int bricks = COLS * ROWS;
    
    
        // number of lives initially
        int lives = LIVES;
    
    
        // number of points initially
        int points = 0;
    
    
        //balls speed
        double velocity = 2.0;
    
    
        //ball's postion
        double x_point = (rand() % 2) + 1.0;
        double y_point = velocity; 
    
    
    
    
    // need to make direction random 
    
    
        // keep playing until game over
        while (lives > 0 && bricks > 0)
        {
            //Mouse vent for paddle
            GEvent event = getNextEvent(MOUSE_EVENT);
    
    
            //paddle movement --------------------------------->
            if ( event != NULL ) 
            {
                if ( getEventType(event) == MOUSE_MOVED )
                {
                    double x = getX(event) - getWidth(paddle) / 2;
                    double y = getY(paddle);
    
    
                    // keep paddle from going off screen
                    if (x >= 0 && (x + getWidth(paddle) <= 400))
                        setLocation(paddle, x, y);
                }
    
    
            } //------------------------------------------------<
          
    
            bounce_ball_wall(window, ball, &velocity, &x_point, &y_point);
            
            //check what ball is Collides with 
            GObject hits = detectCollision(window, ball);
            
            if(hits == paddle)
            {
    
                //bottom ball top of paddle
                if (getY(ball) + getHeight(ball) >= getY(paddle))
                {
                    x_point = -velocity;
                    y_point = -velocity;
                   // y_point =  (rand() % 2) + 1.0;
               }
    
                 //top ball bottom paddle
               if (getY(ball) >= getY(paddle) + getHeight(paddle))
                {
                    x_point = velocity;
                    y_point = velocity;
                } 
    
                //right ball left of paddle
                if (getX(ball) + getWidth(ball) >= getX(paddle))
                {
                    x_point = -velocity;
                    y_point = -velocity;
                }
    
                //left ball right of paddle
                if (getX(ball) <= getX(paddle) + getWidth(paddle))
                {
                    x_point = velocity;
                    y_point = velocity;
                }
            }
        }
        // wait for click before exiting
        waitForClick();
    
        // game over
        closeGWindow(window);
        return 0;
    }
    
    
    /**
     * Initializes window with a grid of bricks.
     */
    void initBricks(GWindow window)
    {
       GRect bricks[5][10];
    
        //first brick postion
        int x = 2, y = 50;
    
        for (int i = 0; i < 5; i++) 
        {
            for (int j = 0; j < 10; j++) 
            {
                if ( j == 0 ) 
                {
                    x = 2;
                    bricks[i][j] = newGRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
                } 
                else 
                {
                    bricks[i][j] = newGRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
                }
               
                add(window, bricks[i][j]);
                setFilled(bricks[i][j], true);
                setColor(bricks[i][j], assignColor(i));
                x += 40;
            }
            y += 15;
        }
    }
    
    
    /**
     * Instantiates ball in center of window.  Returns ball.
     */
    GOval initBall(GWindow window)
    {
        GOval ball = newGOval((WINDOW_WIDTH / 2 ) , (WINDOW_HEIGHT / 2) , 20, 20);
        add(window, ball);
        setFilled(ball, true);
        setColor(ball, "BLACK");
        return ball;
    }
    
    
    /**
     * Instantiates paddle in bottom-middle of window.
     */
    GRect initPaddle(GWindow window)
    {
        GRect paddle = newGRect(170, 540, PADDLE_WIDTH, PADDLE_HEIGHT);
        add(window, paddle);
        setFilled(paddle, true);
        setColor(paddle, "BLACK");
    
        return paddle;
    }
    
    
    /**
     * Instantiates, configures, and returns label for scoreboard.
     */
    GLabel initScoreboard(GWindow window)
    {
        // TODO
        return NULL;
    }
    
    
    /**
     * Updates scoreboard's label, keeping it centered in window.
     */
    void updateScoreboard(GWindow window, GLabel label, int points)
    {
        // update label
        char s[12];
        sprintf(s, "%i", points);
        setLabel(label, s);
    
        // center label in window
        double x = (getWidth(window) - getWidth(label)) / 2;
        double y = (getHeight(window) - getHeight(label)) / 2;
        setLocation(label, x, y);
    }
    
    
    /**
     * Detects whether ball has collided with some object in window
     * by checking the four corners of its bounding box (which are
     * outside the ball's GOval, and so the ball can't collide with
     * itself).  Returns object if so, else NULL.
     */
    GObject detectCollision(GWindow window, GOval ball)
    {
        // ball's location
        double x = getX(ball);
        double y = getY(ball);
    
        // for checking for collisions
        GObject object;
    
        // check for collision at ball's top-left corner
        object = getGObjectAt(window, x, y);
        if (object != NULL)
        {
            return object;
        }
    
        // check for collision at ball's top-right corner
        object = getGObjectAt(window, x + 2 * RADIUS, y);
        if (object != NULL)
        {
            return object;
        }
    
        // check for collision at ball's bottom-left corner
        object = getGObjectAt(window, x, y + 2 * RADIUS);
        if (object != NULL)
        {
            return object;
        }
    
        // check for collision at ball's bottom-right corner
        object = getGObjectAt(window, x + 2 * RADIUS, y + 2 * RADIUS);
        if (object != NULL)
        {
            return object;
        }
    
        // no collision
        return NULL;
    }
    
    /**
     * takes the row number and returns the color
     * for that row as a string. 
     * */
    string assignColor(int row)  //try to validate
    {
        switch ( row ) {
            case 0:    
                return "RED";
                break;
    
            case 1:    
                return "ORANGE";
                break;
    
            case 2:    
                return "YELLOW";
                break;
    
            case 3:    
                return "GREEN";
                break;
    
            case 4:    
                return "CYAN";
                break;
    
            default:    
                return "BLACK";  //NULL ?
                break;
        }
    }
    
    /**
     * Bounces ball by changing velocity depending on  its postion  
     * in the window
     */
    void bounce_ball_wall(GObject window , GObject ball, double *velocity, 
            double *x_direction, double *y_direction)
    {
    
            move(ball, *x_direction, *y_direction);
    
            //right wall
            if (getX(ball) + getWidth(ball) >= getWidth(window)) 
                *x_direction = -(*velocity);    
    
            //left wall
            if (getX(ball) <= 0) 
                *x_direction = (*velocity);
    
            //bottom
            if (getY(ball) + getHeight(ball) >= getHeight(window)) 
                *y_direction = -(*velocity);
    
            //top
            if (getY(ball) <= 0) 
                *y_direction = (*velocity);
     
            pause(10);
    }
    Last edited by arortell; 04-30-2014 at 01:29 PM.

  2. #2
    Registered User
    Join Date
    Apr 2014
    Location
    New York
    Posts
    52
    I know I'm a beginner, so I can't help much, but you have a #define and an #include in line one. It gave me an error.

  3. #3
    Registered User
    Join Date
    Apr 2014
    Posts
    21
    Quote Originally Posted by shaddock View Post
    I know I'm a beginner, so I can't help much, but you have a #define and an #include in line one. It gave me an error.
    That must have happened during copy and paste. Thanks.

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by arortell View Post
    Hello I am working on a problem for the cs50 class through edx. I am creating a version breakout. My ball keeps bouncing off the paddle to the left no matter where it hits the paddle at. It uses the standford portable library.
    Is it possible to download the Stanford Portable Library so that it can be compiled on the users machine? I see references to it and one of the professors has posted a C++ version, but I don't see a publicly available implementation that uses the C interface which you seem to be using.

  5. #5
    Registered User
    Join Date
    Apr 2014
    Posts
    21
    I have not been able to find it I looked for it also the version that came with the outline for the project is all compiled in 32 bit so I have to work out of a 32bit vmware machine.. Here is link to the outline of the version that came with the project for the class.' wget http://cdn.cs50.net/2013/fall/psets/4/pset4/pset4.zip'

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    If it were able to run your program easily it would be better. Maybe I will try it later to see what happens. In the meantime you could look at what happens when the ball collides with the paddle. It is here and there are four possibilities:

    Code:
            if(hits == paddle)
            {
     
                //bottom ball top of paddle
                if (getY(ball) + getHeight(ball) >= getY(paddle))
                {
                    x_point = -velocity;
                    y_point = -velocity;
                   // y_point =  (rand() % 2) + 1.0;
               }
     
                 //top ball bottom paddle
               if (getY(ball) >= getY(paddle) + getHeight(paddle))
                {
                    x_point = velocity;
                    y_point = velocity;
                } 
     
                //right ball left of paddle
                if (getX(ball) + getWidth(ball) >= getX(paddle))
                {
                    x_point = -velocity;
                    y_point = -velocity;
                }
     
                //left ball right of paddle
                if (getX(ball) <= getX(paddle) + getWidth(paddle))
                {
                    x_point = velocity;
                    y_point = velocity;
                }
            }
    At this point you should use debugging techniques (step through with a debugger or else just print out some debugging statements) to figure out which branch you are going into and modify it accordigly (e.g. to make it bounce to the other direction instead). This is the kind of thing where it's probably easiest to experiment with the settings. There are only four cases, so it is feasible.

    Also your members "x_point" and "y_point" seem to represent directions rather than "points" (compare with your bounce_ball_wall function). In this case, wouldn't it make sense that only one direction changes? -- Again compare with the bounce_ball_wall function and see how it only changes one of x_direction or y_direction depending on what collision occurs.

    Edit: I think it would be easier if you make an analogous function bounce_ball_paddle - it should work the similarly to your bouce_ball_wall fuction. Invoke it whenever you detect the collision with the paddle in your event loop.
    Last edited by c99tutorial; 04-30-2014 at 02:25 PM.

  7. #7
    Registered User
    Join Date
    Apr 2014
    Posts
    21
    I fixed it I had one of those conditions backwards thanks for trying.

  8. #8
    Registered User
    Join Date
    Apr 2014
    Posts
    21
    Ho do I close this?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bouncing a ball
    By ammad in forum C++ Programming
    Replies: 16
    Last Post: 08-27-2009, 05:02 PM
  2. Bouncing Ball
    By The Brain in forum Windows Programming
    Replies: 12
    Last Post: 12-29-2006, 08:56 AM
  3. The Old Bouncing Ball
    By bartybasher in forum Game Programming
    Replies: 3
    Last Post: 08-19-2003, 03:06 AM
  4. Bouncing ball
    By SKINp in forum Game Programming
    Replies: 4
    Last Post: 01-13-2003, 02:26 PM
  5. Bouncing ball
    By motocross95 in forum Game Programming
    Replies: 10
    Last Post: 01-07-2002, 09:25 AM