Untitled

mail@pastecode.io avatar
unknown
plain_text
13 days ago
11 kB
2
Indexable
Never
#include "game.h"
#include <cstdlib>
#include <ctime>
#include <string>



Game::Game() : window(sf::VideoMode(windowWidth, windowHeight), "Tetris"), score() {
    srand(time(0));

	for (int i =0; i < M; i++)
		for (int j = 0; j< N; j++)
			field[i][j]=0;
    
    t1.loadFromFile("images/tiles.png");
    t2.loadFromFile("images/background.png");
    
    s.setTexture(t1);
    
    s.setScale(2, 2);
    
    background.setSize(sf::Vector2f(windowWidth, windowHeight));
    background.setFillColor(sf::Color(200, 220, 255, 180));
    
    font.loadFromFile("fonts/Roboto-Regular.ttf");
    
    scoreText.setFont(font);
    highScoreText.setFont(font);
    text1.setFont(font);
    text2.setFont(font);
    gameOverText.setFont(font);
    playAgainText.setFont(font);

    text1.setString("Score");
    text2.setString("High");

    scoreText.setFillColor(sf::Color(35, 47, 68));
    highScoreText.setFillColor(sf::Color(35, 47, 68));
    text1.setFillColor(sf::Color(35, 47, 68));
    text2.setFillColor(sf::Color(35, 47, 68));
    gameOverText.setFillColor(sf::Color::Red);
    playAgainText.setFillColor(sf::Color(35, 47, 68));

    scoreText.setCharacterSize(20);
    highScoreText.setCharacterSize(20);
    text1.setCharacterSize(20);
    text2.setCharacterSize(20);
    gameOverText.setCharacterSize(30);
    playAgainText.setCharacterSize(20);


    playfieldBoundary.setSize(sf::Vector2f(playfieldWidth, playfieldHeight));
    playfieldBoundary.setFillColor(sf::Color(200, 220, 255));
    playfieldBoundary.setOutlineThickness(8);
    playfieldBoundary.setOutlineColor(sf::Color(100, 100, 150));
    playfieldBoundary.setPosition(blockSize, 4 * blockSize);

    nextTempoBoundary.setSize(sf::Vector2f(playfieldWidth / 1.5f, playfieldHeight / 5.0f));
    nextTempoBoundary.setFillColor(sf::Color(200, 220, 255));
    nextTempoBoundary.setOutlineThickness(8);
    nextTempoBoundary.setOutlineColor(sf::Color(100, 100, 150));
    nextTempoBoundary.setPosition(blockSize + blockSize + playfieldWidth, 4 * blockSize);

    scoreBoundary.setSize(sf::Vector2f(playfieldWidth / 1.5f, playfieldHeight / 12.0f));
    scoreBoundary.setFillColor(sf::Color(200, 220, 255));
    scoreBoundary.setOutlineThickness(8);
    scoreBoundary.setOutlineColor(sf::Color(100, 100, 150));
    scoreBoundary.setPosition(blockSize + blockSize + playfieldWidth, 4 * blockSize + playfieldHeight * 2 / 5 + blockSize);

    highScoreBoundary.setSize(sf::Vector2f(playfieldWidth / 1.5f, playfieldHeight / 12.0f));
    highScoreBoundary.setFillColor(sf::Color(200, 220, 255));
    highScoreBoundary.setOutlineThickness(8);
    highScoreBoundary.setOutlineColor(sf::Color(100, 100, 150));
    highScoreBoundary.setPosition(blockSize + blockSize + playfieldWidth, 4 * blockSize + playfieldHeight * 2 / 5 + blockSize + playfieldHeight / 12 + 8);

	sf::FloatRect scoreRectangleBounds = scoreBoundary.getGlobalBounds();
    sf::FloatRect scoreTextBounds = scoreText.getLocalBounds();
    text1.setOrigin(scoreTextBounds.left + scoreTextBounds.width - 6, scoreTextBounds.top + 12 + scoreTextBounds.height / 2.0f);
    text1.setPosition(scoreRectangleBounds.left, scoreRectangleBounds.top + scoreRectangleBounds.height / 2.0f);
	text1.scale(2,2);

	sf::FloatRect highScoreRectangleBounds = highScoreBoundary.getGlobalBounds();
    sf::FloatRect highScoreTextBounds = highScoreText.getLocalBounds();
    text2.setOrigin(highScoreTextBounds.left + highScoreTextBounds.width - 6, highScoreTextBounds.top + 12 + highScoreTextBounds.height / 2.0f);
    text2.setPosition(highScoreRectangleBounds.left, highScoreRectangleBounds.top + highScoreRectangleBounds.height / 2.0f);
	text2.scale(2,2);

	sf::FloatRect backgroundBounds = background.getGlobalBounds();
    sf::FloatRect playAgainTextBounds = playAgainText.getLocalBounds();
    playAgainText.setOrigin(playAgainTextBounds.left + playAgainTextBounds.width, playAgainTextBounds.top + 12 + playAgainTextBounds.height / 2.0f);
    playAgainText.setPosition(backgroundBounds.left, backgroundBounds.top + backgroundBounds.height / 2.0f);
	playAgainText.scale(2,2);


    scoreText.setOrigin(scoreTextBounds.left + scoreTextBounds.width + 2, scoreTextBounds.top + 12 + scoreTextBounds.height / 2.0f);
	scoreText.scale(2,2);
    highScoreText.setOrigin(highScoreTextBounds.left + highScoreTextBounds.width + 2, highScoreTextBounds.top + 12 + highScoreTextBounds.height / 2.0f);
	highScoreText.scale(2,2);


    resetGame();
}

