2018-01-09 13:22:10 +01:00
# include <stdio.h>
2018-01-10 23:40:17 +01:00
# include <stdlib.h>
2018-01-09 13:22:10 +01:00
# include <stdbool.h>
# include <math.h>
2018-01-27 11:37:39 +01:00
# include <time.h>
2018-01-09 13:22:10 +01:00
# include <SDL2/SDL.h>
# include <SDL2/SDL_image.h>
2018-01-27 11:37:39 +01:00
# include <SDL2/SDL_mixer.h>
2018-01-09 13:22:10 +01:00
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"
2018-01-27 15:51:36 +01:00
# define BREAKOUT_CountdownTexturePath "assets / images / text.png"
# define BREAKOUT_PausedTexturePath "assets / images / paused.png"
2018-01-27 18:48:45 +01:00
# define BREAKOUT_IngameSoundPath "assets / sounds / ingame_music.wav"
2018-01-29 19:10:08 +01:00
# define BREAKOUT_DeathSoundPath "assets / sounds / death.wav"
# define BREAKOUT_HitSoundPath1 "assets / sounds / hit1.wav"
# define BREAKOUT_HitSoundPath2 "assets / sounds / hit2.wav"
# define BREAKOUT_HitSoundPath3 "assets / sounds / hit3.wav"
# define BREAKOUT_HitSoundPath4 "assets / sounds / hit4.wav"
# define BREAKOUT_HitSoundPath5 "assets / sounds / hit5.wav"
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-26 10:40:19 +01:00
# define BREAKOUT_PushIntervale 1800
2018-01-27 18:48:45 +01:00
# define BREAKOUT_FadeTime 1000
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-26 10:40:19 +01:00
float BLOCK_SmoothFactor = 0.05f ;
float BREAKOUT_LifePenalty = 0.75f ;
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-27 18:48:45 +01:00
Mix_Chunk * BREAKOUT_DeathSound ;
2018-01-29 19:10:08 +01:00
Mix_Chunk * * BREAKOUT_HitSound ;
2018-01-27 18:48:45 +01:00
Mix_Music * BREAKOUT_IngameMusic ;
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-27 15:51:36 +01:00
BREAKOUT_CountdownTexture = IMG_LoadTexture ( renderer , BREAKOUT_CountdownTexturePath ) ;
2018-01-23 22:17:45 +01:00
if ( ! BREAKOUT_CountdownTexture ) printf ( " Countdown texture failed to load! \n " ) ;
2018-01-27 15:51:36 +01:00
BREAKOUT_PausedTexture = IMG_LoadTexture ( renderer , BREAKOUT_PausedTexturePath ) ;
2018-01-23 22:17:45 +01:00
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-29 19:10:08 +01:00
BREAKOUT_HitSound = malloc ( 5 * sizeof ( Mix_Chunk * ) ) ;
BREAKOUT_HitSound [ 0 ] = Mix_LoadWAV ( BREAKOUT_HitSoundPath1 ) ;
BREAKOUT_HitSound [ 1 ] = Mix_LoadWAV ( BREAKOUT_HitSoundPath2 ) ;
BREAKOUT_HitSound [ 2 ] = Mix_LoadWAV ( BREAKOUT_HitSoundPath3 ) ;
BREAKOUT_HitSound [ 3 ] = Mix_LoadWAV ( BREAKOUT_HitSoundPath4 ) ;
BREAKOUT_HitSound [ 4 ] = Mix_LoadWAV ( BREAKOUT_HitSoundPath5 ) ;
2018-01-27 18:48:45 +01:00
BREAKOUT_DeathSound = Mix_LoadWAV ( BREAKOUT_DeathSoundPath ) ;
BREAKOUT_IngameMusic = Mix_LoadMUS ( BREAKOUT_IngameSoundPath ) ;
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-27 18:48:45 +01:00
void BREAKOUT_StartMusic ( ) {
printf ( " Attempting to start game music... \n " ) ;
if ( ! Mix_PlayingMusic ( ) )
Mix_FadeInMusic ( BREAKOUT_IngameMusic , - 1 , BREAKOUT_FadeTime ) ;
else printf ( " Game music is already playing! \n " ) ;
}
void BREAKOUT_PauseMusic ( ) {
printf ( " Attempting to pause game music... \n " ) ;
if ( Mix_PlayingMusic ( ) )
Mix_HaltMusic ( ) ;
// Mix_FadeOutMusic(BREAKOUT_FadeTime);
else printf ( " There is no game music to be paused! \n " ) ;
}
// Toggle Game pause, not the music!
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 ;
2018-01-26 10:40:19 +01:00
scenery . TopLeftBlockColor = 0 ;
2018-01-21 15:33:09 +01:00
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-26 10:40:19 +01:00
scenery . YBlocks = 9 ;
scenery . XBlocks = 15 ;
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-26 10:40:19 +01:00
for ( int y = 0 ; y < scenery . YBlocks ; y + + ) {
index = ( scenery . XBlocks ) * y ;
for ( int x = 0 ; x < scenery . XBlocks ; 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-26 10:40:19 +01:00
scenery . blocks [ x + index ] . DestYValue = ( ( 64 * y ) + 1 ) ;
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-26 10:40:19 +01:00
void BREAKOUT_PushNewRow ( Scenery * scenery ) {
printf ( " Pushing new line... \n " ) ;
( scenery - > TopLeftBlockColor ) - - ;
// Rotate through textures
if ( ( scenery - > TopLeftBlockColor ) < 0 ) ( scenery - > TopLeftBlockColor ) = ( BLOCK_TextureCount - 1 ) ;
else if ( ( scenery - > TopLeftBlockColor ) > = 24 ) ( scenery - > TopLeftBlockColor ) = 0 ;
int oldBlockCount = ( scenery - > BlockCount ) ;
( scenery - > BlockCount ) + = ( scenery - > XBlocks ) ;
( scenery - > YBlocks ) + + ;
scenery - > blocks = realloc ( ( scenery - > blocks ) , ( scenery - > BlockCount ) * sizeof ( Block ) ) ;
for ( size_t i = 0 ; i < oldBlockCount ; i + + ) {
( scenery - > blocks ) [ i ] . DestYValue + = 64 ;
}
for ( size_t x = 0 ; x < ( scenery - > XBlocks ) ; x + + ) {
( scenery - > blocks ) [ x + oldBlockCount ] = BLOCK_CreateDefault ( ) ;
2018-01-26 23:50:05 +01:00
( scenery - > blocks ) [ x + oldBlockCount ] . TargetRect = ( SDL_Rect ) { . x = ( ( 128 * x ) + 2 ) , . y = - 63 , . w = 124 , . h = 62 } ;
2018-01-26 10:40:19 +01:00
( scenery - > blocks ) [ x + oldBlockCount ] . TextureIndex = ( ( ( scenery - > TopLeftBlockColor ) + x ) % BLOCK_TextureCount ) ;
( scenery - > blocks ) [ x + oldBlockCount ] . DestYValue = 1 ;
}
printf ( " New line was pushed! \n " ) ;
} /* BREAKOUT_PushNewRow */
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-26 10:40:19 +01:00
else {
// Reduce score when there is a life left
2018-01-29 23:47:18 +01:00
// scenery->Score = (int)roundf((float)(scenery->Score) * BREAKOUT_LifePenalty);
2018-01-21 15:33:09 +01:00
printf ( " Oh oh, only %d lives left! \n " , scenery - > Lives ) ;
2018-01-26 10:40:19 +01:00
}
2018-01-21 15:33:09 +01:00
return ;
}
2018-01-26 10:40:19 +01:00
if ( ( scenery - > Frames ) % BREAKOUT_PushIntervale = = 0 ) {
BREAKOUT_PushNewRow ( scenery ) ;
}
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-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-26 10:40:19 +01:00
BALL_Update ( & ( scenery - > ball ) , scenery ) ;
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-27 18:48:45 +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-29 19:10:08 +01:00
for ( int i = 0 ; i < 5 ; i + + ) {
Mix_FreeChunk ( BREAKOUT_HitSound [ i ] ) ;
}
free ( BREAKOUT_HitSound ) ;
2018-01-27 18:48:45 +01:00
Mix_FreeChunk ( BREAKOUT_DeathSound ) ;
Mix_FreeMusic ( BREAKOUT_IngameMusic ) ;
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-29 19:10:08 +01:00
} /* BREAKOUT_DEINITIALIZE */
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-29 23:47:18 +01:00
Vector unitMomentum = VECTOR_ChangeScaleTo ( ( obj - > Momentum ) , 1.0f ) ;
Vector center = BALL_GetCenter ( obj ) ;
2018-01-15 16:02:21 +01:00
Vector corner ;
2018-01-15 13:54:17 +01:00
bool left , right , top , bottom , yMid = false , xMid = false ;
2018-01-29 23:47:18 +01:00
left = ( center . x ) < ( rect - > x ) ;
right = ( center . x ) > ( rect - > x ) + ( rect - > w ) ;
top = ( center . y ) < ( rect - > y ) ;
bottom = ( center . y ) > ( rect - > y ) + ( rect - > h ) ;
2018-01-18 11:45:19 +01:00
yMid = ! ( top | | bottom ) ;
xMid = ! ( left | | right ) ;
2018-01-29 23:47:18 +01:00
// Move away from hitbox from where you came from when stuck in the middle of the block at high speeds
while ( yMid & & xMid ) {
( obj - > Location ) = VECTOR_Subtract ( ( obj - > Location ) , unitMomentum ) ;
center = BALL_GetCenter ( obj ) ;
left = ( center . x ) < ( rect - > x ) ;
right = ( center . x ) > ( rect - > x ) + ( rect - > w ) ;
top = ( center . y ) < ( rect - > y ) ;
bottom = ( center . y ) > ( rect - > y ) + ( rect - > h ) ;
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 ) ) ;
}
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-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 ) ;
}
2018-01-29 23:47:18 +01:00
Vector BALL_GetCenter ( Ball * obj ) {
return ( Vector ) { . x = ( ( obj - > Location ) . x ) + ( obj - > Size ) , . y = ( ( obj - > Location ) . 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-29 23:47:18 +01:00
Vector ballCenter = BALL_GetCenter ( obj ) ;
2018-02-01 11:41:12 +01:00
if ( ( ballCenter . x ) > ( ( paddle - > TargetRect ) . x ) | | ( ballCenter . x ) < ( ( paddle - > TargetRect ) . x + ( paddle - > TargetRect ) . w ) ) // if the ball hits the paddle from the sides (or the bottom (?))
BALL_SteerMomentum ( obj , paddle ) ; // Sets it to unit vector!
2018-01-21 14:27:53 +01:00
else
2018-02-01 11:41:12 +01:00
BALL_CollideWithRect ( obj , & ( paddle - > TargetRect ) ) ;
// 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-29 19:10:08 +01:00
BALL_PlayCollisionSound ( ) ;
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-29 19:10:08 +01:00
void BALL_PlayCollisionSound ( ) {
int sound ;
Mix_PlayChannel ( - 1 , BREAKOUT_HitSound [ ( sound = ( rand ( ) % 5 ) ) ] , 0 ) ;
printf ( " Collision sound %d played... \n " , sound ) ;
}
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 ) ) ) {
2018-01-29 19:10:08 +01:00
BALL_PlayCollisionSound ( ) ;
2018-01-21 14:27:53 +01:00
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-02-01 17:55:15 +01:00
BREAKOUT_IncreaseScoreBy ( scenery , ( int ) round ( ( 15.0f / ( ( scenery - > ball ) . Size ) ) * ( ( ( scenery - > ball ) . Speed ) * ( ( scenery - > ball ) . Speed ) / 5.0f ) ) ) ;
2018-01-23 21:22:59 +01:00
}
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-27 18:48:45 +01:00
Mix_PlayChannel ( - 1 , BREAKOUT_DeathSound , 0 ) ;
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-26 23:50:05 +01:00
void PADDLE_MoveAuto ( Scenery * scenery ) {
int paddleXMid , halfPaddle = ( ( ( scenery - > paddle ) . TargetRect ) . w / 2 ) ;
paddleXMid = halfPaddle + ( ( scenery - > paddle ) . TargetRect . x ) ; // Current State
( ( scenery - > paddle ) . TargetRect ) . x = paddleXMid - ( int ) roundf ( ( float ) ( paddleXMid - ( ( ( scenery - > ball ) . Location ) . x + ( rand ( ) % 30 ) + ( ( scenery - > ball ) . Size ) ) ) * 0.2f ) - 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 ;
2018-01-26 23:50:05 +01:00
case Automatic :
PADDLE_MoveAuto ( scenery ) ;
break ;
2018-01-18 11:45:19 +01:00
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-27 18:48:45 +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 ) ,
2018-01-26 10:40:19 +01:00
. HP = 1 ,
. DestYValue = 0
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-26 10:40:19 +01:00
void BLOCK_MoveSmooth ( Block * obj ) {
( ( obj - > TargetRect ) . y ) - = ( int ) roundf ( ( float ) ( ( ( obj - > TargetRect ) . y ) - ( obj - > DestYValue ) ) * BLOCK_SmoothFactor ) ;
}
2018-01-12 10:47:14 +01:00
void BLOCK_Update ( Block * obj ) {
2018-01-26 10:40:19 +01:00
BLOCK_MoveSmooth ( obj ) ;
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
}