Untitled

mail@pastecode.io avatar
unknown
plain_text
16 days ago
15 kB
2
Indexable
Never
#include <SFML/Graphics.hpp>
#include <time.h>
#include <string>
#include <iostream>
using namespace sf;


// Playfield dimensions
const int playfieldWidth = 180; // 180 pixels wide
const int playfieldHeight = 360; // 360 pixels high
const int boundaryThickness = 4; // Thickness of the boundary

const int windowHeight = 960;
const int windowWidth = 720;
const int M = 23;
const int N = 10;

// Grid dimensions
const int gridWidth = 10;
const int gridHeight = 23;
const int blockSize = 18*2; // Each block is 32x32 pixels

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4], c[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};



void resetGame(int& score, int& colorNum, int& nextColorNum, int& nextTemo, float& timer, float& delay, bool& gameOver)
{
	for(int i = 0; i < M; i++)
	{
		for(int j = 0; j < N; j++) field[i][j] = 0;
	}

	score = 0;
	colorNum = 1 + rand() % 7;
	timer = 0;
	delay = 0.3;
	gameOver = false;

	int n = rand() % 7;
	int offset = rand() % 6;
	for(int i = 0; i < 4; i++)
	{
		a[i].y = figures[n][i] % 2;
		a[i].x = figures[n][i] / 2 + offset;
	}
	nextColorNum = 1 + rand() % 7;
	nextTemo = rand() % 7;
	for (int i = 0; i < 4; i++)
    {
        c[i].y = figures[nextTemo][i] % 2;
        c[i].x = figures[nextTemo][i] / 2;
    }
}

bool check()
{
    for (int i = 0; i < 4; i++)
        if (a[i].x < 0 || a[i].x >= N || a[i].y >= M) return 0;
        else if (field[a[i].y][a[i].x]) return 0;
    return 1;
};

bool isDraw()
{
	for (int i = 0; i < 4; i++)
        if (a[i].y < 3) return 0;
    return 1;
}

bool checkI()
{
	for(int i = 0; i < 4; i++){
		if(c[i].y != 1) return false;
	}
	return true;
}

bool checkO(){
	if(c[0].y == 0 &&
		c[1].y == 1 &&
		c[2].y == 0 &&
		c[3].y == 1) return true;
	return false;
}

void checkLines(int& score)
{
	int fieldTem[M][N] = { 0 };
	int x = M - 1;
	for(int i = M - 1; i >= 4; i--)
	{
		int count = 0;
		for(int j = 0; j < N; j++){
			if(field[i][j]) count++;
		}
		if(count < N)
		{
			for(int j = 0; j < N; j++)
			{
				fieldTem[x][j] = field[i][j];
			}
			x--;
		}
		else score += 100;
	}
	for(int i = 4; i < M; i++){
		for(int j = 0; j < N; j++)
		{
			field[i][j] = fieldTem[i][j];
		}
	}
}

