view lamertetris/sources/game.C @ 9:cdadbf30a821

arkanoid-0.7-1_PKG
author prymula <prymula76@outlook.com>
date Sun, 04 Feb 2024 15:47:05 +0100
parents 2787f5e749ae
children
line wrap: on
line source

/* 
 * LamerTetris 2
 * author: prymula
 * date: 10-VI-2023
 * licence: Public Domain
 * tool: Geany
 * Program based on:
 * -This source code copyrighted by Lazy Foo' Productions (2004-2020)
 * and may not be redistributed without written permission.
 * -Andrew Lim Chong Liang https://github.com/andrew-lim/sdl2-boilerplate
 */


#include "game.h"

Game::Game()
:running(0), window(NULL), renderer(NULL) {
	screenSurface = SDL_CreateRGBSurface(0,400,600,32,0,0,0,0);
}

Game::~Game() {
	//delete actual_ball;
	//delete octagon;
    this->stop();
}

void Game::start() {

    if (SDL_Init(SDL_INIT_EVERYTHING)) {
        return ;
    }
    // Ten sposób tworzenia okna i renderu gwarantuje że duszki nie będą przerywać
    window = SDL_CreateWindow( "Lamer Tetris", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DISPLAY_WIDTH, DISPLAY_HEIGHT, SDL_WINDOW_SHOWN );
	if( window == NULL )
	{
		printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
		return;
	}
    renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
	if( renderer == NULL )
	{
		printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
		return;
	}
	if(TTF_Init()==-1) {
		printf("TTF_Init: %s\n", TTF_GetError());
		return;
	}
	
	if( !loadWallpaper()){
		printf( "Failed to load media!\n" );
		exit(1);
	}
	
	if(hiscore.file_exist())
		hi_score = hiscore.load_hiscore();
	else hi_score = 0;
		
    this->running = 1 ;
}

void Game::draw(SDL_Rect *srcField, SDL_Rect *positionField, bool end) {

	SDL_Rect destrect; //, srcrect;
	SDL_Surface * scoreSurface;
	
	//destrect = set_rect(0, 0, background->w, background->h);
	//srcrect = set_rect(0, 0, background->w, background->h);
	SDL_BlitSurface(background, NULL, screenSurface, NULL);
	
	// dla elementu wysuwanego
	if(srcField->y>0 && !end){
		SDL_BlitSurface( field.get(figure,n_element), srcField, screenSurface, positionField );
	} else  // dla elementu wysunietego
		SDL_BlitSurface( field.get(figure,n_element), srcField, screenSurface, positionField );	


	szlam.draw();
	SDL_BlitSurface( szlam.get(), NULL, screenSurface, NULL );	

	// punkty na tapete
	scoreSurface = scoreTxt.loadFromRenderedText(std::to_string(score) ,{0xff, 0xff, 0xff}, fontScore);
	destrect = set_rect(10, 3, background->w, background->h);
	SDL_BlitSurface( scoreSurface, NULL, screenSurface, &destrect );	
	SDL_FreeSurface( scoreSurface );

	// najlepszy wynik na tapete
	scoreSurface = scoreTxt.loadFromRenderedText(std::to_string(hi_score) ,{0xe1, 0x06, 0x40}, fontScore);
	destrect = set_rect(300, 3, background->w, background->h);
	SDL_BlitSurface( scoreSurface, NULL, screenSurface, &destrect );	
	SDL_FreeSurface( scoreSurface );


	
	texture = SDL_CreateTextureFromSurface( renderer, screenSurface);
	if( texture == NULL )
	{
		printf( "Unable to create texture ! SDL Error: %s\n", SDL_GetError() );
		exit(1);
	}
	destrect = set_rect(0, 0, background->w, background->h);
	SDL_RenderCopy(renderer, texture, NULL, &destrect);

    SDL_RenderPresent(renderer);
    SDL_DestroyTexture(texture);

}

void Game::stop() {
    if (NULL != renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = NULL;
    }
    if (NULL != window) {
        SDL_DestroyWindow(window);
        window = NULL;
    }
    SDL_Quit() ;
}

