Merge branch 'dev' into 'master'
New Version with working Main menu See merge request czg6669/breakout!2
3
.gitignore
vendored
@ -1,14 +1,11 @@
|
||||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
*.depend
|
||||
*.cbp
|
||||
*.layout
|
||||
sdl2-config
|
||||
*.exclude
|
||||
*.o
|
||||
highscoretest.c
|
||||
*.psd
|
||||
*.exe
|
||||
!bhi.exe
|
||||
|
6
Makefile
@ -1,13 +1,15 @@
|
||||
libs = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lSDL2_image -lSDL2_ttf
|
||||
includes = -I".\include"
|
||||
compiler = gcc
|
||||
warningLevel = -Wall
|
||||
warningLevel = -Wall -Wno-unused-variable -Wno-unused-but-set-variable
|
||||
sources = *.c
|
||||
linker = -L".\lib"
|
||||
dir = bin
|
||||
target = Breakout.exe
|
||||
target = Breakout
|
||||
args = -o
|
||||
|
||||
all:
|
||||
$(compiler) $(warningLevel) $(includes) $(sources) $(linker) $(libs) $(args) $(dir)\$(target)
|
||||
|
||||
run:
|
||||
cd $(dir) && $(target)
|
||||
|
BIN
bin/assets/fonts/ae-bi.ttf
Normal file
BIN
bin/assets/fonts/ka1.ttf
Normal file
BIN
bin/assets/fonts/minecraft.ttf
Normal file
BIN
bin/assets/fonts/monofur.ttf
Normal file
BIN
bin/assets/images/Texts.png
Normal file
After Width: | Height: | Size: 658 KiB |
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 155 KiB |
BIN
bin/assets/images/blocks_debug.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
bin/assets/images/breaking_button.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bin/assets/images/highscores_button.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
bin/assets/images/level_button.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 9.9 KiB |
BIN
bin/assets/images/play_button.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
bin/assets/images/quit_button.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
bin/assets/images/settings_button.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
bin/assets/images/settings_title.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
bin/assets/images/skins_button.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
bin/assets/images/spritesheet.png
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
bin/bhi.exe
352
breakout.c
@ -10,23 +10,27 @@
|
||||
#include "breakout.h"
|
||||
#include "vector.h"
|
||||
|
||||
#define BALL_TexturePath "assets/images/ball.png"
|
||||
#define PADDLE_TexturePath "assets/images/paddle.png"
|
||||
#define BLOCK_TexturePath "assets/images/spritesheet.png"
|
||||
|
||||
#ifndef __nullptr__
|
||||
#define Nullptr(type) (type *)0
|
||||
#endif // __nullptr__
|
||||
|
||||
int BLOCK_TextureCount = 24;
|
||||
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight;
|
||||
SDL_Texture * BALL_Texture;
|
||||
SDL_Rect * BALL_SourceRects;
|
||||
Ball ball;
|
||||
Paddle paddle;
|
||||
SDL_Texture * PADDLE_Texture;
|
||||
SDL_Texture * BLOCK_Texture;
|
||||
SDL_Rect * BALL_SourceRects;
|
||||
SDL_Rect * PADDLE_SourceRects;
|
||||
SDL_Rect * BLOCK_SourceRects;
|
||||
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
|
||||
double BALL_Speed = 15.0f;
|
||||
int PADDLE_Speed = 10;
|
||||
bool BREAKOUT_IsInit = false;
|
||||
bool BALL_IsInit = false;
|
||||
bool PADDLE_IsInit = false;
|
||||
bool BLOCK_IsInit = false;
|
||||
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
|
||||
if (!BREAKOUT_IsInit) {
|
||||
@ -36,46 +40,90 @@ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
|
||||
BREAKOUT_BoxHeight = height;
|
||||
BALL_Initialize(renderer);
|
||||
PADDLE_Initialize(renderer);
|
||||
BLOCK_Initialize(renderer);
|
||||
printf("Game initialized!\n");
|
||||
BREAKOUT_IsInit = true;
|
||||
} else printf("Game is already initialized!\n");
|
||||
}
|
||||
} /* BREAKOUT_INITIALIZE */
|
||||
|
||||
Scenery BREAKOUT_CreateDefault(){
|
||||
Scenery scenery;
|
||||
|
||||
scenery.BlockCount = 60;
|
||||
scenery.ball = BALL_CreateDefault();
|
||||
scenery.paddle = PADDLE_CreateDefault();
|
||||
scenery.blocks = malloc(scenery.BlockCount * sizeof(Block));
|
||||
int index;
|
||||
for (int y = 0; y < 6; y++) {
|
||||
index = 10 * y;
|
||||
for (int x = 0; x < 10; x++) {
|
||||
scenery.blocks[x + index] = BLOCK_CreateDefault();
|
||||
scenery.blocks[x + index].TargetRect = (SDL_Rect) {.x = ((192 * x) + 4), .y = ((96 * y) + 2), .w = 184, .h = 92 };
|
||||
scenery.blocks[x + index].TextureIndex = y + x + 2;
|
||||
// printf("Block created at index: %d\n", (x + index));
|
||||
// printf("Block Target: %d %d %d %d\n", ( scenery.blocks[x + index].TargetRect.x), ( scenery.blocks[x + index].TargetRect.y), ( scenery.blocks[x + index].TargetRect.w), ( scenery.blocks[x + index].TargetRect.h));
|
||||
// printf("Block Texture index: %d\n", scenery.blocks[x + index].TextureIndex);
|
||||
// system("pause");
|
||||
}
|
||||
}
|
||||
return scenery;
|
||||
} /* BREAKOUT_CreateDefault */
|
||||
|
||||
// This Function is obsolete! Do not use it!
|
||||
void BREAKOUT_ChangeSize(int width, int height){
|
||||
BREAKOUT_BoxWidth = width;
|
||||
BREAKOUT_BoxHeight = height;
|
||||
}
|
||||
|
||||
void BREAKOUT_Update(Uint8 * keystate){
|
||||
BALL_Update(&ball, &paddle);
|
||||
PADDLE_Update(&paddle, keystate);
|
||||
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
|
||||
PADDLE_Update(&(scenery->paddle), keystate); // Update paddle before ball because paddle is not static!
|
||||
BALL_Update(&(scenery->ball), &(scenery->paddle), (scenery->blocks), (scenery->BlockCount));
|
||||
for (int i = 0; i < (scenery->BlockCount); i++) {
|
||||
BLOCK_Update((scenery->blocks) + i);
|
||||
}
|
||||
}
|
||||
|
||||
void BREAKOUT_Draw(SDL_Renderer * renderer){
|
||||
BALL_Draw(renderer, &ball);
|
||||
PADDLE_Draw(renderer, &paddle);
|
||||
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
|
||||
for (int i = 0; i < (scenery->BlockCount); i++) {
|
||||
BLOCK_Draw(renderer, &((scenery->blocks)[i]));
|
||||
}
|
||||
BALL_Draw(renderer, &(scenery->ball));
|
||||
PADDLE_Draw(renderer, &(scenery->paddle));
|
||||
}
|
||||
|
||||
void BREAKOUT_DEINITIALIZE(){
|
||||
if (BREAKOUT_IsInit) {
|
||||
printf("De-initializing Game...\n");
|
||||
SDL_DestroyTexture(BALL_Texture);
|
||||
SDL_DestroyTexture(PADDLE_Texture);
|
||||
free(PADDLE_MoveLeftKeys);
|
||||
free(PADDLE_MoveRightKeys);
|
||||
free(BALL_SourceRects);
|
||||
free(PADDLE_SourceRects);
|
||||
free(BLOCK_SourceRects);
|
||||
BALL_Deinitialize();
|
||||
PADDLE_Deinitialize();
|
||||
BLOCK_Deinitialize();
|
||||
printf("Game de-initialized!\n");
|
||||
BREAKOUT_IsInit = false;
|
||||
} else printf("Game is already de-initialized!\n");
|
||||
}
|
||||
|
||||
void BREAKOUT_DestroyObject(Scenery * scenery){
|
||||
for (size_t i = 0; i < (scenery->BlockCount); i++) {
|
||||
BLOCK_DestroyObject((scenery->blocks) + i);
|
||||
}
|
||||
BALL_DestroyObject(&(scenery->ball));
|
||||
PADDLE_DestroyObject(&(scenery->paddle));
|
||||
free((scenery->blocks));
|
||||
}
|
||||
|
||||
void BALL_Initialize(SDL_Renderer * renderer){
|
||||
if (!BALL_IsInit) {
|
||||
printf("Initializing Ball...\n");
|
||||
BALL_Texture = IMG_LoadTexture(renderer, "assets/images/ball.png");
|
||||
BALL_Texture = IMG_LoadTexture(renderer, BALL_TexturePath);
|
||||
if (!BALL_Texture) printf("Ball texture failed to load!\n");
|
||||
BALL_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
|
||||
if (!BALL_SourceRects) printf("FATAL! Memory allocation failed!\n");
|
||||
BALL_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 };
|
||||
ball = BALL_CreateDefault();
|
||||
paddle = PADDLE_CreateDefault();
|
||||
printf("Ball initialized!\n");
|
||||
BALL_IsInit = true;
|
||||
} else printf("Ball is already initialized!\n");
|
||||
@ -85,13 +133,14 @@ Ball BALL_CreateDefault(){
|
||||
double rotation = (double)(rand() % 360);
|
||||
|
||||
return (Ball) {
|
||||
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 },
|
||||
.Momentum = (Vector) {.x = 0.0f, .y = BALL_Speed },
|
||||
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 },
|
||||
.Momentum = (Vector) {.x = 0.0f, .y = 15.0f },
|
||||
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 50, .h = 50 },
|
||||
.Size = 25.0f,
|
||||
.Rotation = rotation,
|
||||
.RotationValue = 2,
|
||||
.TextureIndex = 0
|
||||
.TextureIndex = 0,
|
||||
.Speed = 15.0f
|
||||
}; // Objekt für die Eigenschaften des Balls
|
||||
}
|
||||
|
||||
@ -101,28 +150,54 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
|
||||
}
|
||||
|
||||
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){
|
||||
SDL_Point ballCenter = (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
|
||||
SDL_Point ballCenter = BALL_GetCenter(obj);
|
||||
|
||||
// THIS IS CURRENTLY A RECTANGLE COLLIDE
|
||||
if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) {
|
||||
return false;
|
||||
}
|
||||
if (((obj->TargetRect).x) > (rect->x) + (rect->w)) {
|
||||
return false;
|
||||
}
|
||||
if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) {
|
||||
return false;
|
||||
}
|
||||
if (((obj->TargetRect).y) > (rect->y) + (rect->h)) {
|
||||
return false;
|
||||
}
|
||||
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt
|
||||
if ((ballCenter.x) < (rect->x) || (ballCenter.x) > (rect->x) + (rect->w)) {
|
||||
if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) return false;
|
||||
if (((obj->TargetRect).x) > (rect->x) + (rect->w)) return false;
|
||||
if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) return false;
|
||||
if (((obj->TargetRect).y) > (rect->y) + (rect->h)) return false;
|
||||
// Already returned with false if square ball hitbox didnt collide with rect
|
||||
Vector center = (Vector) {.x = ballCenter.x, .y = ballCenter.y };
|
||||
Vector corner;
|
||||
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt!
|
||||
// double perpendicular, oldMomentum, angle;
|
||||
// oldMomentum = fmod((double)(vectorRotation(obj->Momentum) + 180), 360.0f);
|
||||
|
||||
bool left, right, top, bottom, yMid = false, xMid = false;
|
||||
left = (ballCenter.x) < (rect->x);
|
||||
right = (ballCenter.x) > (rect->x) + (rect->w);
|
||||
top = (ballCenter.y) < (rect->y);
|
||||
bottom = (ballCenter.y) > (rect->y) + (rect->h);
|
||||
// if (top)
|
||||
// corner.y = rect->y;
|
||||
// else if (bottom)
|
||||
// corner.y = (rect->y) + (rect->w);
|
||||
// else
|
||||
// yMid = true;
|
||||
// if (left)
|
||||
// corner.x = rect->x;
|
||||
// else if (right)
|
||||
// corner.x = (rect->x) + (rect->w);
|
||||
// else
|
||||
// xMid = true;
|
||||
yMid = !(top || bottom);
|
||||
xMid = !(left || right);
|
||||
if (yMid)
|
||||
(obj->Momentum).x = -(obj->Momentum).x;
|
||||
}
|
||||
if ((ballCenter.y) < (rect->y) || (ballCenter.y) > (rect->y) + (rect->h)) {
|
||||
if (xMid)
|
||||
(obj->Momentum).y = -(obj->Momentum).y;
|
||||
}
|
||||
// if (yMid && xMid) printf("WARNING: Ball is completely inside block!\n");
|
||||
// if (yMid || xMid) { // Ball collides with Edge
|
||||
// } else { // Ball collides with corner
|
||||
// /*
|
||||
// * perpendicular = vectorRotation(vectorSub(center, corner));
|
||||
// * angle = fabs(perpendicular - oldMomentum);
|
||||
// * if (oldMomentum < perpendicular)
|
||||
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), (obj->Speed));
|
||||
// * else
|
||||
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), (obj->Speed));
|
||||
// */
|
||||
// }
|
||||
return true;
|
||||
} /* BALL_CollideWithRect */
|
||||
|
||||
@ -143,56 +218,83 @@ bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2){
|
||||
}
|
||||
|
||||
void BALL_SteerMomentum(Ball * obj, Paddle * paddle){
|
||||
int paddleHalfLen = ((paddle->TargetRect).w / 2.0f);
|
||||
double paddleHalfLen = ((double)((paddle->TargetRect).w) / 2.0f);
|
||||
double offset = (((obj->TargetRect).x) + (obj->Size)) - ((paddle->TargetRect).x + paddleHalfLen);
|
||||
|
||||
offset *= 60.0f;
|
||||
offset /= (double)(paddleHalfLen);
|
||||
printf("Offset = %.2f\n", offset);
|
||||
(obj->Momentum) = getScaledDirectionalUnitVector(offset, BALL_Speed);
|
||||
offset /= paddleHalfLen;
|
||||
offset *= (paddle->SteeringAngle);
|
||||
DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (paddle->SteeringAngle));
|
||||
(obj->Momentum) = getDirectionalUnitVector(offset);
|
||||
}
|
||||
|
||||
void BALL_Update(Ball * obj, Paddle * paddle){
|
||||
Vector oldMomentum = obj->Momentum;
|
||||
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){
|
||||
rect->x = (int)round(Location->x);
|
||||
rect->y = (int)round(Location->y);
|
||||
}
|
||||
|
||||
(obj->Rotation) += (obj->RotationValue);
|
||||
SDL_Point BALL_GetCenter(Ball * obj){
|
||||
return (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
|
||||
}
|
||||
|
||||
void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){
|
||||
Vector oldMomentum = obj->Momentum;
|
||||
Vector oldLocation = obj->Location;
|
||||
SDL_Point ballCenter = BALL_GetCenter(obj);
|
||||
|
||||
(obj->Rotation) += (obj->RotationValue); // No effect on physics
|
||||
(obj->Location) = vectorAdd((obj->Location), oldMomentum);
|
||||
|
||||
if (BALL_CollideWithRect(obj, &(paddle->TargetRect))) {
|
||||
(obj->Location) = vectorSub((obj->Location), oldMomentum); // Maybe remove this
|
||||
BALL_SteerMomentum(obj, paddle);
|
||||
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); // Maybe remove this
|
||||
if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) {
|
||||
(obj->Location) = oldLocation; // Maybe remove this
|
||||
BALL_SteerMomentum(obj, paddle); // Sets it to unit vector!
|
||||
// Following assumes that the paddle position was udated before the ball was updated
|
||||
// BUG/GLITCH: Make sure that the postition of the ball is not shifted into the borders of the game!
|
||||
while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps
|
||||
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum));
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
}
|
||||
(obj->Momentum) = vectorScaleTo((obj->Momentum), (obj->Speed));
|
||||
}
|
||||
for (size_t i = 0; i < BlockCount; i++) {
|
||||
if (blocks[i].HP <= 0) continue;
|
||||
oldMomentum = obj->Momentum;
|
||||
oldLocation = obj->Location;
|
||||
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
|
||||
BLOCK_DealDamage(blocks + i, 1);
|
||||
(obj->Location) = vectorAdd(oldLocation, (obj->Momentum));
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj->Location).y > BREAKOUT_BoxHeight)
|
||||
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 }; // Dead
|
||||
if ((obj->Location).y < 0.0f)
|
||||
if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
|
||||
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead
|
||||
else if ((obj->Location).y < 0.0f)
|
||||
(obj->Momentum).y = -(obj->Momentum).y;
|
||||
if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size)))
|
||||
(obj->Momentum).x = -(obj->Momentum).x;
|
||||
(obj->TargetRect).x = (int)round((obj->Location).x);
|
||||
(obj->TargetRect).y = (int)round((obj->Location).y);
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
} /* BALL_Update */
|
||||
|
||||
void BALL_DestroyObject(Ball * obj){
|
||||
}
|
||||
|
||||
void BALL_Deinitialize(){
|
||||
if (BALL_IsInit) {
|
||||
printf("De-initializing Ball...\n");
|
||||
|
||||
SDL_DestroyTexture(BALL_Texture);
|
||||
printf("Ball de-initialized!\n");
|
||||
BALL_IsInit = false;
|
||||
} else printf("Ball is already de-initialized!\n");
|
||||
}
|
||||
|
||||
|
||||
void PADDLE_Initialize(SDL_Renderer * renderer){
|
||||
if (!PADDLE_IsInit) {
|
||||
printf("Initializing Paddle...\n");
|
||||
PADDLE_Texture = IMG_LoadTexture(renderer, "assets/images/paddle.png");
|
||||
PADDLE_Texture = IMG_LoadTexture(renderer, PADDLE_TexturePath);
|
||||
if (!PADDLE_Texture) printf("Paddle texture failed to load!\n");
|
||||
PADDLE_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
|
||||
if (!PADDLE_SourceRects) printf("FATAL! Memory allocation failed!\n");
|
||||
PADDLE_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 };
|
||||
PADDLE_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 1000, .h = 100 };
|
||||
PADDLE_MoveLeftKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
|
||||
if (!PADDLE_MoveLeftKeys) printf("FATAL! Memory allocation failed!\n");
|
||||
PADDLE_MoveRightKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
|
||||
@ -203,7 +305,6 @@ void PADDLE_Initialize(SDL_Renderer * renderer){
|
||||
PADDLE_MoveRightKeys[0] = 2;
|
||||
PADDLE_MoveRightKeys[1] = SDL_SCANCODE_RIGHT;
|
||||
PADDLE_MoveRightKeys[2] = SDL_SCANCODE_D;
|
||||
ball = BALL_CreateDefault();
|
||||
printf("Paddle initialized!\n");
|
||||
PADDLE_IsInit = true;
|
||||
} else printf("Paddle is already initialized!\n");
|
||||
@ -214,48 +315,151 @@ Paddle PADDLE_CreateDefault(){
|
||||
|
||||
return (Paddle) {
|
||||
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 },
|
||||
.TextureIndex = 0
|
||||
.TextureIndex = 0,
|
||||
.Speed = 10,
|
||||
.SteeringAngle = 40.0f,
|
||||
.Mode = KeyboardControl
|
||||
}; // Objekt für die Eigenschaften des Balls
|
||||
}
|
||||
|
||||
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){
|
||||
// printf("Paddle drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x);
|
||||
// SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
SDL_RenderDrawRect(renderer, &(obj->TargetRect));
|
||||
SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
|
||||
// SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
// SDL_RenderDrawRect(renderer, &(obj->TargetRect));
|
||||
}
|
||||
|
||||
bool KeyPressed(Uint8 * keystate, Uint8 * keyArray){
|
||||
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray){
|
||||
for (int i = 0; i < (*keyArray); i++) {
|
||||
if (keystate[keyArray[(i + 1)]]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void constrain(int * variable, int min, int max){
|
||||
void INT_Constrain(int * variable, int min, int max){
|
||||
if (*variable > max)
|
||||
*variable = max;
|
||||
else if (*variable < min)
|
||||
*variable = min;
|
||||
}
|
||||
|
||||
void PADDLE_Update(Paddle * obj, Uint8 * keystate){
|
||||
bool leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys), rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys);
|
||||
void DOUBLE_Constrain(double * variable, double min, double max){
|
||||
if (*variable > max)
|
||||
*variable = max;
|
||||
else if (*variable < min)
|
||||
*variable = min;
|
||||
}
|
||||
|
||||
void PADDLE_Update(Paddle * obj, const Uint8 * keystate){
|
||||
bool leftKeyPressed = false, rightKeyPressed = false;
|
||||
int paddleXMid = (obj->TargetRect).x + ((obj->TargetRect).w / 2);
|
||||
int mouseX;
|
||||
|
||||
switch (obj->Mode) {
|
||||
case MouseControl:
|
||||
SDL_GetMouseState(&mouseX, NULL);
|
||||
if (abs(mouseX - paddleXMid) > (obj->Speed)) {
|
||||
if (mouseX > paddleXMid)
|
||||
rightKeyPressed = true;
|
||||
else
|
||||
leftKeyPressed = true;
|
||||
}
|
||||
break;
|
||||
case KeyboardControl:
|
||||
leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys);
|
||||
rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Paddle Control Mode: %d!\n", obj->Mode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (leftKeyPressed && (!rightKeyPressed)) {
|
||||
((obj->TargetRect).x) -= PADDLE_Speed;
|
||||
((obj->TargetRect).x) -= (obj->Speed);
|
||||
} else if ((!leftKeyPressed) && rightKeyPressed) {
|
||||
((obj->TargetRect).x) += PADDLE_Speed;
|
||||
}
|
||||
constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w)));
|
||||
((obj->TargetRect).x) += (obj->Speed);
|
||||
}
|
||||
INT_Constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w)));
|
||||
} /* PADDLE_Update */
|
||||
|
||||
void PADDLE_DestroyObject(Paddle * obj){
|
||||
}
|
||||
|
||||
void PADDLE_Deinitialize(){
|
||||
if (PADDLE_IsInit) {
|
||||
printf("De-initializing Paddle...\n");
|
||||
|
||||
SDL_DestroyTexture(PADDLE_Texture);
|
||||
printf("Paddle de-initialized!\n");
|
||||
PADDLE_IsInit = false;
|
||||
} else printf("Paddle is already de-initialized!\n");
|
||||
}
|
||||
|
||||
void BLOCK_Initialize(SDL_Renderer * renderer){
|
||||
if (!BLOCK_IsInit) {
|
||||
printf("Initializing Block...\n");
|
||||
BLOCK_Texture = IMG_LoadTexture(renderer, BLOCK_TexturePath);
|
||||
if (!BLOCK_Texture) printf("Block texture failed to load!\n");
|
||||
BLOCK_SourceRects = (SDL_Rect *)malloc(BLOCK_TextureCount * sizeof(SDL_Rect));
|
||||
if (!BLOCK_SourceRects) printf("FATAL! Memory allocation failed!\n");
|
||||
BLOCK_SourceRects[0] = (SDL_Rect) {.x = 2000, .y = 1500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[1] = (SDL_Rect) {.x = 2000, .y = 2000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[2] = (SDL_Rect) {.x = 2000, .y = 2500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[3] = (SDL_Rect) {.x = 0, .y = 3000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[4] = (SDL_Rect) {.x = 1000, .y = 3000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[5] = (SDL_Rect) {.x = 2000, .y = 3000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[6] = (SDL_Rect) {.x = 0, .y = 3500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[7] = (SDL_Rect) {.x = 1000, .y = 3500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[8] = (SDL_Rect) {.x = 2000, .y = 3500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[9] = (SDL_Rect) {.x = 0, .y = 500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[10] = (SDL_Rect) {.x = 2000, .y = 0, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[11] = (SDL_Rect) {.x = 0, .y = 1000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[12] = (SDL_Rect) {.x = 0, .y = 1500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[13] = (SDL_Rect) {.x = 1000, .y = 0, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[14] = (SDL_Rect) {.x = 1000, .y = 500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[15] = (SDL_Rect) {.x = 1000, .y = 1000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[16] = (SDL_Rect) {.x = 1000, .y = 1500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[17] = (SDL_Rect) {.x = 0, .y = 2000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[18] = (SDL_Rect) {.x = 1000, .y = 2000, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[19] = (SDL_Rect) {.x = 0, .y = 2500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[20] = (SDL_Rect) {.x = 1000, .y = 2500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[21] = (SDL_Rect) {.x = 0, .y = 0, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[22] = (SDL_Rect) {.x = 2000, .y = 500, .w = 1000, .h = 500 };
|
||||
BLOCK_SourceRects[23] = (SDL_Rect) {.x = 2000, .y = 1000, .w = 1000, .h = 500 };
|
||||
printf("Block initialized!\n");
|
||||
BLOCK_IsInit = true;
|
||||
} else printf("Block is already initialized!\n");
|
||||
} /* PADDLE_Initialize */
|
||||
|
||||
Block BLOCK_CreateDefault() {
|
||||
return (Block) {
|
||||
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 100, .h = 50 },
|
||||
.TextureIndex = (rand() % BLOCK_TextureCount),
|
||||
.HP = 1
|
||||
}; // Objekt für die Eigenschaften des Balls
|
||||
}
|
||||
|
||||
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj){
|
||||
if ((obj->HP) > 0) {
|
||||
// printf("Block drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).y);
|
||||
SDL_RenderCopy(renderer, BLOCK_Texture, (BLOCK_SourceRects + (obj->TextureIndex)), &(obj->TargetRect));
|
||||
}
|
||||
}
|
||||
|
||||
void BLOCK_DealDamage(Block * obj, int dmg){
|
||||
if (((obj->HP) -= dmg) <= 0) printf("Block was destroyed!\n");
|
||||
}
|
||||
|
||||
void BLOCK_Update(Block * obj){
|
||||
// Do nothing currently
|
||||
}
|
||||
void BLOCK_DestroyObject(Block * obj){
|
||||
}
|
||||
|
||||
void BLOCK_Deinitialize(){
|
||||
if (BLOCK_IsInit) {
|
||||
printf("De-initializing Block...\n");
|
||||
SDL_DestroyTexture(BLOCK_Texture);
|
||||
printf("Block de-initialized!\n");
|
||||
BLOCK_IsInit = false;
|
||||
} else printf("Block is already de-initialized!\n");
|
||||
}
|
||||
|
43
breakout.h
@ -9,48 +9,75 @@
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
// Enums
|
||||
typedef enum controlModeEnum {KeyboardControl = 0, MouseControl = 1} ControlMode;
|
||||
// End Enums
|
||||
|
||||
// Structs
|
||||
typedef struct ballStruct {
|
||||
Vector Location, Momentum;
|
||||
SDL_Rect TargetRect;
|
||||
double Size, Rotation, RotationValue;
|
||||
int TextureIndex;
|
||||
double Speed;
|
||||
} Ball; // Objekt für die Eigenschaften des Balls
|
||||
|
||||
typedef struct paddleStruct {
|
||||
SDL_Rect TargetRect;
|
||||
int TextureIndex;
|
||||
int Speed;
|
||||
double SteeringAngle;
|
||||
ControlMode Mode;
|
||||
} Paddle; // Objekt für die Eigenschaften des Paddles
|
||||
|
||||
typedef struct blockStruct {
|
||||
Vector Location;
|
||||
SDL_Rect TargetRect;
|
||||
int XSize, YSize, TextureIndex;
|
||||
int TextureIndex, HP;
|
||||
} Block; // Objekt für die Eigenschaften des Paddles
|
||||
|
||||
typedef struct sceneryStruct {
|
||||
Ball ball;
|
||||
Paddle paddle;
|
||||
Block * blocks;
|
||||
int BlockCount; // Move to scenery
|
||||
} Scenery; // Objekt für die Objekte und Eigenschaften einer Szenerie
|
||||
// End Structs
|
||||
|
||||
// Prototypes
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height);
|
||||
Scenery BREAKOUT_CreateDefault();
|
||||
void BREAKOUT_ChangeSize(int width, int height);
|
||||
void BREAKOUT_Update(Uint8 * keystate);
|
||||
void BREAKOUT_Draw(SDL_Renderer * renderer);
|
||||
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate);
|
||||
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer);
|
||||
void BREAKOUT_DEINITIALIZE();
|
||||
void BREAKOUT_DestroyObject(Scenery * scenery);
|
||||
void BALL_Initialize(SDL_Renderer * renderer);
|
||||
Ball BALL_CreateDefault();
|
||||
void BALL_Draw(SDL_Renderer * renderer, Ball * obj);
|
||||
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect);
|
||||
bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2);
|
||||
void BALL_Update(Ball * obj, Paddle * paddle);
|
||||
void BALL_SteerMomentum(Ball * obj, Paddle * paddle);
|
||||
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location);
|
||||
SDL_Point BALL_GetCenter(Ball * obj);
|
||||
void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount);
|
||||
void BALL_DestroyObject(Ball * obj);
|
||||
void BALL_Deinitialize();
|
||||
void PADDLE_Initialize(SDL_Renderer * renderer);
|
||||
Paddle PADDLE_CreateDefault();
|
||||
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj);
|
||||
bool KeyPressed(Uint8 * keystate, Uint8 * keyArray);
|
||||
void constrain(int * variable, int min, int max);
|
||||
void PADDLE_Update(Paddle * obj, Uint8 * keystate);
|
||||
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray);
|
||||
void INT_Constrain(int * variable, int min, int max);
|
||||
void DOUBLE_Constrain(double * variable, double min, double max);
|
||||
void PADDLE_Update(Paddle * obj, const Uint8 * keystate);
|
||||
void PADDLE_DestroyObject(Paddle * obj);
|
||||
void PADDLE_Deinitialize();
|
||||
void BLOCK_Initialize(SDL_Renderer * renderer);
|
||||
Block BLOCK_CreateDefault() ;
|
||||
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj);
|
||||
void BLOCK_DealDamage(Block * obj, int dmg);
|
||||
void BLOCK_Update(Block * obj);
|
||||
void BLOCK_DestroyObject(Block * obj);
|
||||
void BLOCK_Deinitialize();
|
||||
// End Prototypes
|
||||
|
||||
#endif // __breakout_h__
|
||||
|
14
button.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __button_h__
|
||||
#define __button_h__
|
||||
|
||||
// Structs
|
||||
typedef struct buttonStruct {
|
||||
SDL_Rect TargetRect;
|
||||
void (*OnClick)();
|
||||
} Button;
|
||||
// End Structs
|
||||
|
||||
// Prototypes
|
||||
// End Prototypes
|
||||
|
||||
#endif
|
6
gamestate.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __gamestate_h__
|
||||
#define __gamestate_h__
|
||||
|
||||
typedef enum gameStateEnum { MainMenu = 1, Game = 2, LevelSelect = 3, SkinSelect = 4, Settings = 5, Highscores = 6 } GameState;
|
||||
|
||||
#endif
|
167
highscores.c
Normal file
@ -0,0 +1,167 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#include "highscores.h"
|
||||
|
||||
#define HIGHSCORES_FontFile "assets/fonts/monofur.ttf"
|
||||
|
||||
int HIGHSCORES_EntriesGot = 0;
|
||||
User * HIGHSCORES_UserList;
|
||||
SDL_Color HIGHSCORES_FontColor;
|
||||
SDL_Texture * HIGHSCORES_TableTexture;
|
||||
SDL_Rect HIGHSCORES_TotalRect;
|
||||
TTF_Font * HIGHSCORES_FontFamily = NULL;
|
||||
SDL_Surface * tempSurface;
|
||||
|
||||
void HIGHSCORES_Initialize(){
|
||||
printf("Initializing Highscores...\n");
|
||||
HIGHSCORES_FontColor = (SDL_Color) {255, 255, 255 };
|
||||
HIGHSCORES_UserList = malloc(10 * sizeof(User));
|
||||
HIGHSCORES_FontFamily = TTF_OpenFont(HIGHSCORES_FontFile, 48);
|
||||
if (!HIGHSCORES_FontFamily) printf("Font could not initialize! Error: %s\n", TTF_GetError());
|
||||
else printf("Font was successfully initialized!\n");
|
||||
printFontStyle(HIGHSCORES_FontFamily);
|
||||
HIGHSCORES_TotalRect = (SDL_Rect) {.x = 0, .y = 0, .w = 1920, .h = 1080 };
|
||||
printf("Highscores initialized!\n");
|
||||
}
|
||||
|
||||
void printFontStyle(TTF_Font * ffont){
|
||||
int style;
|
||||
|
||||
style = TTF_GetFontStyle(ffont);
|
||||
printf("The font style is:");
|
||||
if (style == TTF_STYLE_NORMAL)
|
||||
printf(" normal");
|
||||
else {
|
||||
if (style & TTF_STYLE_BOLD)
|
||||
printf(" bold");
|
||||
if (style & TTF_STYLE_ITALIC)
|
||||
printf(" italic");
|
||||
if (style & TTF_STYLE_UNDERLINE)
|
||||
printf(" underline");
|
||||
if (style & TTF_STYLE_STRIKETHROUGH)
|
||||
printf(" strikethrough");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void HIGHSCORES_Draw(SDL_Renderer * renderer){
|
||||
SDL_RenderCopy(renderer, HIGHSCORES_TableTexture, &HIGHSCORES_TotalRect, &HIGHSCORES_TotalRect);
|
||||
} /* HIGHSCORES_Draw */
|
||||
|
||||
void HIGHSCORES_Deinitialize(){
|
||||
printf("De-initializing Highscores...\n");
|
||||
TTF_CloseFont(HIGHSCORES_FontFamily);
|
||||
HIGHSCORES_FontFamily = NULL; // to be safe...
|
||||
SDL_DestroyTexture(HIGHSCORES_TableTexture);
|
||||
SDL_FreeSurface(tempSurface);
|
||||
free(HIGHSCORES_UserList);
|
||||
printf("Highscores de-initialized!\n");
|
||||
}
|
||||
|
||||
void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer){
|
||||
char * buffer = calloc(100, sizeof(char));
|
||||
int count = 0;
|
||||
char format[20] = "| %-58s | %-10s |";
|
||||
SDL_Rect Message_rect;
|
||||
SDL_Surface * HIGHSCORES_TableSurface = SDL_CreateRGBSurface(0, 1920, 1080, 32, 0, 0, 0, 0);
|
||||
|
||||
if (!HIGHSCORES_TableSurface) {
|
||||
printf("Surface wasn't created!\n");
|
||||
}
|
||||
sprintf(buffer, format, "Username", "Score");
|
||||
HIGHSCORES_DrawText(buffer, &Message_rect);
|
||||
Message_rect.y = 70;
|
||||
Message_rect.x = 50;
|
||||
Message_rect.h = 50;
|
||||
Message_rect.w = 50;
|
||||
SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
|
||||
SDL_FreeSurface(tempSurface);
|
||||
while (count < HIGHSCORES_EntriesGot) {
|
||||
sprintf(buffer, format, HIGHSCORES_UserList[count].Username, HIGHSCORES_UserList[count].Score);
|
||||
HIGHSCORES_DrawText(buffer, &Message_rect);
|
||||
Message_rect.y = ((Message_rect.h + 15) * (count + 1)) + 140;
|
||||
Message_rect.x = 50;
|
||||
SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
|
||||
SDL_FreeSurface(tempSurface);
|
||||
count++;
|
||||
}
|
||||
HIGHSCORES_TableTexture = SDL_CreateTextureFromSurface(renderer, HIGHSCORES_TableSurface);
|
||||
if (!HIGHSCORES_TableTexture) {
|
||||
printf("Texture wasn't created!\n");
|
||||
}
|
||||
SDL_FreeSurface(HIGHSCORES_TableSurface);
|
||||
} /* HIGHSCORES_GenerateSurface */
|
||||
|
||||
void HIGHSCORES_DrawText(char * text, SDL_Rect * Message_rect){
|
||||
TTF_SizeText(HIGHSCORES_FontFamily, text, &(Message_rect->w), &(Message_rect->h));
|
||||
tempSurface = TTF_RenderText_Solid(HIGHSCORES_FontFamily, text, HIGHSCORES_FontColor);
|
||||
}
|
||||
|
||||
void HIGHSCORES_ReloadList(){
|
||||
printf("Call BHI interface:\n");
|
||||
system("bhi top output.txt");
|
||||
printf("BHI interface quit!\nBHI output handling...\n");
|
||||
|
||||
HIGHSCORES_EntriesGot = 0;
|
||||
FILE * fp;
|
||||
char * line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
char * name, * scorestring;
|
||||
int nameCharCount = 0, scoreCharCount = 0;
|
||||
bool switchread = false;
|
||||
HIGHSCORES_UserList = malloc(10 * sizeof(User));
|
||||
fp = fopen("output.txt", "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
if ((read = getline(&line, &len, fp)) != -1)
|
||||
if (line[0] == 0)
|
||||
return;
|
||||
int counter = 0;
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
name = malloc(read * sizeof(char));
|
||||
scorestring = malloc(read * sizeof(char));
|
||||
nameCharCount = 0;
|
||||
scoreCharCount = 0;
|
||||
switchread = false;
|
||||
#ifdef DEBUG
|
||||
printf("Retrieved line of length %u:\n", read);
|
||||
printf("%s", line);
|
||||
#endif
|
||||
for (ssize_t i = 0; i < read; i++) {
|
||||
if (line[i] == '+') {
|
||||
switchread = true;
|
||||
continue;
|
||||
}
|
||||
if (switchread) {
|
||||
if (line[i] == '\n') break;
|
||||
scorestring[scoreCharCount++] = line[i];
|
||||
} else
|
||||
name[nameCharCount++] = line[i];
|
||||
}
|
||||
name[nameCharCount] = '\0';
|
||||
scorestring[scoreCharCount] = '\0';
|
||||
User tmp;
|
||||
strcpy(tmp.Username, name);
|
||||
strcpy(tmp.Score, scorestring);
|
||||
HIGHSCORES_UserList[counter++] = tmp;
|
||||
}
|
||||
free(name);
|
||||
free(scorestring);
|
||||
|
||||
fclose(fp);
|
||||
if (line)
|
||||
free(line);
|
||||
for (size_t i = 0; i < counter; i++) {
|
||||
printf("User: %s -> Score: %s\n", HIGHSCORES_UserList[i].Username, HIGHSCORES_UserList[i].Score);
|
||||
}
|
||||
|
||||
HIGHSCORES_EntriesGot = counter;
|
||||
printf("BHI Interface successfully quit!\n");
|
||||
} /* main */
|
20
highscores.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __highscores_h__
|
||||
#define __highscores_h__
|
||||
|
||||
// Structs
|
||||
typedef struct userStruct {
|
||||
char Username[50], Score[30];
|
||||
} User;
|
||||
// End Structs
|
||||
|
||||
// Prototypes
|
||||
void HIGHSCORES_Initialize();
|
||||
void printFontStyle(TTF_Font * ffont);
|
||||
void HIGHSCORES_Draw(SDL_Renderer * renderer);
|
||||
void HIGHSCORES_Deinitialize();
|
||||
void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer);
|
||||
void HIGHSCORES_DrawText(char * text, SDL_Rect * Message_rect);
|
||||
void HIGHSCORES_ReloadList();
|
||||
// End Prototypes
|
||||
|
||||
#endif
|
158
main.c
@ -9,63 +9,105 @@
|
||||
|
||||
#include "breakout.h"
|
||||
#include "vector.h"
|
||||
#include "startmenu.h"
|
||||
#include "gamestate.h"
|
||||
#include "highscores.h"
|
||||
#include "settings.h"
|
||||
|
||||
#ifndef __nullptr__
|
||||
#define Nullptr(type) (type *)0
|
||||
#endif // __nullptr__
|
||||
#include "main.h"
|
||||
|
||||
void DrawFrame();
|
||||
void INITIALIZE();
|
||||
void QUIT();
|
||||
void GAMELOOP();
|
||||
void mousePress(SDL_MouseButtonEvent b);
|
||||
void keyPress(SDL_KeyboardEvent b);
|
||||
void windowChanged(SDL_WindowEvent b);
|
||||
void toggleFullscreen();
|
||||
// Default Render Size (Upscaled for bigger monitors)
|
||||
const int width = 1920;
|
||||
const int height = 1080;
|
||||
float XScale = 1.0f, YScale = 1.0f;
|
||||
// End render properties
|
||||
|
||||
const int width = 1600; // TODO: Fullscreen
|
||||
const int height = 900;
|
||||
|
||||
Uint8 * keystate; // TODO: export all this into scenery and enemy waves
|
||||
int numKeys;
|
||||
const Uint8 * keystate; // TODO: export all this into scenery and enemy waves
|
||||
SDL_Window * window;
|
||||
SDL_Renderer * renderer;
|
||||
SDL_Event event;
|
||||
bool running = true, fullscreen = false;
|
||||
|
||||
Ball ball;
|
||||
GameState gameState = MainMenu;
|
||||
Scenery scenery;
|
||||
|
||||
int main(int argc, char * args[]){
|
||||
// system("bhi.exe");
|
||||
// printf("Spielbereiche\n\t- 1: Hauptmen"ue "\n\t- 2: Spiel\n\t- 3: Level Select\n\t- 4: Settings\n\t- 5: Highscores\n");
|
||||
// GAME_ChangeState(readIntFromIO("W"ae "hle einen Spielbereich aus, den du testen m"oe "chtest:", "Fehlerhafte Eingabe!\n", "%d ist kein g"ue "ltiger Spielbereich!\n", 1, 5));
|
||||
INITIALIZE();
|
||||
while (running) { // Gameloop
|
||||
HandleSDLEvents();
|
||||
DrawBackground(renderer);
|
||||
switch (gameState) {
|
||||
case Game:
|
||||
BREAKOUT_Update(&scenery, keystate);
|
||||
BREAKOUT_Draw(&scenery, renderer);
|
||||
break;
|
||||
case MainMenu:
|
||||
// Startmenu_Update(keystate);
|
||||
Startmenu_Draw(renderer);
|
||||
break;
|
||||
case Highscores:
|
||||
HIGHSCORES_Draw(renderer);
|
||||
break;
|
||||
case Settings:
|
||||
Settings_Draw(renderer);
|
||||
break;
|
||||
default:
|
||||
printf("Unknow state was updated: %d\n", gameState);
|
||||
break;
|
||||
}
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
QUIT();
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
void GAME_Escape(){
|
||||
running = false;
|
||||
printf("GAME_Escape was called!\n");
|
||||
}
|
||||
|
||||
void GAME_ChangeState(GameState state){
|
||||
if (gameState == state) {
|
||||
printf("State wasn't changed!\n");
|
||||
return;
|
||||
}
|
||||
gameState = state;
|
||||
switch (gameState) {
|
||||
case Highscores:
|
||||
HIGHSCORES_ReloadList();
|
||||
HIGHSCORES_GenerateTexture(renderer);
|
||||
printf("State was changed to Highscores!\n");
|
||||
break;
|
||||
default:
|
||||
printf("State was changed to %d!\n", gameState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSDLEvents(){
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
printf("NOTICE: User manually quit window!\n");
|
||||
running = false;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false;
|
||||
else keyPress(event.key);
|
||||
// if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false;
|
||||
// else
|
||||
keyPress(event.key);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mousePress(event.button);
|
||||
button_clicked(event.button, gameState);
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
windowChanged(event.window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GAMELOOP();
|
||||
DrawFrame();
|
||||
}
|
||||
QUIT();
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
void GAMELOOP() {
|
||||
keystate = SDL_GetKeyboardState(NULL);
|
||||
BREAKOUT_Update(keystate);
|
||||
} /* GAMELOOP */
|
||||
} /* HandleSDLEvents */
|
||||
|
||||
void mousePress(SDL_MouseButtonEvent b){ // Debug prop
|
||||
if (b.button == SDL_BUTTON_LEFT) {
|
||||
@ -97,25 +139,29 @@ void windowChanged(SDL_WindowEvent b){ // Debug prop
|
||||
switch (b.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
printf("Window was resized to (%d|%d)!\n", event.window.data1, event.window.data2);
|
||||
BREAKOUT_ChangeSize(event.window.data1, event.window.data2);
|
||||
// BREAKOUT_ChangeSize(event.window.data1, event.window.data2);
|
||||
XScale = ((double)(event.window.data1) / (double)width);
|
||||
YScale = ((double)(event.window.data2) / (double)height);
|
||||
SDL_RenderSetScale(renderer, XScale, YScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawFrame(){
|
||||
void DrawBackground(SDL_Renderer * renderer){
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
BREAKOUT_Draw(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
} /* DrawFrame */
|
||||
|
||||
void INITIALIZE() {
|
||||
printf("Initializing started...\n");
|
||||
srand(time(NULL));
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) printf("SDL could not initialize! Error: %s\n", SDL_GetError());
|
||||
else printf("SDL was successfully initialized!\n");
|
||||
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) printf("IMG could not initialize! IMG_Error: %s\n", IMG_GetError());
|
||||
keystate = SDL_GetKeyboardState(&numKeys);
|
||||
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) printf("IMG could not initialize! Error: %s\n", IMG_GetError());
|
||||
else printf("IMG was successfully initialized!\n");
|
||||
TTF_Init();
|
||||
if (TTF_Init() == -1) printf("TTF could not initialize! Error: %s\n", TTF_GetError());
|
||||
else printf("TTF was successfully initialized!\n");
|
||||
|
||||
window = SDL_CreateWindow("BreakING", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL);
|
||||
SDL_SetWindowResizable(window, true);
|
||||
@ -123,12 +169,19 @@ void INITIALIZE() {
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
printf("Renderer was created!\n");
|
||||
BREAKOUT_INITIALIZE(renderer, width, height);
|
||||
scenery = BREAKOUT_CreateDefault();
|
||||
Load_Textures(renderer);
|
||||
HIGHSCORES_Initialize();
|
||||
Settings_Initialize(renderer);
|
||||
printf("Initializing finished!\n");
|
||||
} /* INITIALIZE */
|
||||
|
||||
void QUIT(){
|
||||
printf("De-initializing started...\n");
|
||||
Settings_Deinitialize();
|
||||
HIGHSCORES_Deinitialize();
|
||||
BREAKOUT_DestroyObject(&scenery);
|
||||
BREAKOUT_DEINITIALIZE();
|
||||
free(keystate);
|
||||
TTF_Quit();
|
||||
IMG_Quit();
|
||||
printf("Quitting SDL_IMG finished!\n");
|
||||
@ -140,3 +193,28 @@ void QUIT(){
|
||||
printf("Quitting SDL finished!\n");
|
||||
printf("De-initializing finished!\n");
|
||||
} /* QUIT */
|
||||
|
||||
int readIntFromIO(char * m1, char * m2, char * m3, int min, int max){
|
||||
int nitems, num;
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
printf(m1);
|
||||
nitems = scanf("%d", &num);
|
||||
if (nitems == 0) {
|
||||
printf(m2);
|
||||
fflush(stdin);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((num < min) || (num > max)) {
|
||||
printf(m3, num);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fflush(stdin);
|
||||
return(num);
|
||||
} /* readIntFromIO */
|
||||
|
42
main.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef __main_h__
|
||||
#define __main_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#include "breakout.h"
|
||||
#include "vector.h"
|
||||
#include "startmenu.h"
|
||||
#include "gamestate.h"
|
||||
#include "highscores.h"
|
||||
|
||||
#ifndef __nullptr__
|
||||
#define Nullptr(type) (type *)0
|
||||
#endif // __nullptr__
|
||||
|
||||
#define ae "\204"
|
||||
#define oe "\224"
|
||||
#define ue "\201"
|
||||
#define ss "\341"
|
||||
|
||||
// Prototypes
|
||||
void GAME_ChangeState(GameState state);
|
||||
void HandleSDLEvents();
|
||||
void GAME_Escape();
|
||||
void mousePress(SDL_MouseButtonEvent b);
|
||||
void keyPress(SDL_KeyboardEvent b);
|
||||
void toggleFullscreen();
|
||||
void windowChanged(SDL_WindowEvent b);
|
||||
void DrawBackground(SDL_Renderer * renderer);
|
||||
void INITIALIZE();
|
||||
void QUIT();
|
||||
int readIntFromIO(char * m1, char * m2, char * m3, int min, int max);
|
||||
// End Prototypes
|
||||
|
||||
#endif // __main_h__
|
62
settings.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
SDL_Texture* Setting_Texture;
|
||||
|
||||
SDL_Rect Settings_rect;
|
||||
SDL_Rect BV_Bar_rect;
|
||||
SDL_Rect BV_Scalar_rect;
|
||||
SDL_Rect BS_Bar_rect;
|
||||
SDL_Rect BT_Bar_rect;
|
||||
SDL_Rect BVController_rect;
|
||||
|
||||
bool Settings_IsInit=false;
|
||||
|
||||
void Settings_Initialize (SDL_Renderer* renderer) {
|
||||
BV_Bar_rect = (SDL_Rect){.y = 300,.x = 400 , .w=400, .h=100};
|
||||
BV_Scalar_rect = (SDL_Rect){.y=300,.x=420,.w=20,.h=100};
|
||||
BS_Bar_rect = (SDL_Rect){.y = 500,.x = 400, .w=400, .h=100};
|
||||
BT_Bar_rect = (SDL_Rect){.y = 700,.x = 400, .w=400, .h=100};
|
||||
Setting_Texture = IMG_LoadTexture(renderer, "assets/images/settings_title.png");
|
||||
Settings_rect = (SDL_Rect){.x = 800, .y = 180, .w=313, .h=100};
|
||||
Settings_IsInit = true;
|
||||
}
|
||||
|
||||
void Settings_Draw (SDL_Renderer* renderer) {
|
||||
SDL_SetRenderDrawColor(renderer,255,255,255,255);
|
||||
SDL_RenderDrawRect(renderer,&BV_Bar_rect);
|
||||
SDL_RenderDrawRect(renderer,&BS_Bar_rect);
|
||||
SDL_RenderDrawRect(renderer,&BT_Bar_rect);
|
||||
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
|
||||
SDL_RenderCopy(renderer, Setting_Texture, NULL, &Settings_rect);
|
||||
int x,y;
|
||||
Uint32 Mousestate=SDL_GetMouseState(&x,&y);
|
||||
if(y<=400&&y>=300&&x<=800&&x>=400&&(Mousestate & SDL_BUTTON(SDL_BUTTON_LEFT))){
|
||||
SDL_RenderFillRect(renderer,&BV_Scalar_rect);
|
||||
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
|
||||
if(x>790){
|
||||
BV_Scalar_rect.x=780;
|
||||
}
|
||||
else if(x<410){
|
||||
BV_Scalar_rect.x=400;
|
||||
}
|
||||
else{
|
||||
BV_Scalar_rect.x=x-10;
|
||||
}
|
||||
}
|
||||
else{
|
||||
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
|
||||
}
|
||||
printf("%d,%d\n",x,y);
|
||||
|
||||
}
|
||||
|
||||
void Settings_Deinitialize(){
|
||||
if(Settings_IsInit){
|
||||
SDL_DestroyTexture(Setting_Texture);
|
||||
Settings_IsInit=false;
|
||||
}
|
||||
}
|
18
settings.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __Settings__
|
||||
|
||||
#define __Settings__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
void Settings_Initialize (SDL_Renderer* renderer);
|
||||
|
||||
void Settings_Draw (SDL_Renderer* renderer);
|
||||
|
||||
void Settings_Deinitialize();
|
||||
|
||||
#endif
|
78
startmenu.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include "gamestate.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
SDL_Texture * TITLE_Texture;
|
||||
SDL_Texture * PLAYBUTTON_Texture;
|
||||
SDL_Texture * SKINSBUTTON_Texture;
|
||||
SDL_Texture * LEVELBUTTON_Texture;
|
||||
SDL_Texture * SETTINGSBUTTON_Texture;
|
||||
SDL_Texture * HIGHSCORESBUTTON_Texture;
|
||||
SDL_Texture * QUITBUTTON_Texture;
|
||||
|
||||
SDL_Rect TITLE_Rect;
|
||||
SDL_Rect PLAYBUTTON_Rect;
|
||||
SDL_Rect SETTINGSBUTTON_Rect;
|
||||
SDL_Rect LEVELBUTTON_Rect;
|
||||
SDL_Rect SKINSBUTTON_Rect;
|
||||
SDL_Rect HIGHSCORESBUTTON_Rect;
|
||||
SDL_Rect QUITBUTTON_Rect;
|
||||
|
||||
int clickInRect(SDL_MouseButtonEvent b, SDL_Rect * area_rect) {
|
||||
return (((b.x) >= (area_rect->x)) && ((b.x) <= ((area_rect->x) + (area_rect->w))) && ((b.y) >= (area_rect->y)) && ((b.y) <= ((area_rect->y) + (area_rect->h))));
|
||||
}
|
||||
|
||||
void Load_Textures(SDL_Renderer * renderer) {
|
||||
TITLE_Texture = IMG_LoadTexture(renderer, "assets/images/breaking_button.png");
|
||||
TITLE_Rect = (SDL_Rect) {.x = 685, .y = 50, .w = 550, .h = 250 };
|
||||
|
||||
PLAYBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/play_button.png");
|
||||
PLAYBUTTON_Rect = (SDL_Rect) {.x = 497, .y = 400, .w = 313, .h = 178 };
|
||||
|
||||
SKINSBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/skins_button.png");
|
||||
SKINSBUTTON_Rect = (SDL_Rect) {.x = 1110, .y = 400, .w = 313, .h = 178 };
|
||||
|
||||
LEVELBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/level_button.png");
|
||||
LEVELBUTTON_Rect = (SDL_Rect) {.x = 497, .y = 700, .w = 313, .h = 178 };
|
||||
|
||||
SETTINGSBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/settings_button.png");
|
||||
SETTINGSBUTTON_Rect = (SDL_Rect) {.x = 1110, .y = 700, .w = 313, .h = 178 };
|
||||
|
||||
HIGHSCORESBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/highscores_button.png");
|
||||
HIGHSCORESBUTTON_Rect = (SDL_Rect) {.x = 1557, .y = 120, .w = 313, .h = 178 };
|
||||
|
||||
QUITBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/quit_button.png");
|
||||
QUITBUTTON_Rect = (SDL_Rect) {.x = 50, .y = 896, .w = 235, .h = 134 };
|
||||
} /* Load_Textures */
|
||||
|
||||
void Startmenu_Draw(SDL_Renderer * renderer) {
|
||||
SDL_RenderCopy(renderer, TITLE_Texture, NULL, &TITLE_Rect);
|
||||
SDL_RenderCopy(renderer, PLAYBUTTON_Texture, NULL, &PLAYBUTTON_Rect);
|
||||
SDL_RenderCopy(renderer, SKINSBUTTON_Texture, NULL, &SKINSBUTTON_Rect);
|
||||
SDL_RenderCopy(renderer, LEVELBUTTON_Texture, NULL, &LEVELBUTTON_Rect);
|
||||
SDL_RenderCopy(renderer, SETTINGSBUTTON_Texture, NULL, &SETTINGSBUTTON_Rect);
|
||||
SDL_RenderCopy(renderer, HIGHSCORESBUTTON_Texture, NULL, &HIGHSCORESBUTTON_Rect);
|
||||
SDL_RenderCopy(renderer, QUITBUTTON_Texture, NULL, &QUITBUTTON_Rect);
|
||||
}
|
||||
|
||||
void button_clicked(SDL_MouseButtonEvent b, GameState gameState) {
|
||||
if (gameState == MainMenu) {
|
||||
if (clickInRect(b, &PLAYBUTTON_Rect) == 1) {
|
||||
GAME_ChangeState(Game);
|
||||
} else if (clickInRect(b, &SKINSBUTTON_Rect) == 1) {
|
||||
GAME_ChangeState(SkinSelect);
|
||||
} else if (clickInRect(b, &LEVELBUTTON_Rect) == 1) {
|
||||
GAME_ChangeState(LevelSelect);
|
||||
} else if (clickInRect(b, &SETTINGSBUTTON_Rect) == 1) {
|
||||
GAME_ChangeState(Settings);
|
||||
} else if (clickInRect(b, &HIGHSCORESBUTTON_Rect) == 1) {
|
||||
GAME_ChangeState(Highscores);
|
||||
} else if (clickInRect(b, &QUITBUTTON_Rect) == 1) {
|
||||
GAME_Escape();
|
||||
}
|
||||
}
|
||||
}
|
20
startmenu.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __Startmenu__
|
||||
|
||||
#define __Startmenu__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
#include "gamestate.h"
|
||||
|
||||
void Load_Textures (SDL_Renderer* renderer);
|
||||
|
||||
void Startmenu_Draw (SDL_Renderer* renderer);
|
||||
|
||||
void button_clicked(SDL_MouseButtonEvent b, GameState gameState);
|
||||
|
||||
int clickInRect(SDL_MouseButtonEvent b, SDL_Rect* area_rect);
|
||||
|
||||
#endif
|