int main()
{
    srand(time(0));

    RenderWindow window(VideoMode(windowWidth, windowHeight), "The Game!");

    Texture t1, t2, t3;
    t1.loadFromFile("images/tiles.png");
    t2.loadFromFile("images/background.png");
    t3.loadFromFile("images/frame.png");
    Sprite s(t1), frame(t3);
    sf::RectangleShape background(sf::Vector2f(windowWidth, windowHeight));
    background.setFillColor(sf::Color(200, 220, 255, 180));
	s.setScale(2,2);
    Font font;
    font.loadFromFile("fonts/Roboto-Regular.ttf");

    Text scoreText;
	Text highScoreText;
	Text text1, text2;
	Text gameOverText, playAgainText;

    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(Color(35, 47, 68));
    highScoreText.setFillColor(Color(35, 47, 68));
    text1.setFillColor(Color(35, 47, 68));
    text2.setFillColor(Color(35, 47, 68));
    gameOverText.setFillColor(Color::Red);
    playAgainText.setFillColor(Color(35, 47, 68));

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

    scoreText.setPosition(250, 20);  // Position on the right side
    highScoreText.setPosition(250, 50);
    gameOverText.setPosition(40, 220);
    playAgainText.setPosition(70, 260);

	// Create a grid
    sf::RectangleShape gridLines[gridWidth * gridHeight];

    // Initialize grid lines
	for (int i = 3; i < gridHeight; ++i)
    {
        for (int j = 0; j < gridWidth; ++j)
        {
            gridLines[i * gridWidth + j].setSize(sf::Vector2f(blockSize - 1, blockSize - 1)); // Adjust size for line thickness
            gridLines[i * gridWidth + j].setFillColor(sf::Color::Transparent);
            gridLines[i * gridWidth + j].setOutlineThickness(1);
            gridLines[i * gridWidth + j].setOutlineColor(sf::Color::Black);
            gridLines[i * gridWidth + j].setPosition(j * blockSize, i * blockSize);
			gridLines[i * gridWidth + j].move(blockSize, 2 * blockSize);
        }
    }

	// Create a rectangle for the playfield boundary
    sf::RectangleShape playfieldBoundary(sf::Vector2f(playfieldWidth, playfieldHeight));
    playfieldBoundary.setFillColor(sf::Color(200, 220, 255)); // Light blue background for playfield
    playfieldBoundary.setOutlineThickness(boundaryThickness);
    playfieldBoundary.setOutlineColor(sf::Color(100, 100, 150)); // Darker blue border
	playfieldBoundary.move(blockSize, 4 * blockSize);
	playfieldBoundary.setScale(2,2);

	sf::RectangleShape nextTempoBoundary(sf::Vector2f(playfieldWidth / 1.5, playfieldHeight / 5));
    nextTempoBoundary.setFillColor(sf::Color(200, 220, 255)); // Light blue background for playfield
    nextTempoBoundary.setOutlineThickness(boundaryThickness);
    nextTempoBoundary.setOutlineColor(sf::Color(100, 100, 150)); // Darker blue border
	//nextTempoBoundary.move(2 * blockSize, 6 * blockSize);
	nextTempoBoundary.move(blockSize + blockSize + playfieldWidth * 2, 4 * blockSize);
	nextTempoBoundary.setScale(2,2);

	sf::RectangleShape scoreBoundary(sf::Vector2f(playfieldWidth / 1.5, playfieldHeight / 12));
    scoreBoundary.setFillColor(sf::Color(200, 220, 255)); // Light blue background for playfield
    scoreBoundary.setOutlineThickness(boundaryThickness);
    scoreBoundary.setOutlineColor(sf::Color(100, 100, 150)); // Darker blue border
	scoreBoundary.move(blockSize + blockSize + playfieldWidth * 2, 4 * blockSize + playfieldHeight * 2 / 5 + blockSize);
	scoreBoundary.setScale(2,2);

	sf::RectangleShape highScoreBoundary(sf::Vector2f(playfieldWidth / 1.5, playfieldHeight / 12));
    highScoreBoundary.setFillColor(sf::Color(200, 220, 255)); // Light blue background for playfield
    highScoreBoundary.setOutlineThickness(boundaryThickness);
    highScoreBoundary.setOutlineColor(sf::Color(100, 100, 150)); // Darker blue border
	highScoreBoundary.move(blockSize + blockSize + playfieldWidth * 2, 4 * blockSize + playfieldHeight * 2 / 5 + blockSize + playfieldHeight * 2 / 12 + 8);
	highScoreBoundary.setScale(2,2);


	//Hien thi chu highscore
	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);


	// Hien thi diem
    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);

	sf::FloatRect nextTempoBounds = nextTempoBoundary.getLocalBounds();

	int dx = 0;
    bool rotate = 0;
    int colorNum = 1;
	int nextColorNum = 1 + rand() % 7;
	int nextTemo = rand() % 7;
    float timer = 0, delay = 0.3;
    int score = 0;
    int highScore = 0;
    bool gameOver = false;

    Clock clock;

    // Initialize the first piece
	resetGame(score, colorNum, nextColorNum, nextTemo, timer, delay, gameOver);

    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;
        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (gameOver)
            {
                if (e.type == Event::KeyPressed && e.key.code == Keyboard::Space)
                {
                    	resetGame(score, colorNum, nextColorNum, nextTemo, timer, delay, gameOver);
                }
                continue;
            }

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

        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(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();
            continue;
        }
		// Check gameover
		for(int i = 0; i < N; i++)
		{
			if(field[3][i] > 0)
			{
				gameOver = true;
				break;
			}
		}
        if (Keyboard::isKeyPressed(Keyboard::Down)) delay = 0.05;

        //// <- Move -> ///
        for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //////Rotate//////
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
            if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];
        }

        ///////Tick//////
        if (timer > delay)
        {
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].y += 1; }

            if (!check())
            {
                for (int i = 0; i < 4; i++) field[b[i].y][b[i].x] = colorNum;
				colorNum = nextColorNum;
                int n = nextTemo;
				nextColorNum = 1 + rand() % 7;
				nextTemo = rand() % 7;
				int offset = rand() % 6;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = c[i].x + offset;
                    a[i].y = c[i].y;
                }
				for (int i = 0; i < 4; i++)
                {
                    c[i].y = figures[nextTemo][i] % 2;
                    c[i].x = figures[nextTemo][i] / 2;
                }
				
            }
            timer = 0;
        }

        ///////check lines//////////
		checkLines(score);


        // Update high score
        if (score > highScore) highScore = score;

        dx = 0; rotate = 0; delay = 0.3;

        /////////draw//////////
        window.clear(Color::White);
        window.draw(background);
		window.draw(playfieldBoundary);
		window.draw(nextTempoBoundary);
		window.draw(scoreBoundary);
		window.draw(highScoreBoundary);
		if(checkI())
		for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(nextColorNum * 18, 0, 18, 18));
            s.setPosition(c[i].x * blockSize, c[i].y * blockSize);
            s.move(blockSize + blockSize + playfieldWidth * 2 + 1.5*blockSize - 8,4 * blockSize + blockSize/2); //offset
            window.draw(s);
        }
		else if(checkO())
		for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(nextColorNum * 18, 0, 18, 18));
            s.setPosition(c[i].x * blockSize, c[i].y * blockSize);
            s.move(blockSize + blockSize + playfieldWidth * 2 + 1.5*blockSize - 8,4 * blockSize + blockSize); //offset
            window.draw(s);
        }
		else
		for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(nextColorNum * 18, 0, 18, 18));
            s.setPosition(c[i].x * blockSize, c[i].y * blockSize);
            s.move(blockSize + blockSize + playfieldWidth * 2 + blockSize - 8,4 * blockSize + blockSize); //offset
            window.draw(s);
        }

        for (int i = 3; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * blockSize, i * blockSize);
                s.move(blockSize, blockSize); //offset
                window.draw(s);
            }
		if(isDraw()){
        for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(colorNum * 18, 0, 18, 18));
            s.setPosition(a[i].x * blockSize, a[i].y * blockSize);
            s.move(blockSize, 1 * blockSize); //offset
            window.draw(s);
        }
		}
		std::string tHighScore = std::to_string(highScore);
		std::string tScoreText = std::to_string(score);
		scoreText.setString(tScoreText);
		highScoreText.setString(tHighScore);
		int lenScoreText = tScoreText.length();
		int lenHighScoreText = tHighScore.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);
        window.display();
    }

    return 0;
}
Leave a Comment