0

in pset3 --> breakout I haven't been able to make the Scoreboard (label) to update after each brick broken or ball touching the bottom.

I am printing in the gedit terminal the values of "lives" and "points" to check if they are increasing and decreasing when brick breaks or and ball missed, and the print is correct but not in the Score board in the window.

Here I share my code:

    //
// 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 410

// number of rows of bricks
#define ROWS 5

// number of columns of bricks
#define COLS 10

// radius of ball in pixels
#define RADIUS 10

// lives
//#define LIVES 3
//#define POINTS 0

//BALL PARAMETERS
#define xCircle 190
#define yCircle 285
#define wCircle 30
#define hCircle 30



// 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 circle);
GOval circle;
void removeGWindow(GWindow gw, GObject gobj);

// variables for detect collision
GObject object;
GRect paddle;
GRect brick;

// initial velocity of bouncing
    double velocity = 5.0;

// number of lives and points initially
    int lives = 3;
    int points = 0;


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 circle = 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;


    // keep playing until game over
    while (lives > 0 && bricks > 0)
    {

     // instantiate scoreboard, centered in middle of window, just above ball
    GLabel label = initScoreboard(window);

    //******************BOUNCING******************        

    // bounce forever
    while (true)
    {       
        //Score board
        GLabel initScoreboard(GWindow window);                              

        move(circle, 0.1, velocity);

        // bounce off right edge of window
        if (getY(circle) + getHeight(circle) >= getHeight(window))
        {
            velocity = -velocity;           

        }

        // bounce off left edge of window
        else if (getY(circle) <= 0)
        {
            velocity = -velocity;
        }

        // linger before moving again
        pause(10); 

        // check for mouse event
        GEvent event = getNextEvent(MOUSE_EVENT);

        // if we heard one

        if (event != NULL)
        {
            // if the event was movement
            if (getEventType(event) == MOUSE_MOVED)
            {
                // ensure circle follows top cursor
                double x = getX(event) - getWidth(paddle) / 2;
                double y = 500;
                setLocation(paddle, x, y);
            }                      
        } 

     //Detect collision and bounce
     GObject object = detectCollision(window, circle);
     if (strcmp(getType(object), "GRect") == 0)
         {
            if(object != paddle)
           {                
                removeGWindow(window, object);
                points = points + 1;
                lives = lives + 1;
                printf("points = %i\n", points);
                printf("lives = %i\n", lives);                                                                                                                      
            }

            velocity = - velocity;                           

         }

     //detects when ball touches bottom edge and takes out one life and point.
     double yLow = getY(circle);  
     if(yLow == 570)
     {      
        lives = lives -1;
        points = points - 1;
        printf("liveLow = %i\n", lives);

        pause(1000);       
     }

     }    
  }

    // wait for click before exiting
    waitForClick();

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

/**
 * Initializes window with a grid of bricks.
 */
void initBricks(GWindow window)
{
    // TODO: EL ---> use pair of for loops nested. In the innermost loop use GRect with W and H and color
    for(int i = 0; i < ROWS; i++)
    {    
        int level = i+1;

        for(int j = 0; j < COLS; j++)
        {
            GRect brick = newGRect((70*j) + 5, (10*level) + 5, 50, 5);
            setFilled(brick, true);
            setColor(brick, "BLACK");
            add(window, brick);         
        }

    }

}

/**
 * Instantiates ball in center of window.  Returns ball.
 */
GOval initBall(GWindow window)
{
    // instantiates circle

    GOval circle = newGOval(190, 285, 30, 30);
    setFilled(circle, true);
    setColor(circle, "RED");

    // add circle to window
    add(window, circle);

    return circle;
}

/**
 * Instantiates paddle in bottom-middle of window.
 */
GRect initPaddle(GWindow window)
{
    // TODO: use GRect

    GRect paddle = newGRect(155, 500, 100, 10);
    setFilled(paddle, true);
    setColor(paddle, "BLUE");
    add(window, paddle); 

    return paddle;
}

/**
 * Instantiates, configures, and returns label for scoreboard.
 */
GLabel initScoreboard(GWindow window)
{
    // TODO: use GLabel which is a char*

    // instantiate label
    GLabel label = newGLabel("");
    setFont(label, "SansSerif-36");
    add(window, label);


    // to store 50 through 0 (with '\0'), we need <= 3 chars
        char s[12];

        // convert i from int to string
        sprintf(s, "%i", points + lives);

        // update label
        setLabel(label, s);

        // center label
        double xLabel = (getWidth(window) - getWidth(label)) / 2;
        double yLabel = 300;      
        setLocation(label, xLabel, yLabel);       

    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 = 300;
    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 circle)
{
    // ball's location
    double x = getX(circle);
    double y = getY(circle);

    // 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

1

Looking at your code, I see two issues. First, you call initScoreboard twice, once before starting the while loop and once just inside the loop, without assigning the object to a variable. Instantiating the scoreboard once should be enough. I think that doing it with every pass through the loop will just cause problems.

 // instantiate scoreboard, centered in middle of window, just above ball
GLabel label = initScoreboard(window);

//******************BOUNCING******************        

// bounce forever
while (true)
{       
    //Score board
    GLabel initScoreboard(GWindow window);   

Next, you never actually call the updateScoreboard() function to update the scoreboard object label.

Running your program shows that there are other issues, but that's for another day and another question, should you not be able to resolve them.

If this answers your question, please accept this answer to remove the question from the unanswered question pool. Let's keep up on forum housekeeping. ;-)

You must log in to answer this question.

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