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"
|
2018-01-23 21:22:59 +01:00
|
|
|
#include "gamestate.h"
|
|
|
|
#include "gameover.h"
|
|
|
|
#include "main.h"
|
2018-01-09 13:22:10 +01:00
|
|
|
|
2018-01-21 19:41:29 +01:00
|
|
|
extern float XScale, YScale;
|
2018-01-23 21:22:59 +01:00
|
|
|
extern int width, height;
|
2018-01-21 19:41:29 +01:00
|
|
|
|
2018-01-22 23:06:22 +01:00
|
|
|
#define BALL_TexturePath "assets/images/ball.png"
|
|
|
|
#define PADDLE_TexturePath "assets/images/paddle.png"
|
|
|
|
#define BLOCK_TexturePath "assets/images/spritesheet.png"
|
|
|
|
#define BRAEKOUT_CountdownTexturePath "assets/images/text.png"
|
2018-01-23 22:13:57 +01:00
|
|
|
#define BRAEKOUT_PausedTexturePath "assets/images/paused.png"
|
2018-01-22 23:06:22 +01:00
|
|
|
#define BALL_MinSpeed 8.0f
|
2018-01-23 22:13:57 +01:00
|
|
|
#define BALL_MaxSpeed 25.0f
|
|
|
|
#define BALL_AccelerationTime 10000
|
|
|
|
#define PADDLE_MaxSize 300
|
|
|
|
#define PADDLE_MinSize 50
|
|
|
|
#define PADDLE_AccelerationTime 18000
|
2018-01-23 21:22:59 +01:00
|
|
|
#define BREAKOUT_LiveHUDSize 35
|
|
|
|
#define BREAKOUT_LiveHUDMargin 8
|
2018-01-16 12:10:37 +01:00
|
|
|
|
2018-01-09 13:22:10 +01:00
|
|
|
#ifndef __nullptr__
|
|
|
|
#define Nullptr(type) (type *)0
|
|
|
|
#endif // __nullptr__
|
|
|
|
|
2018-01-22 23:06:22 +01:00
|
|
|
float PADDLE_SmoothFactor = 0.1f;
|
2018-01-12 10:47:14 +01:00
|
|
|
int BLOCK_TextureCount = 24;
|
2018-01-22 23:06:22 +01:00
|
|
|
int BALL_TextureCount = 9;
|
2018-01-23 22:17:45 +01:00
|
|
|
int BREAKOUT_CountdownTextureCount = 4;
|
2018-01-22 23:06:22 +01:00
|
|
|
int PADDLE_TextureCount = 9;
|
2018-01-10 15:37:55 +01:00
|
|
|
SDL_Texture * BALL_Texture;
|
2018-01-23 22:17:45 +01:00
|
|
|
SDL_Texture * BREAKOUT_CountdownTexture;
|
2018-01-12 09:47:32 +01:00
|
|
|
SDL_Texture * PADDLE_Texture;
|
|
|
|
SDL_Texture * BLOCK_Texture;
|
2018-01-23 22:17:45 +01:00
|
|
|
SDL_Texture * BREAKOUT_PausedTexture;
|
2018-01-10 23:40:17 +01:00
|
|
|
SDL_Rect * BALL_SourceRects;
|
2018-01-23 22:17:45 +01:00
|
|
|
SDL_Rect * BREAKOUT_CountdownSourceRects;
|
2018-01-12 09:47:32 +01:00
|
|
|
SDL_Rect * PADDLE_SourceRects;
|
|
|
|
SDL_Rect * BLOCK_SourceRects;
|
2018-01-15 20:28:47 +01:00
|
|
|
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
|
|
|
|
bool BREAKOUT_IsInit = false;
|
|
|
|
bool BALL_IsInit = false;
|
|
|
|
bool PADDLE_IsInit = false;
|
|
|
|
bool BLOCK_IsInit = false;
|
2018-01-09 13:22:10 +01:00
|
|
|
|
2018-01-23 21:22:59 +01:00
|
|
|
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer){
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!BREAKOUT_IsInit) {
|
|
|
|
printf("Initializing Game...\n");
|
|
|
|
srand(time(NULL));
|
|
|
|
BALL_Initialize(renderer);
|
|
|
|
PADDLE_Initialize(renderer);
|
2018-01-12 10:47:14 +01:00
|
|
|
BLOCK_Initialize(renderer);
|
2018-01-23 22:17:45 +01:00
|
|
|
BREAKOUT_CountdownTexture = IMG_LoadTexture(renderer, BRAEKOUT_CountdownTexturePath);
|
|
|
|
if (!BREAKOUT_CountdownTexture) printf("Countdown texture failed to load!\n");
|
|
|
|
BREAKOUT_PausedTexture = IMG_LoadTexture(renderer, BRAEKOUT_PausedTexturePath);
|
|
|
|
if (!BREAKOUT_PausedTexture) printf("Paused texture failed to load!\n");
|
|
|
|
BREAKOUT_CountdownTextureCount = 4;
|
|
|
|
BREAKOUT_CountdownSourceRects = (SDL_Rect *)malloc(BREAKOUT_CountdownTextureCount * sizeof(SDL_Rect));
|
|
|
|
if (!BREAKOUT_CountdownSourceRects) printf("FATAL! Memory allocation failed!\n");
|
|
|
|
BREAKOUT_CountdownSourceRects[0] = (SDL_Rect) {.x = 1, .y = 668, .w = 1000, .h = 732 };
|
|
|
|
BREAKOUT_CountdownSourceRects[1] = (SDL_Rect) {.x = 1, .y = 1, .w = 242, .h = 665 };
|
|
|
|
BREAKOUT_CountdownSourceRects[2] = (SDL_Rect) {.x = 245, .y = 1, .w = 443, .h = 665 };
|
|
|
|
BREAKOUT_CountdownSourceRects[3] = (SDL_Rect) {.x = 690, .y = 1, .w = 443, .h = 665 };
|
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
|
|
|
|
2018-01-23 22:13:57 +01:00
|
|
|
void BREAKOUT_TogglePause(Scenery * scenery){
|
|
|
|
(scenery->IsPaused) = !(scenery->IsPaused);
|
|
|
|
printf("Game was %s!\n", ( (scenery->IsPaused) ? "paused" : "unpaused"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void BREAKOUT_KeyPressed(Scenery * scenery, SDL_KeyboardEvent * b){
|
|
|
|
if ((b->keysym).scancode == SDL_SCANCODE_ESCAPE) {
|
|
|
|
printf("Escape was pressed ingame! Toggle Pause...\n");
|
|
|
|
BREAKOUT_TogglePause(scenery);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
Scenery BREAKOUT_CreateDefault(){
|
|
|
|
Scenery scenery;
|
|
|
|
|
2018-01-21 15:33:09 +01:00
|
|
|
scenery.StartCountdown = 240;
|
|
|
|
scenery.IsGameOver = false;
|
|
|
|
scenery.BlockCount = 135;
|
2018-01-15 22:01:58 +01:00
|
|
|
scenery.ball = BALL_CreateDefault();
|
|
|
|
scenery.paddle = PADDLE_CreateDefault();
|
|
|
|
scenery.blocks = malloc(scenery.BlockCount * sizeof(Block));
|
2018-01-22 23:06:22 +01:00
|
|
|
scenery.Frames = 0;
|
2018-01-23 11:08:15 +01:00
|
|
|
scenery.Score = 0;
|
2018-01-21 15:33:09 +01:00
|
|
|
if (!(scenery.blocks)) printf("FATAL! Memory allocation failed!\n");
|
|
|
|
scenery.IsPaused = false;
|
|
|
|
scenery.Lives = 3;
|
2018-01-23 11:08:15 +01:00
|
|
|
scenery.DestroyedBlocks = 0;
|
2018-01-15 22:01:58 +01:00
|
|
|
int index;
|
2018-01-21 15:33:09 +01:00
|
|
|
for (int y = 0; y < 9; y++) {
|
|
|
|
index = 15 * y;
|
|
|
|
for (int x = 0; x < 15; x++) {
|
2018-01-15 22:01:58 +01:00
|
|
|
scenery.blocks[x + index] = BLOCK_CreateDefault();
|
2018-01-21 15:33:09 +01:00
|
|
|
scenery.blocks[x + index].TargetRect = (SDL_Rect) {.x = ((128 * x) + 2), .y = ((64 * y) + 1), .w = 124, .h = 62 };
|
|
|
|
scenery.blocks[x + index].TextureIndex = y + x;
|
2018-01-15 22:01:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return scenery;
|
2018-01-16 12:10:37 +01:00
|
|
|
} /* BREAKOUT_CreateDefault */
|
2018-01-15 22:01:58 +01:00
|
|
|
|
2018-01-23 21:22:59 +01:00
|
|
|
void BREAKOUT_IncreaseScoreBy(Scenery * scenery, int scoreInc){
|
|
|
|
(scenery->Score) += scoreInc;
|
2018-01-23 11:08:15 +01:00
|
|
|
}
|
|
|
|
|
2018-01-23 22:13:57 +01:00
|
|
|
void TEXTURE_RenderCenteredSpriteSheet(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Rect * srcRect, float Scale){
|
|
|
|
SDL_Rect target;
|
|
|
|
|
|
|
|
target.w = (int)roundf(((float)(srcRect->w)) * Scale);
|
|
|
|
target.h = (int)roundf(((float)(srcRect->h)) * Scale);
|
|
|
|
target.x = ((width - (target.w)) / 2);
|
|
|
|
target.y = ((height - (target.h)) / 2);
|
|
|
|
SDL_RenderCopy(renderer, texture, srcRect, &target);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TEXTURE_RenderCentered(SDL_Renderer * renderer, SDL_Texture * texture, float Scale){
|
|
|
|
int w, h;
|
|
|
|
SDL_Rect target;
|
|
|
|
|
|
|
|
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
|
|
|
|
target.w = (int)roundf(((float)w) * Scale);
|
|
|
|
target.h = (int)roundf(((float)h) * Scale);
|
|
|
|
target.x = ((width - (target.w)) / 2);
|
|
|
|
target.y = ((height - (target.h)) / 2);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, &target);
|
|
|
|
}
|
2018-01-10 15:37:55 +01:00
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
|
2018-01-23 22:13:57 +01:00
|
|
|
if (scenery->IsPaused) return;
|
|
|
|
if ((scenery->StartCountdown)-- > 0) return;
|
2018-01-22 23:06:22 +01:00
|
|
|
(scenery->Frames)++;
|
2018-01-21 15:33:09 +01:00
|
|
|
if (scenery->IsGameOver) {
|
|
|
|
BALL_ResetPosition(&(scenery->ball));
|
|
|
|
PADDLE_ResetPosition(&(scenery->paddle));
|
|
|
|
scenery->StartCountdown = 240;
|
|
|
|
scenery->IsGameOver = false;
|
|
|
|
if (--(scenery->Lives) <= 0)
|
2018-01-23 21:22:59 +01:00
|
|
|
GAME_ChangeState(GameOver);
|
2018-01-21 15:33:09 +01:00
|
|
|
else
|
|
|
|
printf("Oh oh, only %d lives left!\n", scenery->Lives);
|
|
|
|
return;
|
|
|
|
}
|
2018-01-23 22:13:57 +01:00
|
|
|
PADDLE_Update(&(scenery->paddle), scenery, keystate); // Update paddle before ball because paddle is not static!
|
2018-01-21 15:33:09 +01:00
|
|
|
BALL_Update(&(scenery->ball), scenery);
|
2018-01-15 22:01:58 +01:00
|
|
|
for (int i = 0; i < (scenery->BlockCount); i++) {
|
|
|
|
BLOCK_Update((scenery->blocks) + i);
|
2018-01-12 10:47:14 +01:00
|
|
|
}
|
2018-01-21 15:33:09 +01:00
|
|
|
} /* BREAKOUT_Update */
|
2018-01-10 15:37:55 +01:00
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
|
|
|
|
for (int i = 0; i < (scenery->BlockCount); i++) {
|
|
|
|
BLOCK_Draw(renderer, &((scenery->blocks)[i]));
|
2018-01-12 10:47:14 +01:00
|
|
|
}
|
2018-01-15 22:01:58 +01:00
|
|
|
BALL_Draw(renderer, &(scenery->ball));
|
|
|
|
PADDLE_Draw(renderer, &(scenery->paddle));
|
2018-01-23 21:22:59 +01:00
|
|
|
SCORE_DrawHUD(renderer, scenery);
|
|
|
|
BREAKOUT_DrawLivesHUD(renderer, scenery);
|
2018-01-23 22:13:57 +01:00
|
|
|
if (scenery->IsPaused) {
|
2018-01-23 22:17:45 +01:00
|
|
|
TEXTURE_RenderCentered(renderer, BREAKOUT_PausedTexture, 0.5f);
|
2018-01-23 22:13:57 +01:00
|
|
|
} else if ((scenery->StartCountdown) > 0) { // ! Render Z-Layer !
|
2018-01-23 22:17:45 +01:00
|
|
|
TEXTURE_RenderCenteredSpriteSheet(renderer, BREAKOUT_CountdownTexture, (BREAKOUT_CountdownSourceRects + (((scenery->StartCountdown) - 1) / 60)), 1.0f);
|
2018-01-23 22:13:57 +01:00
|
|
|
}
|
2018-01-23 21:22:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
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-23 22:17:45 +01:00
|
|
|
SDL_DestroyTexture(BREAKOUT_CountdownTexture);
|
|
|
|
SDL_DestroyTexture(BREAKOUT_PausedTexture);
|
2018-01-12 10:47:14 +01:00
|
|
|
free(PADDLE_MoveLeftKeys);
|
|
|
|
free(PADDLE_MoveRightKeys);
|
|
|
|
free(BALL_SourceRects);
|
|
|
|
free(PADDLE_SourceRects);
|
|
|
|
free(BLOCK_SourceRects);
|
2018-01-23 22:17:45 +01:00
|
|
|
free(BREAKOUT_CountdownSourceRects);
|
2018-01-12 10:47:14 +01:00
|
|
|
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
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
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");
|
2018-01-16 12:10:37 +01:00
|
|
|
BALL_Texture = IMG_LoadTexture(renderer, BALL_TexturePath);
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!BALL_Texture) printf("Ball texture failed to load!\n");
|
2018-01-22 23:06:22 +01:00
|
|
|
BALL_TextureCount = 9;
|
|
|
|
BALL_SourceRects = (SDL_Rect *)malloc(BALL_TextureCount * sizeof(SDL_Rect));
|
2018-01-11 18:45:00 +01:00
|
|
|
if (!BALL_SourceRects) printf("FATAL! Memory allocation failed!\n");
|
2018-01-22 23:06:22 +01:00
|
|
|
BALL_SourceRects[0] = (SDL_Rect) {.x = 1029, .y = 1029, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[1] = (SDL_Rect) {.x = 1, .y = 1, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[2] = (SDL_Rect) {.x = 1, .y = 515, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[3] = (SDL_Rect) {.x = 1, .y = 1029, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[4] = (SDL_Rect) {.x = 515, .y = 1, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[5] = (SDL_Rect) {.x = 1029, .y = 1, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[6] = (SDL_Rect) {.x = 515, .y = 515, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[7] = (SDL_Rect) {.x = 515, .y = 1029, .w = 512, .h = 512 };
|
|
|
|
BALL_SourceRects[8] = (SDL_Rect) {.x = 1029, .y = 515, .w = 512, .h = 512 };
|
2018-01-11 18:45:00 +01:00
|
|
|
printf("Ball initialized!\n");
|
|
|
|
BALL_IsInit = true;
|
|
|
|
} else printf("Ball is already initialized!\n");
|
2018-01-22 23:06:22 +01:00
|
|
|
} /* BALL_Initialize */
|
2018-01-10 23:40:17 +01:00
|
|
|
|
|
|
|
Ball BALL_CreateDefault(){
|
|
|
|
return (Ball) {
|
2018-01-25 17:05:12 +01:00
|
|
|
.Location = (Vector) {.x = (width / 2) - 15, .y = height - 131 },
|
2018-01-23 21:22:59 +01:00
|
|
|
.Momentum = (Vector) {.x = 0.0f, .y = BALL_MinSpeed },
|
|
|
|
.TargetRect = (SDL_Rect) {.x = width / 2 - 15, .y = height - 130, .w = 30, .h = 30 },
|
2018-01-21 15:33:09 +01:00
|
|
|
.Size = 15.0f,
|
2018-01-23 21:22:59 +01:00
|
|
|
.Rotation = 0,
|
|
|
|
.RotationValue = 9,
|
2018-01-15 22:01:58 +01:00
|
|
|
.TextureIndex = 0,
|
|
|
|
.Speed = 15.0f
|
2018-01-10 23:40:17 +01:00
|
|
|
}; // Objekt für die Eigenschaften des Balls
|
|
|
|
}
|
|
|
|
|
2018-01-21 15:33:09 +01:00
|
|
|
void BALL_ResetPosition(Ball * obj){
|
2018-01-25 17:05:12 +01:00
|
|
|
(obj->Location).x = width / 2 - (obj->Size);
|
|
|
|
(obj->Location).y = height - 101 - (2 * (obj->Size));
|
2018-01-21 15:33:09 +01:00
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
2018-01-22 23:06:22 +01:00
|
|
|
(obj->Momentum) = VECTOR_GetScaledDirectionalUnitVector(0.0f, (obj->Speed));
|
2018-01-21 15:33:09 +01:00
|
|
|
}
|
|
|
|
|
2018-01-23 21:22:59 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-01-10 23:40:17 +01:00
|
|
|
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-20 10:56:52 +01:00
|
|
|
if (!RECT_Collide(&(obj->TargetRect), rect)) return false;
|
2018-01-15 13:54:17 +01:00
|
|
|
// Already returned with false if square ball hitbox didnt collide with rect
|
2018-01-20 10:56:52 +01:00
|
|
|
SDL_Point ballCenter = BALL_GetCenter(obj);
|
2018-01-15 16:02:21 +01:00
|
|
|
Vector center = (Vector) {.x = ballCenter.x, .y = ballCenter.y };
|
|
|
|
Vector corner;
|
2018-01-15 13:54:17 +01:00
|
|
|
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);
|
2018-01-18 11:45:19 +01:00
|
|
|
yMid = !(top || bottom);
|
|
|
|
xMid = !(left || right);
|
2018-01-20 10:56:52 +01:00
|
|
|
if (yMid) // Hit left or right
|
2018-01-15 16:02:21 +01:00
|
|
|
(obj->Momentum).x = -(obj->Momentum).x;
|
2018-01-20 10:56:52 +01:00
|
|
|
if (xMid) // Hit bottom or top
|
2018-01-15 16:02:21 +01:00
|
|
|
(obj->Momentum).y = -(obj->Momentum).y;
|
2018-01-20 10:56:52 +01:00
|
|
|
if (xMid || yMid) return true;
|
|
|
|
// double oldAngle = fmod((double)(VECTOR_GetRotation(obj->Momentum)), 360.0f);
|
|
|
|
|
|
|
|
if (left) {
|
|
|
|
corner.x = (rect->x);
|
|
|
|
} else if (right) {
|
|
|
|
corner.x = ((rect->x) + (rect->w));
|
|
|
|
} // Other case will not appear since returned above
|
|
|
|
if (top) {
|
|
|
|
corner.y = (rect->y);
|
|
|
|
} else if (bottom) {
|
|
|
|
corner.y = ((rect->y) + (rect->h));
|
|
|
|
}
|
|
|
|
// printf("Hit corner at %.0f|%.0f!\n", corner.x, corner.y);
|
|
|
|
// printf("Ball center at %.0f|%.0f!\n", center.x, center.y);
|
|
|
|
// TODO: Reflection at lot
|
2018-01-25 17:05:12 +01:00
|
|
|
Vector cornerToMid = VECTOR_GetVectorFromTo(corner, center);
|
|
|
|
if (VECTOR_GetMagnitude(cornerToMid) > (obj->Size)) return false;
|
|
|
|
double lot = VECTOR_GetRotation(cornerToMid);
|
2018-01-21 15:33:09 +01:00
|
|
|
double inRotation = fmod(VECTOR_GetRotation(obj->Momentum) + 180.0f, 360.0f);
|
|
|
|
double outAngle = fmod(lot + (0.5 * (lot - inRotation)), 360.0f);
|
|
|
|
printf("In: %.2f | Lot: %.2f | Out: %.2f\n", inRotation, lot, outAngle);
|
|
|
|
(obj->Momentum) = VECTOR_GetScaledDirectionalUnitVector(outAngle, (obj->Speed));
|
2018-01-20 10:56:52 +01:00
|
|
|
// printf("New Magnitude = %.2f\n", VECTOR_GetMagnitude((obj->Momentum)));
|
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){
|
2018-01-15 22:01:58 +01:00
|
|
|
double paddleHalfLen = ((double)((paddle->TargetRect).w) / 2.0f);
|
2018-01-11 19:03:12 +01:00
|
|
|
double offset = (((obj->TargetRect).x) + (obj->Size)) - ((paddle->TargetRect).x + paddleHalfLen);
|
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
offset /= paddleHalfLen;
|
|
|
|
offset *= (paddle->SteeringAngle);
|
|
|
|
DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (paddle->SteeringAngle));
|
2018-01-20 10:56:52 +01:00
|
|
|
(obj->Momentum) = VECTOR_GetDirectionalUnitVector(offset);
|
2018-01-12 14:04:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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-21 14:27:53 +01:00
|
|
|
void BALL_CollideWithBorders(Ball * obj){
|
|
|
|
if ((obj->Location).y < 0.0f)
|
|
|
|
(obj->Momentum).y = -(obj->Momentum).y;
|
2018-01-23 21:22:59 +01:00
|
|
|
if ((obj->Location).x < 0.0f || (obj->Location).x > width - (2 * (obj->Size)))
|
2018-01-21 14:27:53 +01:00
|
|
|
(obj->Momentum).x = -(obj->Momentum).x;
|
|
|
|
}
|
2018-01-11 19:05:22 +01:00
|
|
|
|
2018-01-21 14:27:53 +01:00
|
|
|
void BALL_MoveAwayFromBoundaries(Ball * obj){
|
|
|
|
while (((obj->Location).y) < 0)
|
|
|
|
((obj->Location).y)++;
|
|
|
|
while (((obj->Location).x) < 0)
|
|
|
|
((obj->Location).x)++;
|
2018-01-23 21:22:59 +01:00
|
|
|
while ((((obj->Location).x) + ((obj->Size) * 2)) > width)
|
2018-01-21 14:27:53 +01:00
|
|
|
((obj->Location).x)--;
|
|
|
|
}
|
2018-01-11 14:12:30 +01:00
|
|
|
|
2018-01-21 14:27:53 +01:00
|
|
|
bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle){
|
2018-01-18 11:45:19 +01:00
|
|
|
if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) {
|
2018-01-21 14:27:53 +01:00
|
|
|
SDL_Point ballCenter = BALL_GetCenter(obj);
|
|
|
|
if (ballCenter.y > (paddle->TargetRect).y) // if the ball hits the paddle from the sides (or the bottom (?))
|
|
|
|
BALL_CollideWithRect(obj, &(paddle->TargetRect));
|
|
|
|
else
|
|
|
|
BALL_SteerMomentum(obj, paddle); // Sets it to unit vector!
|
2018-01-23 21:22:59 +01:00
|
|
|
// Following assumes that the paddle position was udated before the ball was updated
|
2018-01-12 14:04:44 +01:00
|
|
|
while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps
|
2018-01-20 10:56:52 +01:00
|
|
|
(obj->Location) = VECTOR_Add((obj->Location), (obj->Momentum));
|
2018-01-21 14:27:53 +01:00
|
|
|
BALL_MoveAwayFromBoundaries(obj);
|
2018-01-12 14:04:44 +01:00
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
|
|
|
}
|
2018-01-20 10:56:52 +01:00
|
|
|
(obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed));
|
2018-01-21 14:27:53 +01:00
|
|
|
return true;
|
2018-01-11 14:12:30 +01:00
|
|
|
}
|
2018-01-21 14:27:53 +01:00
|
|
|
return false;
|
|
|
|
} /* BALL_CollideWithPaddle */
|
|
|
|
|
2018-01-22 23:06:22 +01:00
|
|
|
void BALL_AdaptSpeedGradient(Ball * obj, int FrameCount){
|
|
|
|
if (FrameCount > BALL_AccelerationTime)
|
|
|
|
obj->Speed = BALL_MaxSpeed;
|
|
|
|
else
|
|
|
|
obj->Speed = BALL_MinSpeed + (((double)FrameCount / (double)BALL_AccelerationTime) * (BALL_MaxSpeed - BALL_MinSpeed));
|
|
|
|
}
|
|
|
|
|
2018-01-21 15:33:09 +01:00
|
|
|
void BALL_Update(Ball * obj, Scenery * scenery){
|
2018-01-22 23:06:22 +01:00
|
|
|
BALL_AdaptSpeedGradient(obj, (scenery->Frames));
|
|
|
|
(obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed));
|
2018-01-21 15:33:09 +01:00
|
|
|
Block * blocks = (scenery->blocks);
|
|
|
|
Paddle * paddle = &(scenery->paddle);
|
|
|
|
int BlockCount = scenery->BlockCount;
|
2018-01-21 14:27:53 +01:00
|
|
|
Vector oldMomentum = obj->Momentum;
|
|
|
|
Vector oldLocation = obj->Location;
|
|
|
|
|
|
|
|
(obj->Rotation) += (obj->RotationValue); // No effect on physics
|
|
|
|
(obj->Location) = VECTOR_Add((obj->Location), oldMomentum);
|
2018-01-21 19:41:29 +01:00
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
2018-01-11 14:12:30 +01:00
|
|
|
|
2018-01-21 14:27:53 +01:00
|
|
|
if (!BALL_CollideWithPaddle(obj, paddle)) // Collide with Paddle
|
2018-01-21 15:33:09 +01:00
|
|
|
for (int i = 0; i < BlockCount; i++) { // Check Collide with each block
|
2018-01-21 14:27:53 +01:00
|
|
|
if (blocks[i].HP <= 0) continue;
|
|
|
|
oldMomentum = obj->Momentum;
|
|
|
|
oldLocation = obj->Location;
|
|
|
|
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
|
|
|
|
BLOCK_DealDamage(blocks + i, 1);
|
2018-01-23 21:22:59 +01:00
|
|
|
if (blocks[i].HP <= 0) {
|
2018-01-23 11:08:15 +01:00
|
|
|
(scenery->DestroyedBlocks)++;
|
2018-01-23 21:22:59 +01:00
|
|
|
BREAKOUT_IncreaseScoreBy(scenery, (int)round((((scenery->ball).Speed) * ((scenery->ball).Speed) / 5.0f)));
|
|
|
|
}
|
2018-01-21 14:27:53 +01:00
|
|
|
(obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum));
|
|
|
|
BALL_MoveAwayFromBoundaries(obj);
|
|
|
|
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
|
|
|
|
}
|
|
|
|
}
|
2018-01-23 21:22:59 +01:00
|
|
|
if ((obj->Location).y > height) { // Collide with box boundaries
|
2018-01-21 15:33:09 +01:00
|
|
|
scenery->IsGameOver = true;
|
2018-01-23 21:22:59 +01:00
|
|
|
printf("Ball called game_over!\n");
|
|
|
|
} else BALL_CollideWithBorders(obj);
|
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");
|
2018-01-16 12:10:37 +01:00
|
|
|
PADDLE_Texture = IMG_LoadTexture(renderer, PADDLE_TexturePath);
|
2018-01-11 18:45:00 +01:00
|
|
|
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");
|
2018-01-15 20:28:47 +01:00
|
|
|
PADDLE_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 1000, .h = 100 };
|
2018-01-11 18:45:00 +01:00
|
|
|
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(){
|
|
|
|
return (Paddle) {
|
2018-01-23 22:13:57 +01:00
|
|
|
.TargetRect = (SDL_Rect) {.x = (width - PADDLE_MaxSize) / 2, .y = height - 100, .w = PADDLE_MaxSize, .h = 30 },
|
2018-01-15 22:01:58 +01:00
|
|
|
.TextureIndex = 0,
|
|
|
|
.Speed = 10,
|
2018-01-18 11:45:19 +01:00
|
|
|
.SteeringAngle = 40.0f,
|
2018-01-22 23:06:22 +01:00
|
|
|
.Mode = MouseControl
|
2018-01-11 01:06:55 +01:00
|
|
|
}; // Objekt für die Eigenschaften des Balls
|
|
|
|
}
|
|
|
|
|
2018-01-21 15:33:09 +01:00
|
|
|
void PADDLE_ResetPosition(Paddle * obj){
|
2018-01-23 21:22:59 +01:00
|
|
|
(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);
|
2018-01-21 15:33:09 +01:00
|
|
|
}
|
|
|
|
|
2018-01-11 01:06:55 +01:00
|
|
|
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){
|
|
|
|
// printf("Paddle drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x);
|
2018-01-15 20:28:47 +01:00
|
|
|
SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
|
2018-01-11 01:06:55 +01:00
|
|
|
}
|
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray){
|
2018-01-11 01:06:55 +01:00
|
|
|
for (int i = 0; i < (*keyArray); i++) {
|
|
|
|
if (keystate[keyArray[(i + 1)]]) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-01-15 22:01:58 +01:00
|
|
|
void INT_Constrain(int * variable, int min, int max){
|
|
|
|
if (*variable > max)
|
|
|
|
*variable = max;
|
|
|
|
else if (*variable < min)
|
|
|
|
*variable = min;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DOUBLE_Constrain(double * variable, double min, double max){
|
2018-01-11 01:06:55 +01:00
|
|
|
if (*variable > max)
|
|
|
|
*variable = max;
|
|
|
|
else if (*variable < min)
|
|
|
|
*variable = min;
|
|
|
|
}
|
|
|
|
|
2018-01-22 23:06:22 +01:00
|
|
|
void PADDLE_MoveSmooth(Paddle * obj){
|
|
|
|
int mouseX, paddleXMid, halfPaddle = ((obj->TargetRect).w / 2);
|
|
|
|
|
|
|
|
SDL_GetMouseState(&mouseX, NULL);
|
|
|
|
mouseX = (int)roundf((float)mouseX / XScale);
|
|
|
|
paddleXMid = halfPaddle + (obj->TargetRect.x); // Current State
|
|
|
|
(obj->TargetRect).x = paddleXMid - (int)roundf((float)(paddleXMid - mouseX) * PADDLE_SmoothFactor) - halfPaddle;
|
|
|
|
}
|
|
|
|
|
2018-01-23 22:13:57 +01:00
|
|
|
void PADDLE_AdaptSpeedGradient(Paddle * obj, int FrameCount){
|
|
|
|
if (FrameCount > PADDLE_AccelerationTime)
|
|
|
|
return;
|
|
|
|
(obj->TargetRect).w = PADDLE_MaxSize - (((double)FrameCount / (double)PADDLE_AccelerationTime) * (PADDLE_MaxSize - PADDLE_MinSize));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void PADDLE_Update(Paddle * obj, Scenery * scenery, const Uint8 * keystate){
|
|
|
|
PADDLE_AdaptSpeedGradient(obj, (scenery->Frames));
|
2018-01-22 23:06:22 +01:00
|
|
|
bool leftKeyPressed, rightKeyPressed;
|
2018-01-18 11:45:19 +01:00
|
|
|
|
|
|
|
switch (obj->Mode) {
|
|
|
|
case MouseControl:
|
2018-01-22 23:06:22 +01:00
|
|
|
PADDLE_MoveSmooth(obj);
|
2018-01-18 11:45:19 +01:00
|
|
|
break;
|
|
|
|
case KeyboardControl:
|
|
|
|
leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys);
|
|
|
|
rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys);
|
2018-01-22 23:06:22 +01:00
|
|
|
|
|
|
|
if (leftKeyPressed && (!rightKeyPressed)) {
|
|
|
|
((obj->TargetRect).x) -= (obj->Speed);
|
|
|
|
} else if ((!leftKeyPressed) && rightKeyPressed) {
|
|
|
|
((obj->TargetRect).x) += (obj->Speed);
|
|
|
|
}
|
2018-01-18 11:45:19 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Unknown Paddle Control Mode: %d!\n", obj->Mode);
|
|
|
|
break;
|
2018-01-22 23:06:22 +01:00
|
|
|
} /* switch */
|
2018-01-23 21:22:59 +01:00
|
|
|
INT_Constrain(&((obj->TargetRect).x), 0, (width - ((obj->TargetRect).w)));
|
2018-01-18 11:45:19 +01:00
|
|
|
} /* PADDLE_Update */
|
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-16 12:10:37 +01:00
|
|
|
BLOCK_Texture = IMG_LoadTexture(renderer, BLOCK_TexturePath);
|
2018-01-12 10:47:14 +01:00
|
|
|
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-15 20:28:47 +01:00
|
|
|
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 };
|
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
|
|
|
return (Block) {
|
2018-01-15 20:28:47 +01:00
|
|
|
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 100, .h = 50 },
|
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-23 21:22:59 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|