#include "game.h" GameState::GameState(Renderer* renderer, float scale_): closed_ {false}, paused_ {false}, timeAdvance_ {1000}, timeCounterAdvance_ {1000}, timeLevelUp_ {20000}, renderer_ {renderer}, piece_ {Piece::PieceType::LINE, 4}, blockTexture_ {renderer_->renderer()} { renderer->setScale(scale_, scale_); blockTexture_.loadFromFile("assets/block.png"); for(int i=0; i < GRID_WIDTH; i++){ for(int j=0; j < GRID_HEIGHT; j++){ grid[j][i] = 0; } } xdirection_ = Direction::NONE; yspeed_ = 1; } void GameState::close(){ closed_ = true; } void GameState::pause(){ paused_ = true; } void GameState::resume(){ paused_ = false; } bool GameState::isPaused(){ return paused_; } bool GameState::isClosed(){ return closed_; } void GameState::update( unsigned int dt ){ timeCounterAdvance_ -= dt * yspeed_; if ( timeCounterAdvance_ <= 0 ){ timeCounterAdvance_ = timeAdvance_; Piece tmp = piece_; tmp.advance(); Point* p; // Check if there's space to move forward tmp.initIterator(); while ( p = tmp.nextAbsBlockPos() ){ if(!cellIsEmpty(p)){ newPiece(); return; } } piece_.advance(); } // If timer finished, level up timeCounterLevelUp_ -= dt; if ( timeCounterLevelUp_ <= 0 ){ // Make pieces go faster timeAdvance_ *= 0.95; timeCounterLevelUp_ = timeLevelUp_; } } void GameState::render(){ // TODO renderer_->clear(); SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = SQUARE_SIZE; rect.h = SQUARE_SIZE; // Render piece Point* b; piece_.initIterator(); while( b = piece_.nextAbsBlockPos() ){ blockTexture_.render( b->x * SQUARE_SIZE, b->y * SQUARE_SIZE, &rect ); } // Render grid for(int i=0; i < GRID_WIDTH; i++){ for(int j=0; j < GRID_HEIGHT; j++){ if( grid[j][i] != 0){ blockTexture_.render( i * SQUARE_SIZE, j * SQUARE_SIZE , &rect); } } } renderer_->update(); } void GameState::finishGame(){ // TODO: finish properly // FINISH HIM!! for(int i=0; i < GRID_WIDTH; i++){ for(int j=0; j < GRID_HEIGHT; j++){ grid[j][i] = 1; } } pause(); } void GameState::clearLines(){ for(int j=0; j < GRID_HEIGHT; j++){ bool lineFull = true; for(int i=0; i < GRID_WIDTH; i++){ if( grid[j][i] != 1 ){ lineFull = false; break; } } if ( !lineFull ){ continue; } // TODO: Animate and add sound // Move all down for(int k=j; k >= 0; k--){ for(int i=0; i < GRID_WIDTH; i++){ grid[k][i] = k==0 ? 0 : grid[k-1][i]; } } } } void GameState::newPiece(){ Point* p; piece_.initIterator(); while ( p = piece_.nextAbsBlockPos() ){ // Set the piece values as set grid[p->y][p->x] = 1; } // Clear the filled lines clearLines(); piece_.restartTo( Piece::PieceType::LINE, 4); piece_.initIterator(); while ( p = piece_.nextAbsBlockPos() ){ // Set the piece values as set if( !cellIsEmpty(p) ){ finishGame(); } } } bool GameState::cellIsEmpty(Point* p){ return( p->x < GRID_WIDTH && p->x >= 0 && p->y < GRID_HEIGHT && grid[p->y][p->x] == 0 ); } void GameState::pressDown(){ yspeed_ = 8; } void GameState::releaseDown(){ yspeed_ = 1; } void GameState::pressLeft(){ Piece tmp = piece_; tmp.move_left(); Point* p; // Check if there's space to move to tmp.initIterator(); while ( p = tmp.nextAbsBlockPos() ){ if(!cellIsEmpty(p)){ // TODO: indicate that it's not possible to move // sound and visual return; } } piece_.move_left(); } void GameState::pressRight(){ Piece tmp = piece_; tmp.move_right(); Point* p; // Check if there's space to move to tmp.initIterator(); while ( p = tmp.nextAbsBlockPos() ){ if(!cellIsEmpty(p)){ // TODO: indicate that it's not possible to move // sound and visual return; } } piece_.move_right(); } void GameState::pressRotate(){ Piece tmp = piece_; tmp.rotate(); Point* p; // Check if there's space to move to tmp.initIterator(); while ( p = tmp.nextAbsBlockPos() ){ if(!cellIsEmpty(p)){ // TODO: indicate that it's not possible to move // sound and visual return; } } piece_.rotate(); }