Page 1 of 1

Breakout Clone

Posted: Sat Dec 12, 2009 9:58 pm
by dejai
Sorry for the delay since my last post, but I have some more code for you. This time a break out clone. www.dejai.org where you can find all my projects and source code. I have some free time now so I am coding again :)

Code: Select all


/* main.c
 * Author: Ben Wright
 * Date: 12th December 2009
 * Description: A simple breakout clone written in SDL.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#include "SDL.h"
#include "SDL_opengl.h"

#define SCREEN_HEIGHT 480
#define SCREEN_WIDTH 640
#define SCREEN_BPP 32

#define BAT_WIDTH 60
#define BAT_HEIGHT 20

#define BAT_WALL_SPACE (SCREEN_HEIGHT - BAT_HEIGHT)
#define BAT_SPEED 10

#define BALL_WIDTH 20
#define BALL_HEIGHT 20
#define BALL_SPEED 5

#define NUM_BLOCKS (NUM_BLOCK_ROWS*NUM_BLOCK_COLUMNS)
#define NUM_BLOCK_ROWS 5
#define NUM_BLOCK_COLUMNS 12
#define BLOCK_WIDTH 40
#define BLOCK_HEIGHT 20
#define BLOCK_SPACE_WIDTH (15+BLOCK_WIDTH)
#define BLOCK_SPACE_HEIGHT (15+BLOCK_HEIGHT)

#define SCREEN_LEFT 0
#define SCREEN_RIGHT (SCREEN_WIDTH - BAT_WIDTH)

#define SCREEN_TOP 0

#define MAX_SCORE 10
#define NUM_LIVES 3

typedef struct game* Game;

typedef struct {
	int directionx;
	int directiony;
	SDL_Rect node; // The resource that's drawn.
} ball;

typedef struct {
	bool playable; // Determine whether a computer or keyboard input will play this bat.
	int score; // Each bat has it's own score.
	int lives;
	SDL_Rect node; // The resource that's drawn.
} bat;


// Stores all objects to be used in game
struct game {
	bool running;
	bat bat1;
	ball ball1;
	SDL_Rect blocks[NUM_BLOCK_ROWS][NUM_BLOCK_COLUMNS];
	Uint8 *key; // Array that holds what keys are pressed
	SDL_Event event;
	SDL_Surface* screen;
};

Game initGame();
void closeGame(Game gameToBeClosed);

void handleEvents(Game breakout);
void update(Game breakout);
void draw(Game breakout);

void updateBall(Game breakout);
void resetBall(Game breakout);

void loadBlocks(Game breakout);

bool hasCollided(SDL_Rect block1ToCheck, SDL_Rect  block2ToCheck);

int main(int argc, char *argv[]) {
	Game breakout;
	breakout = initGame();
	
	while ( breakout->running ) {
		handleEvents(breakout);
		update(breakout);
		draw(breakout);
	}
	
	SDL_Quit();
	closeGame(breakout);
	
	return EXIT_SUCCESS;
}

Game initGame() {
	Game newGame = malloc(sizeof(struct game));
	
	SDL_Init(SDL_INIT_EVERYTHING);
	newGame->screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); 
	SDL_WM_SetCaption("SmashOut",NULL);
	
	newGame->ball1.node.w = BALL_WIDTH;
	newGame->ball1.node.h = BALL_HEIGHT;
	newGame->ball1.node.x = SCREEN_WIDTH / 2;
	newGame->ball1.node.y = SCREEN_HEIGHT / 2; 
	newGame->ball1.directionx = 1;
	newGame->ball1.directiony = 1;

	newGame->bat1.node.w = BAT_WIDTH;
	newGame->bat1.node.h = BAT_HEIGHT;
	newGame->bat1.node.x = SCREEN_WIDTH / 2;
	newGame->bat1.node.y = BAT_WALL_SPACE;
	newGame->bat1.lives = NUM_LIVES;
	
	loadBlocks(newGame);
	
	newGame->key = SDL_GetKeyState(NULL);
	
	newGame->running = true;
	
	return newGame;
}

void closeGame(Game gameToBeClosed) {
	free(gameToBeClosed);
}

void handleEvents(Game breakout) {
	while ( SDL_PollEvent(&breakout->event) ) {
		switch ( breakout->event.type ) {
			case SDL_QUIT:
				breakout->running = false;
		}
	}
	
	if ( breakout->key[SDLK_a] && breakout->bat1.node.x > SCREEN_LEFT ) {
		breakout->bat1.node.x -= BAT_SPEED;
	} else if ( breakout->key[SDLK_d] && breakout->bat1.node.x < SCREEN_RIGHT ) {
		breakout->bat1.node.x += BAT_SPEED;
	}
	
}

void update(Game breakout) {
	breakout->key = SDL_GetKeyState(NULL);
	if ( breakout->bat1.lives <= 0 ) {
		loadBlocks(breakout);
		breakout->bat1.lives = NUM_LIVES;
	}
	updateBall(breakout);
}

void draw(Game breakout) {
	SDL_FillRect(breakout->screen , NULL , SDL_MapRGB(breakout->screen->format , 0 , 0 , 0 ));
	
	SDL_FillRect(breakout->screen , &breakout->bat1.node , SDL_MapRGB(breakout->screen->format , 0 , 255 , 50 ) );
	SDL_FillRect(breakout->screen , &breakout->ball1.node , SDL_MapRGB(breakout->screen->format ,  0 , 255 , 50 ) );
	
	int row, column;
	for ( row=0; row < NUM_BLOCK_ROWS; row++ ) {
		for ( column=0; column < NUM_BLOCK_COLUMNS; column++ ) {
			if (breakout->blocks[row][column].w != 0) {
				SDL_FillRect(breakout->screen , &breakout->blocks[row][column] , SDL_MapRGB(breakout->screen->format ,  150 , row*20 , column*20) );
			}
		}
	}
	
	SDL_Flip(breakout->screen);
}

void updateBall(Game breakout) {
	if ( (breakout->ball1.node.y + BALL_HEIGHT) >= SCREEN_HEIGHT ) {
		breakout->bat1.score += 1;
		breakout->bat1.lives -= 1;
		resetBall(breakout);
	}
	if ( breakout->bat1.score > MAX_SCORE ) {
		breakout->bat1.score = 0;
	}
	
	if ( hasCollided(breakout->bat1.node, breakout->ball1.node) ) {
		breakout->ball1.directiony = -1;
	}
	
	if ( (breakout->ball1.node.x + BALL_WIDTH) >= SCREEN_WIDTH)  {
		breakout->ball1.directionx = -1;
	} else if ( breakout->ball1.node.x <= 0 ) {
		breakout->ball1.directionx = 1;
	}
	
	if ( breakout->ball1.node.y <= SCREEN_TOP ) {
		breakout->ball1.directiony = 1;
	}
	
	int row, column;
	for ( row=0; row < NUM_BLOCK_ROWS; row++ ) {
		for ( column=0; column < NUM_BLOCK_COLUMNS; column++ ) {
			if ( hasCollided(breakout->ball1.node, breakout->blocks[row][column]) && (breakout->blocks[row][column].w !=0) ) {
				breakout->blocks[row][column].w = 0;
				breakout->blocks[row][column].h = 0;
				breakout->ball1.directiony = 1;
			}
		}
	}
	
	breakout->ball1.node.x  += (breakout->ball1.directionx * BALL_SPEED);
	breakout->ball1.node.y += (breakout->ball1.directiony * BALL_SPEED);
}

void resetBall(Game breakout){
	breakout->ball1.node.w = BALL_WIDTH;
	breakout->ball1.node.h = BALL_HEIGHT;
	breakout->ball1.node.x = SCREEN_WIDTH / 2;
	breakout->ball1.node.y = SCREEN_HEIGHT / 2; 
}

void loadBlocks(Game breakout) {
	int row, column;
	for ( row=0; row < NUM_BLOCK_ROWS; row++ ) {
		for ( column=0; column < NUM_BLOCK_COLUMNS; column++ ) {
			breakout->blocks[row][column].w = BLOCK_WIDTH;
			breakout->blocks[row][column].h = BLOCK_HEIGHT;
			breakout->blocks[row][column].x = BLOCK_SPACE_WIDTH * column;
			breakout->blocks[row][column].y = BLOCK_SPACE_HEIGHT * row;
		}
	}
}

bool hasCollided (SDL_Rect block1ToCheck, SDL_Rect  block2ToCheck) {
	bool collision = true;
	
	int block1Top, block1Bottom;
	int block1Left, block1Right;
	
	int block2Top, block2Bottom;
	int block2Left, block2Right;
	
	block1Top = block1ToCheck.y;
	block1Bottom = block1ToCheck.y + block1ToCheck.h;
	block1Left = block1ToCheck.x;
	block1Right = block1ToCheck.x + block1ToCheck.w;
	
	block2Top = block2ToCheck.y;
	block2Bottom = block2ToCheck.y + block2ToCheck.h;
	block2Left = block2ToCheck.x;
	block2Right = block2ToCheck.x + block2ToCheck.w;
	
	if( block1Bottom <= block2Top ) {
		collision = false;
	} else if( block1Top >= block2Bottom ) {
		collision = false;
	} else if( block1Right <= block2Left) {
		collision = false;
	} else if( block1Left >= block2Right ) {
		collision = false;
	}
	
	return collision;
}

Re: Breakout Clone

Posted: Sat Dec 12, 2009 10:48 pm
by Master Jake
Can you include this file in your post?

Code: Select all

#include <stdbool.h>
=)

Re: Breakout Clone

Posted: Sat Dec 12, 2009 10:54 pm
by dejai
It's part of the C Standard Library (C99) : http://www.opengroup.org/onlinepubs/000 ... ool.h.html . Why the request?

Re: Breakout Clone

Posted: Sat Dec 12, 2009 10:57 pm
by Master Jake
Sorry, I've actually never used that header file, and my compiler isn't finding it.

First I thought it was a typo that you were including with angle-brackets and that it was a local project header file.

Re: Breakout Clone

Posted: Sat Dec 12, 2009 11:00 pm
by dejai
Your compiler should have stdbool.h what compiler are you using? My guess is Visual Studios on Windows Vista?

Re: Breakout Clone

Posted: Sat Dec 12, 2009 11:01 pm
by Master Jake
Good guess =)

Visual Studio 2005 Professional Edition, Windows Vista Home Premium SP2

Re: Breakout Clone

Posted: Sat Dec 12, 2009 11:07 pm
by animangaman690
I think what it is visual studios has a C++ compiler and I don't think you have to have
<stdbool.h>
with a C++ compiler.

Re: Breakout Clone

Posted: Sat Dec 12, 2009 11:29 pm
by Master Jake
You're right, thanks man.

Edit: I completely forget I was compiling in C++ and not C.