void Game::run() {
    sf::Clock clock;
    while (window.isOpen()) {
        float deltaTime = clock.restart().asSeconds();
        processEvents();
        update(deltaTime);
        render();
    }
}

void Game::processEvents() {
    sf::Event e;
    while (window.pollEvent(e)) {
        if (e.type == sf::Event::Closed)
            window.close();

        if (gameOver) {
            if (e.type == sf::Event::KeyPressed && e.key.code == sf::Keyboard::Space)
                resetGame();
            continue;
        }

        if (e.type == sf::Event::KeyPressed) {
            if (e.key.code == sf::Keyboard::Up) rotate = true;
            else if (e.key.code == sf::Keyboard::Left) dx = -1;
            else if (e.key.code == sf::Keyboard::Right) dx = 1;
        }
    }
}

void Game::update(float deltaTime) {
    if (gameOver) return;

    timer += deltaTime;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) delay = 0.05;

    if (dx) {
        currentTetromino.move(dx, 0);
        if (!currentTetromino.checkCollision(field)) currentTetromino.move(-dx, 0);
    }

    if (rotate) {
        if (!currentTetromino.isO()) {  // Don't rotate if it's an O piece
            if (currentTetromino.isI()) {
                // Special rotation for I piece
                currentTetromino.rotate();
                if (!currentTetromino.checkCollision(field)) {
                    currentTetromino.rotate();
                    currentTetromino.rotate();
                    currentTetromino.rotate();
                }
            } else {
                // Normal rotation for other pieces
                currentTetromino.rotate();
                if (!currentTetromino.checkCollision(field)) {
                    currentTetromino.rotate();
                    currentTetromino.rotate();
                    currentTetromino.rotate();
                }
            }
        }
    }


    if (timer > delay) {
        currentTetromino.move(0, 1);
        if (!currentTetromino.checkCollision(field)) {
            currentTetromino.move(0, -1);
            for (int i = 0; i < 4; i++) {
                Point p = currentTetromino.getPosition(i);
                field[p.y][p.x] = currentTetromino.getColorNum();
            }
            currentTetromino = nextTetromino;
			int offset = rand() % 6;
			for (int i = 0; i < 4; i++) {
				currentTetromino.a[i].x += offset;
				}
            nextTetromino.reset(1 + rand() % 7);
            if (currentTetromino.checkOver(field)) {
                gameOver = true;
            }
        }
        timer = 0;
    }

    checkLines();

    dx = 0;
    rotate = false;
    delay = 0.3;
}

