0

I've looked through every Breakout question and can't seem to fix my issue. Whenever I manage to get the Scoreboard visible/counting the ball will always collide then freeze on it. Right now I can't seem to have it visible anymore. In this current code the ball bounces around fine and resets with a click.

Any hints towards my issues - which appear to revolve around the GLabel label = initScoreboard(window), would be great thanks.

    //
        // breakout.c
        //
        // Computer Science 50
        // Problem Set 3
        //

        // standard libraries
        #define _XOPEN_SOURCE
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <time.h>

        // Stanford Portable Library
        #include <spl/gevents.h>
        #include <spl/gobjects.h>
        #include <spl/gwindow.h>

        // height and width of game's window in pixels
        #define HEIGHT 600
        #define 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 12.5

        // lives
        #define LIVES 3

        //Paddle dimensions
        #define padWIDTH 30
        #define padHEIGHT 3

        //BallWidth constants
        #define ballWidth 25 
        #define ballHeight 25

        // 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);
        GLabel scoreboard;

        int main(void)
        {
        // seed pseudorandom number generator
        srand48(time(NULL));

        // instantiate window
        GWindow window = newGWindow(WIDTH, 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;

        // Velocity initial speed    
        double velocityX = drand48()*2;
        double velocityY = drand48()+2;

        updateScoreboard(window, label, points);      

        //Ball paused until click
        waitForClick();     


        while(true)
        {

        //Create/Wait for Mouse Event       
        GEvent event = getNextEvent(MOUSE_EVENT);   
            if(event != NULL)
            {     
                //Detect mouse event 'movement' & move paddle with it. 
                if(getEventType(event) == MOUSE_MOVED)
                    {
                        double x = getX(event) - getWidth(paddle)/2;
                        setLocation(paddle, x, 500);
                    }

            }

         //Call move function at pre-set random velocities         
         move(ball, velocityX, velocityY);     

            //Bounce off right side
            if (getX(ball) + getWidth(ball) >= getWidth(window))  
            {
                velocityX = -velocityX;            
            }
            //Bounce off left side
            if (getX(ball) <= 0)
            {
                velocityX = -velocityX;            
            }   
                //Bounce off roof 
                if (getY(ball) - (getHeight(ball)/2) <= 0)
                {
                    velocityY = -velocityY;            
                }
                //Stop if hit the bottom & change counters, wait for click to reset
                if (getY(ball) + (getHeight(ball)/2) >= getHeight(window)) 
                {
                    lives -= 1;
                    velocityY = 0; velocityX = 0;      
                    setLocation(ball,(WIDTH/2)-(ballWidth/2), (HEIGHT/2)); 
                    while(velocityY == 0)
                      {         
                        GMouseEvent click = waitForEvent(MOUSE_EVENT);
                        if(getEventType(click) == MOUSE_CLICKED)
                        {
                                velocityX = drand48()*2;
                                velocityY = drand48()+2;
                                move(ball, velocityX, velocityY);                                 
                        }
                    }
                }
             pause(10);   


        //Detec collisions with object = ball
        GObject object = detectCollision(window, ball);     //check which side of the ball collides with which side of the GRect
                                                            //bounce the ball off accordingly
            if(object != NULL)
            {
                //reverse velocity when colliding with ball
                if(object == paddle)
                {
                    velocityY = -velocityY;
                }

                //revere velocity when colliding with brick, change counters & rm brick
                else if(strcmp(getType(object), "GRect")==0)
                {
                    velocityY = -velocityY;                
                    bricks -= 1;
                    points += 1;                
                    removeGWindow(window, object);
                    updateScoreboard(window, label, points);
                }
                //Do nothing if colliding with scoreboard label
                else if (strcmp(getType(object), "GLabel") == 0)
                {
                    return 0;                
                }


            }   
        }




        // wait for click before exiting
        waitForClick();

        // game over
        closeGWindow(window);
        return 0;
    }

    /**
     * Initializes window with a grid of bricks.
     */
    void initBricks(GWindow window)
    {
        for(int i = 0; i < ROWS; i++)
        {

            int brickPosHeight = 100;
            brickPosHeight += 10*i;
            for(int j = 0; j < COLS; j++)
            {
                int brickPosWidth = 10;
                brickPosWidth += 39*j;

                GRect brick = newGRect(brickPosWidth, brickPosHeight, 29, 5);

                setFilled(brick, true);       

                    if((j >= 0) && (j <= 2))
                    {
                        setColor(brick, "GREEN");
                        add(window, brick);                    
                    }
                        if((j > 2) && (j <= 6))
                        {
                            setColor(brick, "BLUE");
                            add(window, brick);                        
                        }
                        if((j > 6) && (j <= 10))
                        {
                            setColor(brick, "RED");
                            add(window, brick);                       
                        }
           }
       }    
    }

    /**
     * Instantiates ball in center of window.  Returns ball.
     */
    GOval initBall(GWindow window)
    {  
        GOval ball = newGOval(((WIDTH/2)-(ballWidth/2)), (HEIGHT/2), ballWidth, ballHeight);
        setFilled(ball, true);
        setColor(ball, "PINK");
        add(window, ball);
        return ball;
    }

    /**
     * Instantiates paddle in bottom-middle of window.
     */
    GRect initPaddle(GWindow window)
    {
        GRect paddle = newGRect((WIDTH/2)-(padWIDTH/2), 500, padWIDTH, padHEIGHT);
        setFilled(paddle, true);
        setColor(paddle, "BLUE");
        add(window, paddle);

        return paddle;
    }

    /**
     * Instantiates, configures, and returns label for scoreboard.
     */
    GLabel initScoreboard(GWindow window)
    {
        double labelX =getWidth(window);
        double labelY =getHeight(window);
        GLabel label = newGLabel("0");
        setFont(label, "Verdana-50");
        setColor(label, "GREEN");       
        setLocation(label, labelX, labelY);
        add(window, label);
        return label;    
    }

    /**
     * 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;
    }

1 Answer 1

0

Here's the problem:

           //Do nothing if colliding with scoreboard label
            else if (strcmp(getType(object), "GLabel") == 0)
            {
                return 0;                
            }

In reality, you're not doing nothing. You're executing return 0; from main, which means "terminate the program immediately and return a 0 to the calling program, the operating system."

A collision with the scoreboard is a don't-care event, so nothing should or needs to be done. The solution is to simply delete the entire else clause. Keep it simple! ;-)

If this answers your question, please click the check mark to accept. Let's keep up on forum maintenance. ;-)

2
  • Thanks, however the scoreboard is still not appearing with that change? Dec 7, 2015 at 20:28
  • All good, my scoreboard dimensions were off after all my fiddling, thanks! Dec 7, 2015 at 20:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .