I can't for the life of me figure out why my scoreboard won't appear in the middle of the screen. I checked out the question @Agata S. posted (link below) but it didn't help me resolve my code's bug. Can anyone offer advice?
Pset3 (breakout) -- problems initiating score label
//
// 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 paddle
#define pHeight 8
#define pWidth 50
// height and width of game's window in pixels
#define HEIGHT 500
#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 10
// lives
#define LIVES 3
// 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);
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;
// initiate velocity vectors
double dx = 2.0;
double dy = 1.0;
// keep playing until game over
while (lives > 0 && bricks > 0)
{
move (ball, dx, dy);
pause (20);
GEvent event = getNextEvent(MOUSE_EVENT);
if (event!=NULL)
{
if (getEventType(event)==MOUSE_MOVED)
{
double px = (getX(event) - (pWidth/2));
double py = HEIGHT - pHeight;
setLocation(paddle,px,py);
}
}
GObject object = detectCollision(window, ball);
if (object != NULL)
{
dy = -dy;
if (object != paddle)
{
bricks = bricks-1;
points = points+100;
removeGWindow(window, object);
}
}
if ((getX(ball)+getWidth(ball))>=WIDTH)
dx = -dx;
if (getX(ball)<=0)
dx = -dx;
if (getY(ball)<=0)
dy = -dy;
if ((getY(ball)+getWidth(ball))>=HEIGHT)
{
lives = lives-1;
points = points + 100;
updateScoreboard(window, label, points);
removeGWindow(window, ball);
waitForClick();
ball = initBall(window);
}
}
// 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 c=0; c<COLS; c++)
{
for (int r=0; r<ROWS; r++)
{
int bw = (WIDTH/10)-6;
int bh = 10;
GRect brick = newGRect((7+ c*(5+bw)),(7+ r*(bh+5)+5), bw, bh);
setFilled(brick, true);
if (r==0)
setColor(brick, "RED");
if (r==1)
setColor(brick, "ORANGE");
if (r==2)
setColor(brick, "YELLOW");
if (r==3)
setColor(brick, "GREEN");
if (r==4)
setColor(brick, "BLUE");
add(window, brick);
}
}
}
/**
* Instantiates ball in center of window. Returns ball.
*/
GOval initBall(GWindow window)
{
GOval ball = newGOval((WIDTH/2)-RADIUS, (HEIGHT/2)-RADIUS, (2*RADIUS), (2*RADIUS));
setFilled(ball, true);
setColor(ball, "BLACK");
add(window, ball);
return ball;
}
/**
* Instantiates paddle in bottom-middle of window.
*/
GRect initPaddle(GWindow window)
{
GRect paddle = newGRect(((WIDTH-pWidth)/2), (HEIGHT - pHeight), pWidth, pHeight);
setFilled(paddle, true);
setColor(paddle, "ORANGE");
add (window, paddle);
return paddle;
}
/**
* Instantiates, configures, and returns label for scoreboard.
*/
GLabel initScoreboard(GWindow window)
{
int x = WIDTH/2;
int y = HEIGHT/2;
GLabel label = newGLabel("0");
setColor(label, "BLACK");
add(window, label);
setLocation(label, x, y );
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;
}