Added ingame HUD and texture helper functions
This commit is contained in:
parent
3b2a0c8741
commit
d7e5845e4e
116
breakout.c
116
breakout.c
@ -9,8 +9,12 @@
|
||||
|
||||
#include "breakout.h"
|
||||
#include "vector.h"
|
||||
#include "gamestate.h"
|
||||
#include "gameover.h"
|
||||
#include "main.h"
|
||||
|
||||
extern float XScale, YScale;
|
||||
extern int width, height;
|
||||
|
||||
#define BALL_TexturePath "assets/images/ball.png"
|
||||
#define PADDLE_TexturePath "assets/images/paddle.png"
|
||||
@ -19,6 +23,8 @@ extern float XScale, YScale;
|
||||
#define BALL_MinSpeed 8.0f
|
||||
#define BALL_MaxSpeed 50.0f
|
||||
#define BALL_AccelerationTime 18000
|
||||
#define BREAKOUT_LiveHUDSize 35
|
||||
#define BREAKOUT_LiveHUDMargin 8
|
||||
|
||||
#ifndef __nullptr__
|
||||
#define Nullptr(type) (type *)0
|
||||
@ -29,7 +35,6 @@ int BLOCK_TextureCount = 24;
|
||||
int BALL_TextureCount = 9;
|
||||
int GAME_CountdownTextureCount = 4;
|
||||
int PADDLE_TextureCount = 9;
|
||||
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight;
|
||||
SDL_Texture * BALL_Texture;
|
||||
SDL_Texture * GAME_CountdownTexture;
|
||||
SDL_Texture * PADDLE_Texture;
|
||||
@ -44,12 +49,10 @@ bool BALL_IsInit = false;
|
||||
bool PADDLE_IsInit = false;
|
||||
bool BLOCK_IsInit = false;
|
||||
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer){
|
||||
if (!BREAKOUT_IsInit) {
|
||||
printf("Initializing Game...\n");
|
||||
srand(time(NULL));
|
||||
BREAKOUT_BoxWidth = width;
|
||||
BREAKOUT_BoxHeight = height;
|
||||
BALL_Initialize(renderer);
|
||||
PADDLE_Initialize(renderer);
|
||||
BLOCK_Initialize(renderer);
|
||||
@ -94,18 +97,15 @@ Scenery BREAKOUT_CreateDefault(){
|
||||
return scenery;
|
||||
} /* BREAKOUT_CreateDefault */
|
||||
|
||||
|
||||
int BREAKOUT_RefreshScore(Scenery * scenery){
|
||||
(scenery->Score) = (int)round((double)(scenery->Frames) * 0.005f * ((scenery->ball).Speed) + (double)(50 * (scenery->DestroyedBlocks)));
|
||||
printf("Score: %d\n", (scenery->Score));
|
||||
return (scenery->Score);
|
||||
void BREAKOUT_IncreaseScoreBy(Scenery * scenery, int scoreInc){
|
||||
(scenery->Score) += scoreInc;
|
||||
}
|
||||
|
||||
// This Function is obsolete! Do not use it!
|
||||
void BREAKOUT_ChangeSize(int width, int height){
|
||||
BREAKOUT_BoxWidth = width;
|
||||
BREAKOUT_BoxHeight = height;
|
||||
}
|
||||
// int BREAKOUT_RefreshScore(Scenery * scenery){
|
||||
// (scenery->Score) = (int)round(((scenery->ball).Speed) * (double)(scenery->DestroyedBlocks));
|
||||
// printf("Score: %d\n", (scenery->Score));
|
||||
// return (scenery->Score);
|
||||
// }
|
||||
|
||||
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
|
||||
if (scenery->IsPaused) {
|
||||
@ -113,11 +113,10 @@ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
|
||||
return;
|
||||
}
|
||||
if ((scenery->StartCountdown)-- > 0) {
|
||||
// Render "Countdown"
|
||||
// SDL_WarpMouse(960, 540); Doesn't exist
|
||||
return;
|
||||
}
|
||||
(scenery->Frames)++;
|
||||
BREAKOUT_RefreshScore(scenery);
|
||||
if (scenery->IsGameOver) {
|
||||
BALL_ResetPosition(&(scenery->ball));
|
||||
PADDLE_ResetPosition(&(scenery->paddle));
|
||||
@ -125,7 +124,7 @@ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
|
||||
scenery->IsGameOver = false;
|
||||
scenery->Frames = 0;
|
||||
if (--(scenery->Lives) <= 0)
|
||||
printf("Game over, no lives left!\n");
|
||||
GAME_ChangeState(GameOver);
|
||||
else
|
||||
printf("Oh oh, only %d lives left!\n", scenery->Lives);
|
||||
return;
|
||||
@ -146,10 +145,26 @@ void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
|
||||
if ((scenery->StartCountdown) > 0) { // ! Render Z-Layer !
|
||||
SDL_Rect * rect = GAME_CountdownSourceRects + (((scenery->StartCountdown) - 1) / 60);
|
||||
SDL_Rect target = *rect;
|
||||
target.x = ((BREAKOUT_BoxWidth - (rect->w)) / 2);
|
||||
target.y = ((BREAKOUT_BoxHeight - (rect->h)) / 2);
|
||||
target.x = ((width - (rect->w)) / 2);
|
||||
target.y = ((height - (rect->h)) / 2);
|
||||
SDL_RenderCopy(renderer, GAME_CountdownTexture, rect, &target);
|
||||
}
|
||||
SCORE_DrawHUD(renderer, scenery);
|
||||
BREAKOUT_DrawLivesHUD(renderer, scenery);
|
||||
}
|
||||
|
||||
void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery){
|
||||
SDL_Rect tmpRect;
|
||||
|
||||
tmpRect.y = BREAKOUT_LiveHUDMargin;
|
||||
tmpRect.w = BREAKOUT_LiveHUDSize;
|
||||
tmpRect.h = BREAKOUT_LiveHUDSize;
|
||||
tmpRect.x = width - BREAKOUT_LiveHUDMargin;
|
||||
|
||||
for (int i = 0; i < (scenery->Lives); i++) {
|
||||
tmpRect.x -= (BREAKOUT_LiveHUDSize + BREAKOUT_LiveHUDMargin);
|
||||
BALL_DrawTexture(renderer, &tmpRect, (scenery->ball).TextureIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void BREAKOUT_DEINITIALIZE(){
|
||||
@ -202,27 +217,33 @@ void BALL_Initialize(SDL_Renderer * renderer){
|
||||
} /* BALL_Initialize */
|
||||
|
||||
Ball BALL_CreateDefault(){
|
||||
double rotation = (double)(rand() % 360);
|
||||
|
||||
return (Ball) {
|
||||
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 - 15, .y = BREAKOUT_BoxHeight - 132 },
|
||||
.Momentum = (Vector) {.x = 0.0f, .y = 15.0f },
|
||||
.TargetRect = (SDL_Rect) {.x = BREAKOUT_BoxWidth / 2 - 15, .y = BREAKOUT_BoxHeight - 130, .w = 30, .h = 30 },
|
||||
.Location = (Vector) {.x = (width / 2) - 15, .y = height - 132 },
|
||||
.Momentum = (Vector) {.x = 0.0f, .y = BALL_MinSpeed },
|
||||
.TargetRect = (SDL_Rect) {.x = width / 2 - 15, .y = height - 130, .w = 30, .h = 30 },
|
||||
.Size = 15.0f,
|
||||
.Rotation = rotation,
|
||||
.RotationValue = 5,
|
||||
.Rotation = 0,
|
||||
.RotationValue = 9,
|
||||
.TextureIndex = 0,
|
||||
.Speed = 15.0f
|
||||
}; // Objekt für die Eigenschaften des Balls
|
||||
}
|
||||
|
||||
void BALL_ResetPosition(Ball * obj){
|
||||
(obj->Location).x = BREAKOUT_BoxWidth / 2 - 15;
|
||||
(obj->Location).y = BREAKOUT_BoxHeight - 130;
|
||||
(obj->Location).x = width / 2 - 15;
|
||||
(obj->Location).y = height - 130;
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
(obj->Momentum) = VECTOR_GetScaledDirectionalUnitVector(0.0f, (obj->Speed));
|
||||
}
|
||||
|
||||
void BALL_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
|
||||
if (index > BALL_TextureCount || index < 0) {
|
||||
printf("Ball with unkown texture index %d aus [0,...,%d]\n", index, (BALL_TextureCount - 1));
|
||||
return;
|
||||
}
|
||||
SDL_RenderCopy(renderer, BALL_Texture, BALL_SourceRects + index, dstRect);
|
||||
}
|
||||
|
||||
void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
|
||||
// printf("Ball drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x);
|
||||
SDL_RenderCopyEx(renderer, BALL_Texture, BALL_SourceRects + (obj->TextureIndex), &(obj->TargetRect), obj->Rotation, NULL, SDL_FLIP_NONE);
|
||||
@ -308,7 +329,7 @@ SDL_Point BALL_GetCenter(Ball * obj){
|
||||
void BALL_CollideWithBorders(Ball * obj){
|
||||
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)))
|
||||
if ((obj->Location).x < 0.0f || (obj->Location).x > width - (2 * (obj->Size)))
|
||||
(obj->Momentum).x = -(obj->Momentum).x;
|
||||
}
|
||||
|
||||
@ -317,7 +338,7 @@ void BALL_MoveAwayFromBoundaries(Ball * obj){
|
||||
((obj->Location).y)++;
|
||||
while (((obj->Location).x) < 0)
|
||||
((obj->Location).x)++;
|
||||
while ((((obj->Location).x) + ((obj->Size) * 2)) > BREAKOUT_BoxWidth)
|
||||
while ((((obj->Location).x) + ((obj->Size) * 2)) > width)
|
||||
((obj->Location).x)--;
|
||||
}
|
||||
|
||||
@ -328,7 +349,7 @@ bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle){
|
||||
BALL_CollideWithRect(obj, &(paddle->TargetRect));
|
||||
else
|
||||
BALL_SteerMomentum(obj, paddle); // Sets it to unit vector!
|
||||
// Following assumes that the paddle position was udated before the ball was updated
|
||||
// Following assumes that the paddle position was udated before the ball was updated
|
||||
while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps
|
||||
(obj->Location) = VECTOR_Add((obj->Location), (obj->Momentum));
|
||||
BALL_MoveAwayFromBoundaries(obj);
|
||||
@ -367,16 +388,19 @@ void BALL_Update(Ball * obj, Scenery * scenery){
|
||||
oldLocation = obj->Location;
|
||||
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
|
||||
BLOCK_DealDamage(blocks + i, 1);
|
||||
if (blocks[i].HP <= 0)
|
||||
if (blocks[i].HP <= 0) {
|
||||
(scenery->DestroyedBlocks)++;
|
||||
BREAKOUT_IncreaseScoreBy(scenery, (int)round((((scenery->ball).Speed) * ((scenery->ball).Speed) / 5.0f)));
|
||||
}
|
||||
(obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum));
|
||||
BALL_MoveAwayFromBoundaries(obj);
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
}
|
||||
}
|
||||
if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
|
||||
if ((obj->Location).y > height) { // Collide with box boundaries
|
||||
scenery->IsGameOver = true;
|
||||
else BALL_CollideWithBorders(obj);
|
||||
printf("Ball called game_over!\n");
|
||||
} else BALL_CollideWithBorders(obj);
|
||||
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
||||
} /* BALL_Update */
|
||||
|
||||
@ -419,7 +443,7 @@ Paddle PADDLE_CreateDefault(){
|
||||
int defaultpaddlewidth = 300;
|
||||
|
||||
return (Paddle) {
|
||||
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 },
|
||||
.TargetRect = (SDL_Rect) {.x = (width - defaultpaddlewidth) / 2, .y = height - 100, .w = defaultpaddlewidth, .h = 30 },
|
||||
.TextureIndex = 0,
|
||||
.Speed = 10,
|
||||
.SteeringAngle = 40.0f,
|
||||
@ -428,8 +452,16 @@ Paddle PADDLE_CreateDefault(){
|
||||
}
|
||||
|
||||
void PADDLE_ResetPosition(Paddle * obj){
|
||||
(obj->TargetRect).x = (BREAKOUT_BoxWidth - ((obj->TargetRect).w)) / 2;
|
||||
(obj->TargetRect).y = BREAKOUT_BoxHeight - 100;
|
||||
(obj->TargetRect).x = (width - ((obj->TargetRect).w)) / 2;
|
||||
(obj->TargetRect).y = height - 100;
|
||||
}
|
||||
|
||||
void PADDLE_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
|
||||
if (index > PADDLE_TextureCount || index < 0) {
|
||||
printf("Paddle with unkown texture index %d aus [0,...,%d]\n", index, (PADDLE_TextureCount - 1));
|
||||
return;
|
||||
}
|
||||
SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + index, dstRect);
|
||||
}
|
||||
|
||||
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){
|
||||
@ -488,7 +520,7 @@ void PADDLE_Update(Paddle * obj, const Uint8 * keystate){
|
||||
printf("Unknown Paddle Control Mode: %d!\n", obj->Mode);
|
||||
break;
|
||||
} /* switch */
|
||||
INT_Constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w)));
|
||||
INT_Constrain(&((obj->TargetRect).x), 0, (width - ((obj->TargetRect).w)));
|
||||
} /* PADDLE_Update */
|
||||
|
||||
void PADDLE_DestroyObject(Paddle * obj){
|
||||
@ -547,6 +579,14 @@ Block BLOCK_CreateDefault() {
|
||||
}; // Objekt für die Eigenschaften des Balls
|
||||
}
|
||||
|
||||
void BLOCK_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
|
||||
if (index > BLOCK_TextureCount || index < 0) {
|
||||
printf("Block with unkown texture index %d aus [0,...,%d]\n", index, (BLOCK_TextureCount - 1));
|
||||
return;
|
||||
}
|
||||
SDL_RenderCopy(renderer, BLOCK_Texture, BLOCK_SourceRects + index, dstRect);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -45,17 +45,18 @@ typedef struct sceneryStruct {
|
||||
// End Structs
|
||||
|
||||
// Prototypes
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height);
|
||||
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer);
|
||||
Scenery BREAKOUT_CreateDefault();
|
||||
int BREAKOUT_RefreshScore(Scenery * scenery);
|
||||
void BREAKOUT_ChangeSize(int width, int height);
|
||||
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate);
|
||||
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer);
|
||||
void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery);
|
||||
void BREAKOUT_DEINITIALIZE();
|
||||
void BREAKOUT_DestroyObject(Scenery * scenery);
|
||||
void BALL_Initialize(SDL_Renderer * renderer);
|
||||
Ball BALL_CreateDefault();
|
||||
void BALL_ResetPosition(Ball * obj);
|
||||
void BALL_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
|
||||
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);
|
||||
@ -72,6 +73,7 @@ void BALL_Deinitialize();
|
||||
void PADDLE_Initialize(SDL_Renderer * renderer);
|
||||
Paddle PADDLE_CreateDefault();
|
||||
void PADDLE_ResetPosition(Paddle * obj);
|
||||
void PADDLE_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
|
||||
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj);
|
||||
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray);
|
||||
void INT_Constrain(int * variable, int min, int max);
|
||||
@ -82,6 +84,7 @@ void PADDLE_DestroyObject(Paddle * obj);
|
||||
void PADDLE_Deinitialize();
|
||||
void BLOCK_Initialize(SDL_Renderer * renderer);
|
||||
Block BLOCK_CreateDefault() ;
|
||||
void BLOCK_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
|
||||
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj);
|
||||
void BLOCK_DealDamage(Block * obj, int dmg);
|
||||
void BLOCK_Update(Block * obj);
|
||||
|
Loading…
Reference in New Issue
Block a user