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