void Game::fillRect(SDL_Rect* rc, int r, int g, int b ) {
    SDL_SetRenderDrawColor(renderer, r, g, b, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(renderer, rc);
}

void Game::fpsChanged( int fps ) {
    char szFps[ 128 ] ;
    sprintf( szFps, "%s: %d FPS", "Lamer Tetris", fps );
    SDL_SetWindowTitle(window, szFps);
}
/*
void Game::onQuit() {
	
    running = 0 ;
}
*/
void Game::up_direction() {
	tmp_element=n_element;
	if(tmp_element<3) {
		tmp_element+=1;
	} else tmp_element=0;
					
	if(!szlam.collisionRotate(field.get(figure,tmp_element), tmp_element, 
		figure, positionField.x, positionField.y, field.getColor(figure)))
		if (field.checkEdgeRotate(field.get(figure, tmp_element), positionField.x)) {
			if(n_element<3) {
				n_element+=1;
			} else n_element=0;
		}
}

void Game::left_direction() {
	left=0;
	if(!szlam.collisionLeft(field.get(figure,n_element), n_element, 
		figure, positionField.x, positionField.y, field.getColor(figure)))
		if (field.checkEdgeLeft(field.get(figure, n_element), positionField.x))
			positionField.x-=20;
}
void Game::right_direction() {
	if(!szlam.collisionRight(field.get(figure,n_element), n_element, 
		figure, positionField.x, positionField.y, field.getColor(figure)))
		if (field.checkEdgeRight(field.get(figure, n_element), positionField.x))
			positionField.x+=20;
}
void Game::run() {
    int past = SDL_GetTicks();
    int now = past, pastFps = past ;
    int fps = 0;
	bool end = SDL_FALSE;
	int rate = 1;
	SDL_Joystick *joystick;
    joystick = SDL_JoystickOpen(0);
	score = 0;
	
	positionField = set_rect(200, 0, 80, 0);
	srcField = set_rect(0, 0, 80, 80);
	
    printf("Name: %s\n", SDL_JoystickNameForIndex(0));

    SDL_Event event ;
    while ( running ) {
        int timeElapsed = 0 ;
        if (SDL_PollEvent(&event)) {

            switch (event.type) {
                case SDL_QUIT:
					if (score > hi_score) 
					{
						hi_score=score;
						hiscore.save_hiscore(hi_score);
					}
					
					running = 0 ;
                break;
                case SDL_KEYDOWN:
					if (event.key.keysym.sym==SDLK_ESCAPE)
						running = 0;
						
					if (event.key.keysym.sym==SDLK_SPACE) {
						if (end) {
							szlam.reset();
							end = false;
							score = 0;
							figure = rand()%7;
						}
					}
					if (event.key.keysym.sym==SDLK_UP) {
						up_direction();
					}
					if (event.key.keysym.sym==SDLK_LEFT) {	
						left_direction();		
					}
					if (event.key.keysym.sym==SDLK_RIGHT) {
						right_direction();		
						
					}
					if (event.key.keysym.sym==SDLK_DOWN) {
						rate=5;
					}
					if (event.key.keysym.sym==SDLK_f) {	
						if(figure<NFIGURE-1) {
							figure+=1;
						} else figure=0;
					}
					break;
				case SDL_JOYBUTTONDOWN:
					printf("button: %i\n", event.jbutton.button);
					// góa
					if (event.jbutton.button == 3) {
						up_direction();
					}
					// lewo
					if (event.jbutton.button == 2) {
						left_direction();
					}
					// prawo
					if (event.jbutton.button == 1) {
						right_direction();		
					}
					// dół
					if (event.jbutton.button == 0) {
						rate = 5;	
					}
					// back
					if (event.jbutton.button == 6) {
						if (score > hi_score) 
						{
							hi_score=score;
							hiscore.save_hiscore(hi_score);
						}
						running = 0;
					}
					// lewy przedni
					if (event.jbutton.button == 4) {
						if(figure>0) {
							figure-=1;
						} else figure=NFIGURE-1;
					}
					// prawy przedni
					if (event.jbutton.button == 5) {
						if(figure<NFIGURE-1) {
							figure+=1;
						} else figure=0;
					}
					break;
				case SDL_JOYAXISMOTION:
					printf("axis: %i %i\n", event.jaxis.axis, event.jaxis.value);
					break;
                case SDL_KEYUP:
                case SDL_MOUSEBUTTONDOWN:
                case SDL_MOUSEBUTTONUP:
                case SDL_MOUSEMOTION:
                    break ;
            }
		}

		timeElapsed = (now=SDL_GetTicks()) - past ;
        if ( timeElapsed >= UPDATE_INTERVAL  ) {
           past = now ;

			if (szlam.addBottom(field.get(figure,n_element), figure, n_element,
				field.getColor(figure),positionField.x,positionField.y )){
					printf ("Dodaje na dole\n");
					positionField.y=0;
        			positionField.x=(rand()%6-1)*80;
					positionField.h=0;
					srcField.y=80;
					srcField.h=0;
      				figure = rand()%7;
          			rate=1;
          		
					score++;
          		// sprawdza czy równa powierzchnia
          		int heightLevel=0, evenLevel = szlam.evenSurface(&heightLevel);
          		if (evenLevel) {
					szlam.cutSurface(evenLevel, heightLevel);
					score += 15*evenLevel;
				} 
				//bottom = 1;

			}
            else if (szlam.collisionBottom(field.get(figure,n_element), n_element, 
				figure, positionField.x, positionField.y, field.getColor(figure))){
				if (!end){
					printf ("góra\n");
                	positionField.y=0;
        			positionField.x=(rand()%6-1)*80;
					positionField.h=0;
					srcField.y=80;
					srcField.h=0;
      				figure = rand()%7;
          			rate=1;
          			score++;

          			// sprawdza czy równa powierzchnia
					int heightLevel=0, evenLevel = szlam.evenSurface(&heightLevel);
          			if (evenLevel) {
						printf ("b1\n");
						szlam.cutSurface(evenLevel, heightLevel);
						score += 15*evenLevel;
        			}
				}
				
			}	
		
			if (szlam.highFull()) end = SDL_TRUE;
		
			draw(&srcField, &positionField, end);  // figure -- element
			if(srcField.y>0 && !end){
				srcField.y--; srcField.h++;
			}
			else if (srcField.y==0 && !end) {
				positionField.y+=rate;     
				++fps ;
			}
			if ( now - pastFps >= 1000 ) {
				pastFps = now ;
				fpsChanged( fps );
				fps = 0 ;
			}
        }
        // sleep?
        SDL_Delay( 1 );
    }
    //SDL_FreeSurface(background);
	//SDL_FreeSurface(screenSurface);
	SDL_JoystickClose(joystick);
	SDL_DestroyTexture(texture);
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	SDL_Quit();

}

bool Game::loadFromFile( std::string path, SDL_Renderer * renderer)
{
	
	SDL_Texture* backgroundTexture = NULL;
	if (background) SDL_FreeSurface(background);
	background = SDL_LoadBMP(path.c_str());

	if( background == NULL )
	{
		printf( "Unable to load image %s!\n", path.c_str() );
	}
	else
	{
		//Color key image
		//SDL_SetColorKey( background, SDL_TRUE, SDL_MapRGB( background>format, 0, 0xFF, 0xFF ) );
        backgroundTexture = SDL_CreateTextureFromSurface( renderer, background );
        
		if( backgroundTexture == NULL )
		{
			printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
		}
 	}
	return backgroundTexture != NULL;
}

bool Game::loadWallpaper()
{
#define SIZEFONT 35
	
#if WINDOWS
#define FONT "./assets/SpicyRice.ttf"
#define BACK "./assets/wallpaper.bmp"
#elif LINUX
//#define FONT "./assets/SpicyRice.ttf"
//#define BACK "./assets/wallpaper.bmp"
#define FONT "/usr/share/lamertetris/SpicyRice.ttf"
#define BACK "/usr/share/lamertetris/img/wallpaper.bmp"
#endif
	//Loading success flag
	bool success = true;
	for (int i = 0; i<1; i++) {
		//Load dot texture
		if (!loadFromFile( BACK, renderer))
		{
			printf( "Failed to load dot texture!\n" );
			success = false;
		}
	}
	
	if((gFont = TTF_OpenFont(FONT, SIZEFONT)) == NULL) {
       printf("TTF_OpenFont: %s\n", TTF_GetError());
       exit(1);
	}
	if((fontScore = TTF_OpenFont(FONT, SIZEFONT)) == NULL) {
       printf("TTF_OpenFont: %s\n", TTF_GetError());
       exit(1);
	}
	
	return success;
}

SDL_Rect set_rect(int x, int y, int w, int h)
{
	SDL_Rect rect;
	rect.x = x;
	rect.y = y;
	rect.w = w;
	rect.h = h;
	return rect;
}

int main(int argc, char** argv){
	
    Game game;
    game.start();
	game.run();
    return 0;
}