Example #1
0
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);
            }
        }
    }
}
Example #2
0
void ComplexTetris::droppedPiece(){
    int numFullLines;
    BoardModel newBoard = game->getBoard().placePiece(curPiece(), curX, curY, &numFullLines);
    numLinesRemoved += numFullLines;
    game->setBoard(newBoard);
    newPiece();
}
Example #3
0
///
// 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;
}
Example #4
0
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);
}
Example #5
0
void GenericTetris::startGame()
{
    clearBoard();
    updateScore(0);
    updateLevel(1);
    newPiece();
}
Example #6
0
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();
}
Example #7
0
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;
	}
}
Example #8
0
void QTetrixBoard::timeout()
{
    if ( waitingAfterLine ) {
	timer->stop();
	waitingAfterLine = FALSE;
	newPiece();
	timer->start( timeoutTime );
    } else {
        oneLineDown();
    }
}
Example #9
0
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";
}
Example #10
0
  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();
  }
Example #11
0
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();
}
Example #12
0
  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]
}
Example #14
0
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);
}
Example #16
0
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();
}
Example #17
0
  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]
}
Example #19
0
void QTetrixBoard::pieceDropped(int)
{
    if ( waitingAfterLine ) // give player a break if a line has been removed
        return;
    newPiece();
}
Example #20
0
///
// 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;
}
Example #21
0
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();
}
Example #22
0
void GenericTetris::pieceDropped(int)
{
    newPiece();
}