2018-01-09 13:22:10 +01:00
|
|
|
#include <stdio.h>
|
2018-01-10 23:40:17 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
2018-01-09 13:22:10 +01:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#include <SDL2/SDL_ttf.h>
|
|
|
|
|
2018-01-10 15:37:55 +01:00
|
|
|
#include "breakout.h"
|
2018-01-09 13:22:10 +01:00
|
|
|
#include "vector.h"
|
|
|
|
|
|
|
|
#ifndef __nullptr__
|
|
|
|
#define Nullptr(type) (type *)0
|
|
|
|
#endif // __nullptr__
|
|
|
|
|
2018-01-12 10:47:14 +01:00
|
|
|
int BLOCK_TextureCount = 24;
|
2018-01-10 15:37:55 +01:00
|
|
|
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight;
|
|
|
|
SDL_Texture * BALL_Texture;
|
2018-01-12 09:47:32 +01:00
|
|
|
SDL_Texture * PADDLE_Texture;
|
|
|
|
SDL_Texture * BLOCK_Texture;
|
2018-01-10 23:40:17 +01:00
|
|
|
SDL_Rect * BALL_SourceRects;
|
2018-01-12 09:47:32 +01:00
|
|
|
SDL_Rect * PADDLE_SourceRects;
|
|
|
|
SDL_Rect * BLOCK_SourceRects;
|
2018-01-10 23:40:17 +01:00
|
|
|
Ball ball;
|
2018-01-11 01:06:55 +01:00
|
|
|
Paddle paddle;
|
2018-01-12 10:47:14 +01:00
|
|
|
Block * blocks;
|
2018-01-15 15:35:25 +01:00
|
|
|
int BlockCount = 60; // Move to scenery
|
2018-01-11 01:06:55 +01:00
|
|
|
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
|
2018-01-11 19:03:12 +01:00
|
|
|
double BALL_Speed = 15.0f;
|
2018-01-11 14:12:30 +01:00
|
|
|
int PADDLE_Speed = 10;
|
2018-01-11 18:45:00 +01:00
|
|
|
bool BREAKOUT_IsInit = false;
|
|
|
|
bool BALL_IsInit = false;
|
|
|
|
bool PADDLE_IsInit = false;
|
2018-01-12 09:47:32 +01:00
|
|
|
bool BLOCK_IsInit = false;
|
2018-01-09 13:22:10 +01:00
|
|
|
|
2018-01-10 15:37:55 +01:00
|
|
|
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!BREAKOUT_IsInit) {
|
|
|
|
printf("Initializing Game...\n");
|
|
|
|
srand(time(NULL));
|
|
|
|
BREAKOUT_BoxWidth = width;
|
|
|
|
BREAKOUT_BoxHeight = height;
|
|
|
|
BALL_Initialize(renderer);
|
|
|
|
PADDLE_Initialize(renderer);
|
2018-01-12 10:47:14 +01:00
|
|
|
BLOCK_Initialize(renderer);
|
2018-01-12 09:47:32 +01:00
|
|
|
ball = BALL_CreateDefault();
|
|
|
|
paddle = PADDLE_CreateDefault();
|
2018-01-12 10:47:14 +01:00
|
|
|
blocks = malloc(BlockCount * sizeof(Block));
|
|
|
|
int index;
|
2018-01-15 15:35:25 +01:00
|
|
|
for (int y = 0; y < 6; y++) {
|
|
|
|
index = 10 * y;
|
|
|
|
for (int x = 0; x < 10; x++) {
|
2018-01-12 10:47:14 +01:00
|
|
|
blocks[x + index] = BLOCK_CreateDefault();
|
2018-01-15 15:35:25 +01:00
|
|
|
blocks[x + index].TargetRect = (SDL_Rect) {.x = ((192 * x) + 4), .y = ((96 * y) + 2), .w = 184, .h = 92 };
|
2018-01-12 10:47:14 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-11 18:45:00 +01:00
|
|
|
printf("Game initialized!\n");
|
|
|
|
BREAKOUT_IsInit = true;
|
|
|
|
} else printf("Game is already initialized!\n");
|
2018-01-12 10:47:14 +01:00
|
|
|
} /* BREAKOUT_INITIALIZE */
|
2018-01-11 18:45:00 +01:00
|
|
|
|
|
|
|
void BREAKOUT_ChangeSize(int width, int height){
|
2018-01-10 15:37:55 +01:00
|
|
|
BREAKOUT_BoxWidth = width;
|
|
|
|
BREAKOUT_BoxHeight = height;
|
|
|
|
}
|
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
void BREAKOUT_Update(Uint8 * keystate){
|
2018-01-12 14:04:44 +01:00
|
|
|
PADDLE_Update(&paddle, keystate); // Update paddle before ball because paddle is not static!
|
2018-01-11 14:12:30 +01:00
|
|
|
BALL_Update(&ball, &paddle);
|
2018-01-12 10:47:14 +01:00
|
|
|
for (size_t i = 0; i < BlockCount; i++) {
|
|
|
|
BLOCK_Update(blocks + i);
|
|
|
|
}
|
2018-01-10 15:37:55 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
void BREAKOUT_Draw(SDL_Renderer * renderer){
|
2018-01-15 15:35:25 +01:00
|
|
|
for (int i = 0; i < BlockCount; i++) {
|
|
|
|
BLOCK_Draw(renderer, &(blocks[i]));
|
2018-01-12 10:47:14 +01:00
|
|
|
}
|
2018-01-10 23:40:17 +01:00
|
|
|
BALL_Draw(renderer, &ball);
|
2018-01-11 01:06:55 +01:00
|
|
|
PADDLE_Draw(renderer, &paddle);
|
2018-01-10 15:37:55 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
void BREAKOUT_DEINITIALIZE(){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (BREAKOUT_IsInit) {
|
|
|
|
printf("De-initializing Game...\n");
|
2018-01-12 10:47:14 +01:00
|
|
|
for (size_t i = 0; i < BlockCount; i++) {
|
|
|
|
BLOCK_DestroyObject(blocks + i);
|
|
|
|
}
|
|
|
|
free(blocks);
|
|
|
|
free(PADDLE_MoveLeftKeys);
|
|
|
|
free(PADDLE_MoveRightKeys);
|
|
|
|
free(BALL_SourceRects);
|
|
|
|
free(PADDLE_SourceRects);
|
|
|
|
free(BLOCK_SourceRects);
|
|
|
|
BALL_Deinitialize();
|
|
|
|
PADDLE_Deinitialize();
|
|
|
|
BLOCK_Deinitialize();
|
2018-01-11 18:45:00 +01:00
|
|
|
printf("Game de-initialized!\n");
|
|
|
|
BREAKOUT_IsInit = false;
|
|
|
|
} else printf("Game is already de-initialized!\n");
|
2018-01-09 13:22:10 +01:00
|
|
|
}
|
2018-01-10 23:40:17 +01:00
|
|
|
|
|
|
|
void BALL_Initialize(SDL_Renderer * renderer){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!BALL_IsInit) {
|
|
|
|
printf("Initializing Ball...\n");
|
|
|
|
BALL_Texture = IMG_LoadTexture(renderer, "assets/images/ball.png");
|
|
|
|
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 };
|
|
|
|
printf("Ball initialized!\n");
|
|
|
|
BALL_IsInit = true;
|
|
|
|
} else printf("Ball is already initialized!\n");
|
2018-01-10 23:40:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Ball BALL_CreateDefault(){
|
|
|
|
double rotation = (double)(rand() % 360);
|
|
|
|
|
|
|
|
return (Ball) {
|
2018-01-12 10:47:14 +01:00
|
|
|
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 },
|
2018-01-11 19:03:12 +01:00
|
|
|
.Momentum = (Vector) {.x = 0.0f, .y = BALL_Speed },
|
2018-01-11 01:06:55 +01:00
|
|
|
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 50, .h = 50 },
|
|
|
|
.Size = 25.0f,
|
2018-01-10 23:40:17 +01:00
|
|
|
.Rotation = rotation,
|
|
|
|
.RotationValue = 2,
|
|
|
|
.TextureIndex = 0
|
|
|
|
}; // Objekt für die Eigenschaften des Balls
|
|
|
|
}
|
|
|
|
|
|
|
|
void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
|
2018-01-11 01:06:55 +01:00
|
|
|
// printf("Ball drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x);
|
2018-01-10 23:40:17 +01:00
|
|
|
SDL_RenderCopyEx(renderer, BALL_Texture, BALL_SourceRects + (obj->TextureIndex), &(obj->TargetRect), obj->Rotation, NULL, SDL_FLIP_NONE);
|
|
|
|
}
|
|
|
|
|
2018-01-11 14:12:30 +01:00
|
|
|
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){
|
2018-01-12 14:04:44 +01:00
|
|
|
SDL_Point ballCenter = BALL_GetCenter(obj);
|
2018-01-11 14:12:30 +01:00
|
|
|
|
2018-01-15 13:54:17 +01:00
|
|
|
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 = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
|
|
|
|
Vector corner = (Vector) {0, 0 };
|
2018-01-12 14:04:44 +01:00
|
|
|
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt!
|
2018-01-15 13:54:17 +01:00
|
|
|
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;
|
|
|
|
if (!(yMid || xMid)) { // Ball collides with corner
|
|
|
|
perpendicular = vectorRotation(vectorSub(center, corner));
|
|
|
|
angle = fabs(perpendicular - oldMomentum);
|
|
|
|
if (oldMomentum < perpendicular)
|
|
|
|
(obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), BALL_Speed);
|
|
|
|
else
|
|
|
|
(obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), BALL_Speed);
|
|
|
|
} else { // Ball collides with Edge
|
|
|
|
if (yMid)
|
|
|
|
(obj->Momentum).y = -(obj->Momentum).y;
|
|
|
|
else
|
|
|
|
(obj->Momentum).x = -(obj->Momentum).x;
|
2018-01-11 14:12:30 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} /* BALL_CollideWithRect */
|
|
|
|
|
|
|
|
bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2){
|
|
|
|
if ((rect1->x) + (rect1->w) < (rect2->x)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ((rect1->x) > (rect2->x) + (rect2->w)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ((rect1->y) + (rect1->w) < (rect2->y)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ((rect1->y) > (rect2->y) + (rect2->h)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-01-11 19:03:12 +01:00
|
|
|
void BALL_SteerMomentum(Ball * obj, Paddle * paddle){
|
|
|
|
int paddleHalfLen = ((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);
|
2018-01-12 14:04:44 +01:00
|
|
|
(obj->Momentum) = getDirectionalUnitVector(offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){
|
|
|
|
rect->x = (int)round(Location->x);
|
|
|
|
rect->y = (int)round(Location->y);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Point BALL_GetCenter(Ball * obj){
|
|
|
|
return (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
|
2018-01-11 19:03:12 +01:00
|
|
|
}
|
2018-01-11 14:12:30 +01:00
|
|
|
|
2018-01-11 19:03:12 +01:00
|
|
|
void BALL_Update(Ball * obj, Paddle * paddle){
|
2018-01-11 19:05:22 +01:00
|
|
|
Vector oldMomentum = obj->Momentum;
|
2018-01-12 14:04:44 +01:00
|
|
|
Vector oldLocation = obj->Location;
|
|
|
|
SDL_Point ballCenter = BALL_GetCenter(obj);
|
2018-01-11 19:05:22 +01:00
|
|
|
|
2018-01-12 14:04:44 +01:00
|
|
|
(obj->Rotation) += (obj->RotationValue); // No effect on physics
|
2018-01-11 19:05:22 +01:00
|
|
|
(obj->Location) = vectorAdd((obj->Location), oldMomentum);
|
2018-01-11 14:12:30 +01:00
|
|
|
|
|
|
|
if (BALL_CollideWithRect(obj, &(paddle->TargetRect))) {
|
2018-01-12 14:04:44 +01:00
|
|
|
(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
|
2018-01-12 16:49:17 +01:00
|
|
|
// BUG/GLITCH: Make sure that the postition of the ball is not shifted into the borders of the game!
|
2018-01-12 14:04:44 +01:00
|
|
|
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), BALL_Speed);
|
2018-01-11 14:12:30 +01:00
|
|
|
}
|
2018-01-12 10:47:14 +01:00
|
|
|
for (size_t i = 0; i < BlockCount; i++) {
|
2018-01-12 16:49:17 +01:00
|
|
|
if (blocks[i].HP <= 0) continue;
|
2018-01-12 14:04:44 +01:00
|
|
|
oldMomentum = obj->Momentum;
|
2018-01-15 13:54:17 +01:00
|
|
|
oldLocation = obj->Location;
|
2018-01-12 16:49:17 +01:00
|
|
|
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
|
|
|
|
BLOCK_DealDamage(blocks + i, 1);
|
2018-01-15 13:54:17 +01:00
|
|
|
(obj->Location) = vectorAdd(oldLocation, (obj->Momentum));
|
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
2018-01-12 16:49:17 +01:00
|
|
|
}
|
2018-01-12 10:47:14 +01:00
|
|
|
}
|
2018-01-11 14:12:30 +01:00
|
|
|
|
2018-01-15 13:54:17 +01:00
|
|
|
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)
|
2018-01-11 01:06:55 +01:00
|
|
|
(obj->Momentum).y = -(obj->Momentum).y;
|
2018-01-11 14:12:30 +01:00
|
|
|
if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size)))
|
2018-01-11 01:06:55 +01:00
|
|
|
(obj->Momentum).x = -(obj->Momentum).x;
|
2018-01-12 16:49:17 +01:00
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
2018-01-11 14:12:30 +01:00
|
|
|
} /* BALL_Update */
|
2018-01-15 13:54:17 +01:00
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
void BALL_DestroyObject(Ball * obj){
|
|
|
|
}
|
2018-01-15 13:54:17 +01:00
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
void BALL_Deinitialize(){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (BALL_IsInit) {
|
|
|
|
printf("De-initializing Ball...\n");
|
2018-01-12 10:47:14 +01:00
|
|
|
SDL_DestroyTexture(BALL_Texture);
|
2018-01-11 18:45:00 +01:00
|
|
|
printf("Ball de-initialized!\n");
|
|
|
|
BALL_IsInit = false;
|
|
|
|
} else printf("Ball is already de-initialized!\n");
|
2018-01-10 23:40:17 +01:00
|
|
|
}
|
2018-01-11 01:06:55 +01:00
|
|
|
|
|
|
|
void PADDLE_Initialize(SDL_Renderer * renderer){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!PADDLE_IsInit) {
|
|
|
|
printf("Initializing Paddle...\n");
|
|
|
|
PADDLE_Texture = IMG_LoadTexture(renderer, "assets/images/paddle.png");
|
|
|
|
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_MoveLeftKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
|
|
|
|
if (!PADDLE_MoveLeftKeys) printf("FATAL! Memory allocation failed!\n");
|
|
|
|
PADDLE_MoveRightKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
|
|
|
|
if (!PADDLE_MoveRightKeys) printf("FATAL! Memory allocation failed!\n");
|
|
|
|
PADDLE_MoveLeftKeys[0] = 2; // Erster wert gibt größe des arrays an
|
|
|
|
PADDLE_MoveLeftKeys[1] = SDL_SCANCODE_LEFT;
|
|
|
|
PADDLE_MoveLeftKeys[2] = SDL_SCANCODE_A;
|
|
|
|
PADDLE_MoveRightKeys[0] = 2;
|
|
|
|
PADDLE_MoveRightKeys[1] = SDL_SCANCODE_RIGHT;
|
|
|
|
PADDLE_MoveRightKeys[2] = SDL_SCANCODE_D;
|
|
|
|
printf("Paddle initialized!\n");
|
|
|
|
PADDLE_IsInit = true;
|
|
|
|
} else printf("Paddle is already initialized!\n");
|
|
|
|
} /* PADDLE_Initialize */
|
2018-01-11 01:06:55 +01:00
|
|
|
|
|
|
|
Paddle PADDLE_CreateDefault(){
|
|
|
|
int defaultpaddlewidth = 300;
|
|
|
|
|
|
|
|
return (Paddle) {
|
|
|
|
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 },
|
|
|
|
.TextureIndex = 0
|
|
|
|
}; // 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);
|
2018-01-11 19:03:12 +01:00
|
|
|
// SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
|
|
|
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
|
|
|
SDL_RenderDrawRect(renderer, &(obj->TargetRect));
|
2018-01-11 01:06:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyPressed(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){
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (leftKeyPressed && (!rightKeyPressed)) {
|
2018-01-11 14:12:30 +01:00
|
|
|
((obj->TargetRect).x) -= PADDLE_Speed;
|
2018-01-11 01:06:55 +01:00
|
|
|
} else if ((!leftKeyPressed) && rightKeyPressed) {
|
2018-01-11 14:12:30 +01:00
|
|
|
((obj->TargetRect).x) += PADDLE_Speed;
|
2018-01-11 01:06:55 +01:00
|
|
|
}
|
|
|
|
constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w)));
|
|
|
|
}
|
2018-01-12 16:49:17 +01:00
|
|
|
|
2018-01-11 01:06:55 +01:00
|
|
|
void PADDLE_DestroyObject(Paddle * obj){
|
|
|
|
}
|
2018-01-15 13:54:17 +01:00
|
|
|
|
2018-01-11 01:06:55 +01:00
|
|
|
void PADDLE_Deinitialize(){
|
2018-01-12 09:47:32 +01:00
|
|
|
if (PADDLE_IsInit) {
|
|
|
|
printf("De-initializing Paddle...\n");
|
2018-01-12 10:47:14 +01:00
|
|
|
SDL_DestroyTexture(PADDLE_Texture);
|
2018-01-12 09:47:32 +01:00
|
|
|
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");
|
2018-01-12 10:47:14 +01:00
|
|
|
BLOCK_Texture = IMG_LoadTexture(renderer, "assets/images/blocks_debug.png");
|
|
|
|
if (!BLOCK_Texture) printf("Block texture failed to load!\n");
|
|
|
|
BLOCK_SourceRects = (SDL_Rect *)malloc(BLOCK_TextureCount * sizeof(SDL_Rect));
|
2018-01-12 09:47:32 +01:00
|
|
|
if (!BLOCK_SourceRects) printf("FATAL! Memory allocation failed!\n");
|
2018-01-12 10:47:14 +01:00
|
|
|
for (int i = 0; i < BLOCK_TextureCount; i++) {
|
|
|
|
// TODO: All textures!
|
|
|
|
BLOCK_SourceRects[i] = (SDL_Rect) {.x = 0, .y = 500 * i * 0, .w = 1000, .h = 500 };
|
2018-01-12 09:47:32 +01:00
|
|
|
}
|
|
|
|
printf("Block initialized!\n");
|
|
|
|
BLOCK_IsInit = true;
|
|
|
|
} else printf("Block is already initialized!\n");
|
|
|
|
} /* PADDLE_Initialize */
|
|
|
|
|
2018-01-12 10:47:14 +01:00
|
|
|
Block BLOCK_CreateDefault() {
|
2018-01-12 09:47:32 +01:00
|
|
|
int defaultpaddlewidth = 300;
|
|
|
|
|
|
|
|
return (Block) {
|
2018-01-12 10:47:14 +01:00
|
|
|
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = 150, .h = 75 },
|
2018-01-12 16:49:17 +01:00
|
|
|
.TextureIndex = (rand() % BLOCK_TextureCount),
|
|
|
|
.HP = 1
|
2018-01-12 09:47:32 +01:00
|
|
|
}; // Objekt für die Eigenschaften des Balls
|
|
|
|
}
|
|
|
|
|
2018-01-12 10:47:14 +01:00
|
|
|
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj){
|
2018-01-12 16:49:17 +01:00
|
|
|
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");
|
2018-01-12 09:47:32 +01:00
|
|
|
}
|
|
|
|
|
2018-01-12 10:47:14 +01:00
|
|
|
void BLOCK_Update(Block * obj){
|
|
|
|
// Do nothing currently
|
2018-01-12 09:47:32 +01:00
|
|
|
}
|
2018-01-12 10:47:14 +01:00
|
|
|
void BLOCK_DestroyObject(Block * obj){
|
2018-01-12 09:47:32 +01:00
|
|
|
}
|
2018-01-15 13:54:17 +01:00
|
|
|
|
2018-01-12 09:47:32 +01:00
|
|
|
void BLOCK_Deinitialize(){
|
2018-01-12 10:47:14 +01:00
|
|
|
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");
|
2018-01-11 01:06:55 +01:00
|
|
|
}
|