Last active
June 8, 2016 19:35
-
-
Save rmalkevy/46cfce355882c3e23355a8c5aa43cf8f to your computer and use it in GitHub Desktop.
BallPaddle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Malkevych Roman Ihorovych | |
// 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 | |
// height and width of paddle | |
#define PHEIGHT 10 | |
#define PWIDTH 50 | |
// 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); | |
void removeGWindow(GWindow gw, GObject gobj); | |
GLabel initWin(GWindow window); | |
GLabel initLose(GWindow window); | |
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; | |
// initial speed | |
double speedX = 0.0; | |
if(drand48() > 0.0) | |
{ | |
if(drand48() < 0.5) | |
speedX = 4.0 * drand48(); | |
else | |
speedX = 4.0 * drand48() * (-1); | |
} | |
double speedY = 3.0; | |
waitForClick(); | |
// keep playing until game over | |
while (lives > 0 && bricks > 0) | |
{ | |
// Move Mouse - Move Paddle | |
/**************************/ | |
// 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 paddle follows top cursor | |
double x = getX(event) - getWidth(paddle)/2; | |
double y = 0.9 * HEIGHT - PHEIGHT; | |
setLocation(paddle, x, y); | |
} | |
} | |
// bounce forever BALL BALL BALL BALL | |
/************************************/ | |
// move ball | |
move(ball, speedX, speedY); | |
// Detect collision | |
GObject object = detectCollision(window, ball); | |
// bounce off right edge of window | |
if (getX(ball) + getWidth(ball) >= getWidth(window)) | |
{ | |
speedX = -speedX; | |
} | |
// bounce off left edge of window | |
else if (getX(ball) <= 0) | |
{ | |
speedX = -speedX; | |
} | |
// top | |
else if (getY(ball) <= 0) | |
{ | |
speedY = -speedY; | |
} | |
// padlle | |
else if (object == paddle) | |
{ | |
speedY = -abs(speedY); | |
} | |
// bottom | |
else if (getY(ball) + getHeight(ball) >= getHeight(window)) | |
{ | |
lives--; | |
if(lives > 0) | |
{ | |
setLocation(ball, WIDTH/2 - RADIUS, HEIGHT/2 - RADIUS); | |
setLocation(paddle, (WIDTH - PWIDTH)/2, HEIGHT * 0.9 - PHEIGHT); | |
// check for mouse event | |
waitForClick(); | |
// move ball | |
move(ball, speedX, speedY); | |
} | |
} | |
// remove bricks == blocks | |
else if((object != NULL)) | |
{ | |
if((object != paddle) && (object != label) && (object != ball)) | |
{ | |
speedY = -speedY; | |
removeGWindow(window, object); | |
bricks--; | |
points++; | |
// Scoreboard | |
updateScoreboard(window, label, points); | |
} | |
} | |
// linger before moving again | |
pause(10); | |
} | |
// Print Win!!!!!!! | |
if(bricks == 0) | |
{ | |
GLabel win = initWin(window); | |
} | |
// Print loser!!!!! | |
else if((lives <= 0) && (bricks > 0)) | |
{ | |
GLabel lose = initLose(window); | |
} | |
// wait for click before exiting | |
waitForClick(); | |
// game over | |
closeGWindow(window); | |
return 0; | |
} | |
/** | |
* Initializes window with a grid of bricks. | |
*/ | |
void initBricks(GWindow window) | |
{ | |
double x = WIDTH/10; | |
double y = HEIGHT/40; | |
for(int i = 0; i < (COLS * x); i += x) | |
{ | |
for(int j = 0, a = 0; j < (ROWS * y); j = j + y, a++) | |
{ | |
GRect block = newGRect(2 + i, y + j, x - 5, y - 5); | |
string arrColor[] = {"GREEN", "ORANGE", "PINK", "CYAN", "MAGENTA"}; | |
setColor(block, arrColor[a]); | |
setFilled(block, true); | |
add(window, block); | |
} | |
} | |
} | |
/** | |
* Instantiates ball in center of window. Returns ball. | |
*/ | |
GOval initBall(GWindow window) | |
{ | |
// instantiate ball | |
double x = WIDTH / 2 - RADIUS; | |
double y = HEIGHT / 2 - RADIUS; | |
GOval ball = newGOval(x, y, RADIUS * 2, RADIUS * 2); | |
setColor(ball, "BLUE"); | |
setFilled(ball, true); | |
add(window, ball); | |
return ball; | |
} | |
/** | |
* Instantiates paddle in bottom-middle of window. | |
*/ | |
GRect initPaddle(GWindow window) | |
{ | |
double x = (WIDTH - PWIDTH) / 2; | |
double y = 0.9 * HEIGHT - PHEIGHT; | |
GRect paddle = newGRect(x, y, PWIDTH, PHEIGHT); | |
setColor(paddle, "BLACK"); | |
setFilled(paddle, true); | |
add(window, paddle); | |
return paddle; | |
} | |
/** | |
* Instantiates, configures, and returns label for scoreboard. | |
*/ | |
GLabel initScoreboard(GWindow window) | |
{ | |
GLabel label = newGLabel(" "); | |
setFont(label, "Arial-20"); | |
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); | |
setFont(label, "Arial-25"); | |
// center label in window | |
double x = (getWidth(window) - getWidth(label)) / 2; | |
double y = getHeight(window) - getHeight(label); | |
setLocation(label, x, y); | |
} | |
/** | |
* Label for winner!!!!! | |
*/ | |
GLabel initWin(GWindow window) | |
{ | |
GLabel win = newGLabel("Win!"); | |
setFont(win, "Arial-30"); | |
add(window, win); | |
// center win in window | |
double x = (getWidth(window) - getWidth(win)) / 2; | |
double y = (getHeight(window) - getHeight(win)) / 2; | |
setLocation(win, x, y); | |
return win; | |
} | |
/** | |
* Label for loser!!!!! | |
*/ | |
GLabel initLose(GWindow window) | |
{ | |
GLabel lose = newGLabel("Loser! Hahha"); | |
setFont(lose, "Arial-30"); | |
add(window, lose); | |
// center lose in window | |
double x = (getWidth(window) - getWidth(lose)) / 2; | |
double y = (getHeight(window) - getHeight(lose)) / 2; | |
setLocation(lose, x, y); | |
return lose; | |
} | |
/** | |
* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment