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