#include "ptk.h" #include "KPTK.h" #include "KSound.h" void addALineOfBricks( void ) ; void displayWall( void ) ; long brickType = 0 ; //0 1 2 3 ( pattern ) long ballColor = 0 ; struct sPreference { long score, play ; }; sPreference prefs={0,0} ; KSound *snd_down , *snd_break ,*snd_wheel , *snd_gameov ; void displayBat( void ) ; void resetBall( void ) ; void doBall( void ) ; long batX ; void doDifficulty( void ) ; long gScore, gHighscore ; bool gameOver = true ; long gameOverSteps = 0 ; void saveScores( void ) ; void loadScores( void ) ; struct sChiffre { char c ; short x1,x2 ; }; sChiffre nombres[10]= { '0' , 10 ,23, '1' , 28,35, '2' , 41,52, '3' , 55,67, '4' , 70,81, '5' , 85,96, '6' , 99,111, '7' , 115,125, '8' , 128,140, '9' , 143,155 }; void displayValue( long value , long x , long y ) ; long getCIndex( char c ) ; long getCIndex( char c ) { long i ; for ( i = 0 ; i <= 9 ; i++ ) { if ( c == nombres[i].c ) return i; } return -1 ; } struct sBall { float x1,y1 ; }; //a blue ball and a red ball sBall ball[2] = { 173,126 , 230,126 } ; float ballX, ballY , speedX,speedY ; struct sBrick { bool alive ; short type ; short x1,y1,x2,y2 , dx, dy ; long color ; float alpha ; }; sBrick wallOfBricks[12*33] ; void resetWallOfBricks( void ) ; KWindow *gameWindow ; KGraphic *surf_panel = NULL , *surf_background , *surf_sprites; void displayTinyLogo( void ) ; void displayLogo( void ) ; long difficultyTimer = 0 ; long difficultyTimerStep = 0 ; int WINAPI WinMain( HINSTANCE hInst, /*Win32 entry-point routine */ HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow ) { hInst = hInst ; hPreInst = hPreInst ; lpszCmdLine = lpszCmdLine ; nCmdShow = nCmdShow ; gameWindow = KPTK::createKWindow( K_OPENGL ) ; gameWindow->createGameWindow( 640,480,-1,true,"Nervous breakdown" ); gHighscore = 0 ; loadScores( ) ; surf_panel = KPTK::createKGraphic( ) ; surf_panel->loadPicture( KMiscTools::makeFilePath( "data\\panel.tga" ) , true, true ) ; surf_sprites = KPTK::createKGraphic( ) ; surf_sprites->loadPicture( KMiscTools::makeFilePath( "data\\sprites.tga" ) , true, true ) ; srand( KMiscTools::getMilliseconds( ) ) ; surf_background = KPTK::createKGraphic( ) ; brickType = rand( ) % 4 ; if ( rand( ) % 2 ) { surf_background->loadPicture( KMiscTools::makeFilePath( "data\\background1.tga" ) , true, true ) ; ballColor = 0 ; } else { surf_background->loadPicture( KMiscTools::makeFilePath( "data\\background2.tga" ) , true, true ) ; ballColor = 57 ; } snd_down = new KSound ; snd_down->loadSample( KMiscTools::makeFilePath( "data\\down.ogg" ) ); snd_break = new KSound ; snd_break->loadSample( KMiscTools::makeFilePath( "data\\break.ogg" ) ); snd_break->setVolume( 50 ) ; snd_wheel = new KSound ; snd_wheel->loadSample( KMiscTools::makeFilePath( "data\\wall.ogg" ) ); snd_gameov = new KSound ; snd_gameov->loadSample( KMiscTools::makeFilePath( "data\\gameover.ogg" ) ); resetWallOfBricks( ) ; resetBall( ) ; gScore = 0 ; gameOver = true ; gameOverSteps = 0 ; //main loop do { gameWindow->setDefaultWorldView( ) ; surf_background->blitAlphaRect( 0,0,surf_background->getWidth(),surf_background->getHeight(),20,23 ) ; //display the sprites behind the panel displayWall( ) ; doBall( ) ; displayBat( ) ; surf_panel->blitAlphaRect( 0,0,640,480,0,0 ) ; doDifficulty( ) ; displayValue( gScore , 635,333 ) ; displayValue( gHighscore , 635,259 ) ; displayLogo( ) ; displayTinyLogo( ) ; gameWindow->flipBackBuffer( ) ; }while( gameWindow->isQuit() == false ) ; saveScores( ) ; delete snd_gameov ; delete snd_wheel ; delete snd_break ; delete snd_down ; delete surf_sprites ; delete surf_panel ; delete surf_background ; delete gameWindow ; return 0 ; } //the big logo void displayLogo( void ) { static float fade = 0 ; long x , y ; if ( gameOver == false && fade <= 0 ) { return ; } if ( gameOver == true ) { //first of all, scroll down for ( y = 0 ; y <=31 ; y++ ) { for ( x = 0 ; x < 12 ; x++ ) { if ( y == 31 ) wallOfBricks[x+y*12].alive= false ; memcpy( &wallOfBricks[x+y*12] , &wallOfBricks[x+(y+1)*12] , sizeof( sBrick ) ) ; } } fade+=0.05f; if ( fade > 1) fade = 1 ; } else { fade-=0.1f; if ( fade < 0) fade = 0 ; } surf_sprites->blitAlphaRectFx( 0,174,289,262,130,150 ,0,1,fade) ; if ( KInput::isPressed( K_VK_ESCAPE )== ISDOWN ) { gameWindow->terminate( ) ; } if ( KInput::isPressed( K_VK_SPACE )== ISDOWN || KInput::getLeftButtonState( ) ) { if ( gameOver == true && snd_gameov->isPlaying() == false ) { KInput::waitForKeyRelease( K_VK_SPACE ) ; resetWallOfBricks( ) ; resetBall( ) ; gameOver = false ; gScore = 0 ; } } } void displayBat( void ) { long x,y ; x = KInput::getMouseX( ) ; y = KInput::getMouseY( ) ; if ( x < 17 ) x = 17 ; if ( x > 430 ) x = 430 ; batX = x ; surf_sprites->blitAlphaRect( 165,3,239,29 , x, 440 ) ; } void displayTinyLogo( void ) { // surf_sprites->blitAlphaRect( 0,264,141,310,502,50 ) ; } //wall of bricks void resetWallOfBricks( void ) { long x , y ; difficultyTimer = 0 ; //every 500 add a line difficultyTimerStep = 500 ; for ( y = 0 ; y < 32 ; y++ ) { for ( x = 0 ; x < 12 ; x++ ) { wallOfBricks[x+y*12].alive = false ; } } addALineOfBricks( ) ; addALineOfBricks( ) ; addALineOfBricks( ) ; addALineOfBricks( ) ; addALineOfBricks( ) ; } //resets the ball void resetBall( void ) { ballX = 280 ; ballY = 240 ; speedX = (rand() % 100) -50 ; speedX /= 20 ; speedY = -2 ; } void doDifficulty( void ) { float ratio ; ratio = (float)difficultyTimer / (float)difficultyTimerStep ; surf_sprites->drawRect( 549,409,549+ratio*(float)(634-549),424,1,0.8f,0.8f,0.5f ) ; //surf_sprites->drawRect( 549,407,549+ratio*(float)(634-549),425,1,1,1,0.8f ) ; } void doBall( void ) { sBall *ballPtr ; if ( gameOver == true ) return ; ballPtr = &ball[0] ; ballX += speedX ; if ( ballX <= 18 ) { speedX *= -1 ; snd_wheel->playSample(); ballX = 18 ; } if ( ballX >= 487 ) { speedX *= -1 ; snd_wheel->playSample(); ballX = 487 ; } ballY += speedY ; if ( ballY <= 18 ) { ballY = 18 ; speedY *= -1 ; snd_wheel->playSample(); } //batX //dead if ( ballY >= 433 && ballY <= 450 && (ballX+8) >= batX && ballX <=(batX+74) ) { snd_wheel->playSample(); speedY *= -1.05f ; //patch the weird bug if ( speedY > 0 ) speedY *=-1 ; speedX = ((ballX+8)-batX)-(74/2) ; speedX /= 37.0f ; speedX *= 5.0f ; if ( speedY > 7 ) speedY = 7; if ( speedX > 5 ) speedX = 5; if ( speedY < -7 ) speedY = -7; if ( speedX < -5 ) speedX = -5; } else { if ( ballY > 450 ) { gameOver = true ; snd_gameov->playSample( ) ; } } surf_sprites->blitAlphaRect( 205+ballColor,132,222+ballColor,146 , ballX , ballY ) ; } void displayWall( void ) { long x,y ; sBrick *brickPtr ; float bx1, by1 ; if ( gameOver == false ) { difficultyTimer++ ; if ( difficultyTimer > difficultyTimerStep ) { difficultyTimerStep-=10 ; if ( difficultyTimerStep <= 30 )difficultyTimerStep = 30 ; difficultyTimer = 0 ; addALineOfBricks( ) ; } } bx1 = (ballX+8)+speedX ; by1 = (ballY+7)+speedY ; //surf_sprites->drawRect( bx1,by1,bx2,by2 ,0,1,0,0.5f ) ; //first of all, scroll down for ( y = 0 ; y <32 ; y++ ) { for ( x = 0 ; x < 12 ; x++ ) { brickPtr = &wallOfBricks[x+y*12] ; if ( brickPtr->alive == false ) continue ; if ( y == 31 && gameOver == false ) { gameOver = true ; } brickPtr->dx = 20+x*40 ; brickPtr->dy = 20+y*15 ; surf_sprites->blitAlphaRect( brickPtr->x1, brickPtr->y1, brickPtr->x2 , brickPtr->y2 , brickPtr->dx , brickPtr->dy ) ; if ( bx1 < brickPtr->dx ) continue ; if ( bx1 > (brickPtr->dx+40) ) continue ; if ( by1 < brickPtr->dy ) continue ; if ( by1 > (brickPtr->dy+15) ) continue ; brickPtr->alive = false ; speedY *=-1 ; snd_break->playSample( ) ; gScore++ ; } } if ( gScore > gHighscore ) { gHighscore = gScore ; } } void displayValue( long value , long x , long y ) { char buffer[50] ; long i , l , w , idx; sprintf( buffer , "%d" , value ) ; l = strlen( buffer ) ; //calculates the width w = 0 ; for ( i = 0 ; i < l ; i++ ) { idx = getCIndex( buffer[i] ) ; w+= (nombres[idx].x2-nombres[idx].x1) ; } x-=w ; for ( i = 0 ; i < l ; i++ ) { idx = getCIndex( buffer[i] ) ; surf_sprites->blitAlphaRect( nombres[idx].x1 , 154 , nombres[idx].x2 , 171, x , y ) ; x += (nombres[idx].x2-nombres[idx].x1) ; } } void addALineOfBricks( void ) { long x,y ; sBrick *brickPtr ; long color ; if ( snd_down->isPlaying() == false ) { snd_down->playSample( ) ; } //first of all, scroll down for ( y = 32 ; y >= 1 ; y-- ) { for ( x = 0 ; x < 12 ; x++ ) { memcpy( &wallOfBricks[x+y*12] , &wallOfBricks[x+(y-1)*12] , sizeof( sBrick ) ) ; } } //add a line in 0 color = rand( ) % 9 ; for ( x = 0 ; x < 12 ; x++ ) { brickPtr = &wallOfBricks[x] ; brickPtr->alive = true ; brickPtr->x1 = 40*brickType ; brickPtr->x2 = 41+40*brickType ; brickPtr->y1 = 15*color ; brickPtr->y2 = 15+15*color ; brickPtr->alpha = 0 ; } } void loadScores( void ) { FILE *f ; f= fopen( KMiscTools::makeFilePath( "scores.raw" ) , "rb" ) ; if ( f == NULL ) { prefs.score = 0 ; prefs.play = 0 ; return ; } if ( prefs.play < 0 ) prefs.play = 0 ; if ( prefs.play > 10 ) prefs.play = 10 ; fread( &prefs, 1 , sizeof ( sPreference ) , f ) ; gHighscore = prefs.score ; fclose( f ); } void saveScores( void ) { FILE *f ; prefs.play++ ; f= fopen( KMiscTools::makeFilePath( "scores.raw" ) , "wb" ) ; if ( f == NULL ) return ; prefs.score = gHighscore ; if ( prefs.play < 0 ) prefs.play = 0 ; if ( prefs.play > 10 ) prefs.play = 10 ; fwrite( &prefs, 1 , sizeof ( sPreference ) , f ) ; fclose( f ); }