void Game::render() {
    window.clear(sf::Color::White);
    window.draw(background);
    window.draw(playfieldBoundary);
    window.draw(nextTempoBoundary);
    window.draw(scoreBoundary);
    window.draw(highScoreBoundary);



    for (int i = 3; i < M; i++)
        for (int j = 0; j < N; j++)
        {
            if (field[i][j] == 0) continue;
            s.setTextureRect(sf::IntRect(field[i][j] * 18, 0, 18, 18));
            s.setPosition(j * blockSize + blockSize, i * blockSize + blockSize);
            window.draw(s);
        }

    currentTetromino.draw(window, s, blockSize, blockSize);
	if(nextTetromino.isO()){
		nextTetromino.draw(window, s, blockSize + blockSize + playfieldWidth + blockSize*1.5 - 8, 4 * blockSize + blockSize);
	}
	else if(nextTetromino.isI()){
		nextTetromino.draw(window, s, blockSize + blockSize + playfieldWidth + blockSize*1.5 - 8, 4 * blockSize + blockSize/2);
	}
	else
		nextTetromino.draw(window, s, blockSize + blockSize + playfieldWidth + blockSize - 8, 4 * blockSize + blockSize);
	sf::FloatRect scoreRectangleBounds = scoreBoundary.getGlobalBounds();
	sf::FloatRect highScoreRectangleBounds = highScoreBoundary.getGlobalBounds();
    scoreText.setString(std::to_string(score.getScore()));
    highScoreText.setString(std::to_string(score.getHighScore()));
	int lenScoreText = std::to_string(score.getScore()).length();
	int lenHighScoreText = std::to_string(score.getHighScore()).length();
	scoreText.setPosition(scoreRectangleBounds.left + scoreRectangleBounds.width - 14 - lenScoreText * 20, scoreRectangleBounds.top + scoreRectangleBounds.height / 2.0f);
    highScoreText.setPosition(highScoreRectangleBounds.left + highScoreRectangleBounds.width - 14 - lenHighScoreText * 20, highScoreRectangleBounds.top + highScoreRectangleBounds.height / 2.0f);
    window.draw(scoreText);
    window.draw(highScoreText);
    window.draw(text1);
    window.draw(text2);

    if (gameOver) {
			window.draw(playfieldBoundary);
			window.draw(nextTempoBoundary);
			window.draw(scoreBoundary);
			window.draw(highScoreBoundary);
            window.draw(scoreText);
            window.draw(highScoreText);
			window.draw(text1);
            window.draw(text2);
			for (int i = 3; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(sf::IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * blockSize, i * blockSize);
                s.move(blockSize, blockSize); //offset
                window.draw(s);
            }
			window.draw(background);
            window.draw(gameOverText);
            playAgainText.setString("Press SPACE to Play Again");
            window.draw(playAgainText);
            window.display();
            return;
    }

    window.display();
}

void Game::resetGame() {
    for (int i = 0; i < M; i++)
        for (int j = 0; j < N; j++)
            field[i][j] = 0;

    score.reset();
    currentTetromino.reset(1 + rand() % 7);
    nextTetromino.reset(1 + rand() % 7);
    timer = 0;
    delay = 0.3;
    gameOver = false;
}

void Game::checkLines() {
    int k = M - 1;
    for (int i = M - 1; i >= 0; i--)
    {
        int count = 0;
        for (int j = 0; j < N; j++)
        {
            if (field[i][j]) count++;
            field[k][j] = field[i][j];
        }
        if (count < N) k--;
        else score.addPoints(100);
    }
}

bool Game::isDraw() {
    for (int i = 0; i < 4; i++)
        if (currentTetromino.getPosition(i).y < 3) return false;
    return true;
}
bool Game::checkO() {
    return (nextTetromino.getPosition(0).y == 0 &&
            nextTetromino.getPosition(1).y == 1 &&
            nextTetromino.getPosition(2).y == 0 &&
            nextTetromino.getPosition(3).y == 1);
}
Leave a Comment