void Game::processEvents() { sf::Event event; while(_window.pollEvent(event)) { if (event.type == sf::Event::Closed)//Close window _window.close(); else if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Escape) { _window.close(); } else if (event.key.code == sf::Keyboard::Down) { _board.move(*_currentPiece, 0, 1); } else if (event.key.code == sf::Keyboard::Up) { _board.move(*_currentPiece, 0, -1); } else if (event.key.code == sf::Keyboard::Left) { _board.move(*_currentPiece, -1, 0); } else if (event.key.code == sf::Keyboard::Right) { _board.move(*_currentPiece, 1, 0); } else if (event.key.code == sf::Keyboard::Space) { _board.drop(*_currentPiece); newPiece(); } else if (event.key.code == sf::Keyboard::S) { _board.rotateRight(*_currentPiece); } else if (event.key.code == sf::Keyboard::D) { _board.rotateLeft(*_currentPiece); } } } }
void ComplexTetris::droppedPiece(){ int numFullLines; BoardModel newBoard = game->getBoard().placePiece(curPiece(), curX, curY, &numFullLines); numLinesRemoved += numFullLines; game->setBoard(newBoard); newPiece(); }
/// // Attempt to hold the piece, returning if a hold was successful. /// static bool tryHold(FSEngine *f) { if (f->holdAvailable) { f->holdAvailable = false; if (f->holdPiece == FS_NONE) { f->holdPiece = f->piece; newPiece(f); f->holdAvailable = false; } else { // NOTE: Abstract into new piece of type theta f->x = f->fieldWidth / 2 - 1; f->y = 1; f->actualY = fix(f->y); f->theta = 0; // NOTE: Utilize new piece here to reset variables // consistently. f->floorkickCount = 0; FSBlock t = f->holdPiece; f->holdPiece = f->piece; f->piece = t; } updateHardDropY(f); f->se |= FST_SE_FLAG_HOLD; return true; } return false; }
void GameWidget::newGame() { in_pause = false; fast_mode = false; num_level = 1; num_pieces_level = 2; num_points = 0; bg_sprite = (Sprite)(Sprite_Bg1 + random.getLong(num_bgs)); screen->setBackgroundSprite(bg_sprite); mirror->setBackgroundSprite(bg_sprite); next->setBackgroundSprite(bg_sprite); for (int i = 0; i < scr_width; ++i) mirror_sprites[i] = bg_sprite; for (int i = 0; i < 4; ++i) next_piece[i] = bg_sprite; for (int y = 0; y < scr_height; ++y) for (int x = 0; x < scr_width; ++x) ref(x, y) = bg_sprite; newPiece(); nextPiece(); updateMirror(); in_game = true; repaintChilds(); emit changedStats(num_level, num_points); timer_interval = 700; timer->start(timer_interval); }
void GenericTetris::startGame() { clearBoard(); updateScore(0); updateLevel(1); newPiece(); }
void ComplexTetris::startNewGame(){ paused = false; started = true; gameOver = false; numLinesRemoved = 0; BoardModel emptyBoard(game->getWidth(), game->getHeight()); game->setBoard(emptyBoard); game->setNextPiece(Tetronimo::getRandomPiece()); newPiece(); }
void PlayState::move(int x, int y) { if (collisionTest(x, y)) { if (y == 1) { if (sPiece.y < 1) { GameStateManager::Instance()->changeGameState(new GameOverState()); } else { //Add piece to landed for (int row = 0; row != 4; row++) { for (int col = 0; col != 4; col++) { if (sPiece.size[row][col] != TILEBLANK) { landed[sPiece.y + row][sPiece.x + col] = sPiece.size[row][col]; } } } //Check filled rows for (int row = 0; row != 16; row++) { bool filled{ true }; for (int col = 0; col != 10; col++) { if (landed[row][col] == TILEBLANK) { filled = false; } } if (filled) { deleteRow(row); } } dropDelay -= .05; newPiece(); } } } else //No collision, move piece { sPiece.x += x; sPiece.y += y; } }
void QTetrixBoard::timeout() { if ( waitingAfterLine ) { timer->stop(); waitingAfterLine = FALSE; newPiece(); timer->start( timeoutTime ); } else { oneLineDown(); } }
Game::Game() : _window(sf::VideoMode(800, 600),"SFML Tetris"), _board() { _window.setFramerateLimit(60); // std::cout << "ka" << "\n"; rand_init(); // std::cout << "ki" << "\n"; _board.setPosition(10,10); // std::cout << "ku" << "\n"; _stats.setPosition(300,10); // std::cout << "ke" << "\n"; newPiece(); // std::cout << "ko" << "\n"; }
void run() { isPaused=false; if(!runner.joinable()) // Thread not yet initialized { timeCount=0; newPiece(); isContinuing=true; runner = std::thread( &TetrisGame_impl::threadFunc, this); } pauseCondition.notify_one(); }
void GenericTetrix::startGame(int gameType,int fillRandomLines) { gameID = gameType; clearBoard(fillRandomLines); nLinesRemoved = 0; updateRemoved(nLinesRemoved); nClearLines = height; nPiecesDropped = 0; score = 0; updateScore(score); level = 1; updateLevel(level); newPiece(); }
void timeStep() { if( (timeCount * gravity::num) / gravity::den > 0) { if(current.timeStep(1)) { newPiece(); } timeCount=0; } else { ++timeCount; } }
//! [15] void TetrixBoard::timerEvent(QTimerEvent *event) { if (event->timerId() == timer.timerId()) { if (isWaitingAfterLine) { isWaitingAfterLine = false; newPiece(); timer.start(timeoutTime(), this); } else { oneLineDown(); } } else { QFrame::timerEvent(event); //! [15] //! [16] } //! [16] //! [17] }
void Game::update(sf::Time deltaTime) { if(not _board.isGameOver()) { _stats.addLines(_board.clearLines(*_currentPiece)); _nextFall += deltaTime; if((not _board.isFallen(*_currentPiece)) and (_currentPiece->getTimeSinceLastMove() > sf::seconds(1.f))) newPiece(); sf::Time max_time = sf::seconds(std::max(0.1, 0.6-0.005*_stats.getLvl())); while(_nextFall > max_time) { _nextFall -= max_time; _board.move(*_currentPiece, 0, 1); } } else { _stats.gameOver(); } }
//! [4] void TetrixBoard::start() { if (isPaused) return; isStarted = true; isWaitingAfterLine = false; numLinesRemoved = 0; numPiecesDropped = 0; score = 0; level = 1; clearBoard(); emit linesRemovedChanged(numLinesRemoved); emit scoreChanged(score); emit levelChanged(level); newPiece(); timer.start(timeoutTime(), this); }
void GameWidget::nextPiece() { piece[0] = next_piece[0]; piece[1] = next_piece[1]; piece[2] = next_piece[2]; piece[3] = next_piece[3]; newPiece(); xpos = (scr_width - 2) / 2; ypos = 0; if ((piece[0] != bg_sprite && ref(xpos + 0, ypos + 0) != bg_sprite) || (piece[1] != bg_sprite && ref(xpos + 1, ypos + 0) != bg_sprite) || (piece[2] != bg_sprite && ref(xpos + 0, ypos + 1) != bg_sprite) || (piece[3] != bg_sprite && ref(xpos + 1, ypos + 1) != bg_sprite)) { in_game = false; repaintChilds(); KMessageBox::sorry(this, i18n("Game Over")); emit gameOver(); } putPiece(); }
void consumeInput() { inputMutex.lock(); std::vector<PieceInput> input(std::move(inputBuffer)); inputBuffer.clear(); inputBuffer.reserve(minBuffer); inputMutex.unlock(); for(auto itor = input.begin(); itor != input.end(); ++itor) { if(current.handleInput(*itor)) { if(scanForLoss()) { gameOver(); return; } // 'else' redundant newPiece(); } } }
//! [22] void TetrixBoard::pieceDropped(int dropHeight) { for (int i = 0; i < 4; ++i) { int x = curX + curPiece.x(i); int y = curY - curPiece.y(i); shapeAt(x, y) = curPiece.shape(); } ++numPiecesDropped; if (numPiecesDropped % 25 == 0) { ++level; timer.start(timeoutTime(), this); emit levelChanged(level); } score += dropHeight + 7; emit scoreChanged(score); removeFullLines(); if (!isWaitingAfterLine) newPiece(); //! [22] //! [23] }
void QTetrixBoard::pieceDropped(int) { if ( waitingAfterLine ) // give player a break if a line has been removed return; newPiece(); }
/// // Perform a single game tick. // // This is just a state machine which is repeatedly called from the main // game loop. We do not want a 1 frame delay for some actions so we allow // some to run 'instantly'. /// void fsGameTick(FSEngine *f, const FSInput *i) { i8 distance; bool moved = false, rotated = false; f->se = 0; f->totalTicksRaw++; // TODO: Remove lastInput since unused f->lastInput = *i; // Always handle restart/quit events at any time. if (i->extra & FST_INPUT_RESTART) { f->state = FSS_RESTART; } if (i->extra & FST_INPUT_QUIT) { f->state = FSS_QUIT; } // Always update the current piece finesse counters if (i->extra & FST_INPUT_FINESSE_ROTATE) { f->pieceRotateCount += 1; } if (i->extra & FST_INPUT_FINESSE_MOVE) { f->pieceMovePressCount += 1; } // Always count the number of new keys pressed f->totalKeysPressed += i->newKeysCount; beginTick: switch (f->state) { case FSS_READY: case FSS_GO: // Ready, Go has has slightly different hold mechanics. Since we do not // yet have a piece we need to copy directly from the next queue to the // hold piece. Further, we can optionally hold as many times as we want // so need to discard the hold piece if required. if ((i->extra & FST_INPUT_HOLD) && f->holdAvailable) { f->holdPiece = nextPreviewPiece(f); f->se |= FST_SE_FLAG_HOLD; if (!f->infiniteReadyGoHold) { f->holdAvailable = false; } } if (f->genericCounter == 0) { f->se |= FST_SE_FLAG_READY; } if (f->genericCounter == TICKS(f->readyPhaseLength)) { f->se |= FST_SE_FLAG_GO; f->state = FSS_GO; } // This cannot be an `else if` since goPhaseLength could be 0. if (f->genericCounter == TICKS(f->readyPhaseLength) + TICKS(f->goPhaseLength)) { f->state = FSS_NEW_PIECE; } f->genericCounter++; // We need an explicit return here to avoid incrementing `totalTicks return; case FSS_ARE: // Even if ARE is instant, we still want to check for IHS and IRS state. // This allows the following behaviour: // // Currently we should be able to have three different actions for an initial // action: // // NONE - IRS/IHS disabled and not checked // HELD - Allows input action to remain set from last piece // HIT - Requires a new input action to trigger (not implemented) // // If ARE can be cancelled then the action will occur on the next // frame with the piece already playable. // This may need some more tweaking since during fast play initial stack // far too easily. if (f->initialActionStyle == FST_IA_PERSISTENT) { // Only check the current key state. // This is only dependent on the value on the final frame before the // piece spawns. Could adjust to allow any mid-ARE initial action to // stick till spawn. // We need an implicit ordering here so are slightly biased. May want to // give an option to adjust this ordering or have a stricter // order. if (i->currentKeys & FST_VK_FLAG_ROTR) { f->irsAmount = FST_ROT_CLOCKWISE; } else if (i->currentKeys & FST_VK_FLAG_ROTL) { f->irsAmount = FST_ROT_ANTICLOCKWISE; } else if (i->currentKeys & FST_VK_FLAG_ROTH) { f->irsAmount = FST_ROT_HALFTURN; } else { f->irsAmount = FST_ROT_NONE; } if (i->currentKeys & FST_VK_FLAG_HOLD) { f->ihsFlag = true; } else { f->ihsFlag = false; } } if (f->areCancellable && ( i->rotation != 0 || i->movement != 0 || i->gravity != 0 || i->extra != 0 || // We need to check ihs/irs since this is solely based on new // key state and otherwise may not be picked up. f->ihsFlag || f->irsAmount ) ) { f->areTimer = 0; f->state = FSS_NEW_PIECE; goto beginTick; } if (f->areTimer++ > TICKS(f->areDelay)) { f->areTimer = 0; f->state = FSS_NEW_PIECE; goto beginTick; } break; case FSS_NEW_PIECE: newPiece(f); // Apply ihs/irs before checking lockout. if (f->irsAmount != FST_ROT_NONE) { doRotate(f, f->irsAmount); } if (f->ihsFlag) { tryHold(f); } f->irsAmount = FST_ROT_NONE; f->ihsFlag = false; // Check lockout (irs/ihs has been applied already) if (isCollision(f, f->x, f->y, f->theta)) { f->state = FSS_GAMEOVER; goto beginTick; } updateHardDropY(f); f->state = FSS_FALLING; break; case FSS_FALLING: case FSS_LANDED: // If a hard drop occurs we want to immediately drop the piece and not // apply any other movement. This is far more natural and results in // less misdrops than if movement is processed prior. // // See issue #49 for details. if ((i->extra & FST_INPUT_HARD_DROP) || // We must recheck the lock timer state here since we may have // moved back to FALLING from LANDED on the last frame and do // **not** want to lock in mid-air! (f->lockTimer >= TICKS(f->lockDelay) && f->state == FSS_LANDED)) { f->state = FSS_LINES; // Still need to apply piece gravity before entering FSS_LINES. doPieceGravity(f, i->gravity); break; } if (i->extra & FST_INPUT_HOLD) { tryHold(f); } if (i->rotation) { if (doRotate(f, i->rotation)) { rotated = true; } } // Left movement distance = i->movement; for (; distance < 0; ++distance) { if (!isCollision(f, f->x - 1, f->y, f->theta)) { f->x -= 1; moved = true; } } // Right movement for (; distance > 0; --distance) { if (!isCollision(f, f->x + 1, f->y, f->theta)) { f->x += 1; moved = true; } } if (moved || rotated) { if (moved) { f->se |= FST_SE_FLAG_MOVE; } if (rotated) { f->se |= FST_SE_FLAG_ROTATE; } updateHardDropY(f); } doPieceGravity(f, i->gravity); // This must occur after we process the lockTimer to allow floorkick // limits to be processed correctly. If we encounter a floorkick limit // we set the lockTimer to max to allow a lock next frame, while still // giving the user an option to perform a move/rotate input. if ((moved || rotated) && f->lockStyle == FST_LOCK_MOVE) { f->lockTimer = 0; } if (f->state == FSS_LANDED) { f->lockTimer++; } break; case FSS_LINES: lockPiece(f); // NOTE: Make this conversion less *magic* f->se |= (1 << (FST_SE_IPIECE + f->piece)); f->piece = FS_NONE; const int lines = clearLines(f); if (0 < lines && lines <= 4) { // NOTE: Make this conversion less *magic* f->se |= (FST_SE_FLAG_ERASE1 << (lines - 1)); } f->linesCleared += lines; f->state = f->linesCleared < f->goal ? FSS_ARE : FSS_GAMEOVER; goto beginTick; case FSS_GAMEOVER: f->se |= FST_SE_FLAG_GAMEOVER; /* FALLTHROUGH */ case FSS_QUIT: case FSS_RESTART: break; default: fsLogError("Unknown state entered!"); break; } f->totalTicks += 1; }
PlayState::PlayState() : landed() { font.loadFromFile("assets/MYRIADPRO-BOLD.OTF"); //Play Area playArea.setSize(sf::Vector2f(350, 560)); playArea.setFillColor(sf::Color(100, 100, 100, 255)); playArea.setPosition(20, 20); //Side Area sideArea.setSize(sf::Vector2f(110, 600)); sideArea.setFillColor(sf::Color(100, 100, 100, 255)); sideArea.setPosition(390, 0); //next Text nextText.setFont(font); nextText.setCharacterSize(30); nextText.setString("NEXT"); nextText.setOrigin(nextText.getLocalBounds().width / 2, nextText.getLocalBounds().height / 2); nextText.setPosition(sideArea.getPosition().x + sideArea.getLocalBounds().width / 2, sideArea.getPosition().y + 5); //Menu Button menuButton.setSize(sf::Vector2f(100, 50)); menuButton.setFillColor(DarkGrey); menuButton.setOrigin(menuButton.getLocalBounds().width / 2, menuButton.getLocalBounds().height / 2); menuButton.setPosition(sideArea.getPosition() + sf::Vector2f(sideArea.getLocalBounds().width / 2, 0) + sf::Vector2f(0, 515)); //Menu Text menuText.setFont(font); menuText.setCharacterSize(30); menuText.setString("MENU"); menuText.setOrigin(menuText.getLocalBounds().width / 2, menuText.getLocalBounds().height / 2); menuText.setPosition(menuButton.getPosition().x, menuButton.getPosition().y - 10); //exit Button exitButton.setSize(sf::Vector2f(100, 50)); exitButton.setFillColor(DarkGrey); exitButton.setOrigin(exitButton.getLocalBounds().width / 2, exitButton.getLocalBounds().height / 2); exitButton.setPosition(sideArea.getPosition() + sf::Vector2f(sideArea.getLocalBounds().width / 2, 0) + sf::Vector2f(0, 570)); //exit Text exitText.setFont(font); exitText.setCharacterSize(30); exitText.setString("EXIT"); exitText.setOrigin(exitText.getLocalBounds().width / 2, exitText.getLocalBounds().height / 2); exitText.setPosition(exitButton.getPosition().x, exitButton.getPosition().y - 10); int temp[16][10] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; for (int row = 0; row != 16; row++) { for (int col = 0; col != 10; col++) { landed[row][col] = temp[row][col]; } } srand((unsigned)time(NULL)); newPiece(); }
void GenericTetris::pieceDropped(int) { newPiece(); }