Untitled
unknown
plain_text
17 days ago
9.8 kB
4
Indexable
Never
Certainly! I'll provide the implementation for all the files in the project. Let's go through each file: 1. `game.h`: ```cpp #pragma once #include <SFML/Graphics.hpp> #include "tetromino.h" #include "score.h" const int M = 23; const int N = 10; class Game { public: Game(); void reset(); void update(float deltaTime); bool check(); bool isDraw(); void checkLines(); bool isGameOver(); void moveLeft(); void moveRight(); void rotate(); void moveDown(); int field[M][N]; Tetromino currentPiece; Tetromino nextPiece; Score score; bool gameOver; float timer; float delay; }; ``` 2. `game.cpp`: ```cpp #include "game.h" #include <cstdlib> #include <ctime> Game::Game() : score(), currentPiece(), nextPiece() { std::srand(static_cast<unsigned int>(std::time(nullptr))); reset(); } void Game::reset() { for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { field[i][j] = 0; } } score.reset(); currentPiece.reset(); nextPiece.reset(); timer = 0; delay = 0.3; gameOver = false; } void Game::update(float deltaTime) { if (gameOver) return; timer += deltaTime; if (timer > delay) { moveDown(); timer = 0; } } bool Game::check() { for (int i = 0; i < 4; i++) { if (currentPiece.blocks[i].x < 0 || currentPiece.blocks[i].x >= N || currentPiece.blocks[i].y >= M) return false; else if (field[currentPiece.blocks[i].y][currentPiece.blocks[i].x]) return false; } return true; } bool Game::isDraw() { for (int i = 0; i < 4; i++) { if (currentPiece.blocks[i].y < 3) return false; } return true; } void Game::checkLines() { int k = M - 1; for (int i = M - 1; i > 3; 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::isGameOver() { for (int i = 0; i < N; i++) { if (field[3][i] > 0) return true; } return false; } void Game::moveLeft() { currentPiece.move(-1, 0); if (!check()) currentPiece.move(1, 0); } void Game::moveRight() { currentPiece.move(1, 0); if (!check()) currentPiece.move(-1, 0); } void Game::rotate() { currentPiece.rotate(); if (!check()) currentPiece.rotateBack(); } void Game::moveDown() { currentPiece.move(0, 1); if (!check()) { currentPiece.move(0, -1); for (int i = 0; i < 4; i++) { field[currentPiece.blocks[i].y][currentPiece.blocks[i].x] = currentPiece.colorNum; } currentPiece = nextPiece; nextPiece.reset(); checkLines(); if (isGameOver()) gameOver = true; } } ``` 3. `score.h`: ```cpp #pragma once class Score { public: Score(); void reset(); void addPoints(int points); int getScore() const; int getHighScore() const; private: int currentScore; int highScore; }; ``` 4. `score.cpp`: ```cpp #include "score.h" Score::Score() : currentScore(0), highScore(0) {} void Score::reset() { currentScore = 0; } void Score::addPoints(int points) { currentScore += points; if (currentScore > highScore) { highScore = currentScore; } } int Score::getScore() const { return currentScore; } int Score::getHighScore() const { return highScore; } ``` 5. `render.h`: ```cpp #pragma once #include <SFML/Graphics.hpp> #include "game.h" class Renderer { public: Renderer(sf::RenderWindow& window); void draw(const Game& game); private: void drawField(const Game& game); void drawCurrentPiece(const Game& game); void drawNextPiece(const Game& game); void drawScore(const Game& game); void drawGameOver(); sf::RenderWindow& window; sf::Texture tileTexture; sf::Sprite tileSprite; sf::Font font; sf::Text scoreText; sf::Text highScoreText; sf::Text gameOverText; }; ``` 6. `render.cpp`: ```cpp #include "render.h" Renderer::Renderer(sf::RenderWindow& window) : window(window) { tileTexture.loadFromFile("images/tiles.png"); tileSprite.setTexture(tileTexture); tileSprite.setScale(2, 2); font.loadFromFile("Roboto-Regular.ttf"); scoreText.setFont(font); highScoreText.setFont(font); gameOverText.setFont(font); scoreText.setCharacterSize(20); highScoreText.setCharacterSize(20); gameOverText.setCharacterSize(40); scoreText.setFillColor(sf::Color::Black); highScoreText.setFillColor(sf::Color::Black); gameOverText.setFillColor(sf::Color::Red); gameOverText.setString("Game Over!"); gameOverText.setPosition(200, 200); } void Renderer::draw(const Game& game) { window.clear(sf::Color::White); drawField(game); drawCurrentPiece(game); drawNextPiece(game); drawScore(game); if (game.gameOver) { drawGameOver(); } } void Renderer::drawField(const Game& game) { for (int i = 3; i < M; i++) { for (int j = 0; j < N; j++) { if (game.field[i][j] == 0) continue; tileSprite.setTextureRect(sf::IntRect(game.field[i][j] * 18, 0, 18, 18)); tileSprite.setPosition(j * 36, (i - 3) * 36); window.draw(tileSprite); } } } void Renderer::drawCurrentPiece(const Game& game) { for (int i = 0; i < 4; i++) { tileSprite.setTextureRect(sf::IntRect(game.currentPiece.colorNum * 18, 0, 18, 18)); tileSprite.setPosition(game.currentPiece.blocks[i].x * 36, (game.currentPiece.blocks[i].y - 3) * 36); window.draw(tileSprite); } } void Renderer::drawNextPiece(const Game& game) { for (int i = 0; i < 4; i++) { tileSprite.setTextureRect(sf::IntRect(game.nextPiece.colorNum * 18, 0, 18, 18)); tileSprite.setPosition(400 + game.nextPiece.blocks[i].x * 36, 100 + game.nextPiece.blocks[i].y * 36); window.draw(tileSprite); } } void Renderer::drawScore(const Game& game) { scoreText.setString("Score: " + std::to_string(game.score.getScore())); scoreText.setPosition(400, 20); window.draw(scoreText); highScoreText.setString("High Score: " + std::to_string(game.score.getHighScore())); highScoreText.setPosition(400, 50); window.draw(highScoreText); } void Renderer::drawGameOver() { window.draw(gameOverText); } ``` 7. `tetromino.h`: ```cpp #pragma once #include <array> struct Point { int x, y; }; class Tetromino { public: Tetromino(); void reset(); void rotate(); void rotateBack(); void move(int dx, int dy); std::array<Point, 4> blocks; int colorNum; private: static const std::array<std::array<int, 4>, 7> figures; }; ``` 8. `tetromino.cpp`: ```cpp #include "tetromino.h" #include <cstdlib> const std::array<std::array<int, 4>, 7> Tetromino::figures = { {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 }; Tetromino::Tetromino() { reset(); } void Tetromino::reset() { colorNum = 1 + std::rand() % 7; int n = std::rand() % 7; for (int i = 0; i < 4; i++) { blocks[i].x = figures[n][i] % 2; blocks[i].y = figures[n][i] / 2; } } void Tetromino::rotate() { Point p = blocks[1]; // center of rotation for (int i = 0; i < 4; i++) { int x = blocks[i].y - p.y; int y = blocks[i].x - p.x; blocks[i].x = p.x - x; blocks[i].y = p.y + y; } } void Tetromino::rotateBack() { Point p = blocks[1]; // center of rotation for (int i = 0; i < 4; i++) { int x = blocks[i].y - p.y; int y = blocks[i].x - p.x; blocks[i].x = p.x + x; blocks[i].y = p.y - y; } } void Tetromino::move(int dx, int dy) { for (int i = 0; i < 4; i++) { blocks[i].x += dx; blocks[i].y += dy; } } ``` 9. `main.cpp`: ```cpp #include <SFML/Graphics.hpp> #include "game.h" #include "render.h" int main() { sf::RenderWindow window(sf::VideoMode(720, 960), "Tetris"); Game game; Renderer renderer(window); sf::Clock clock; while (window.isOpen()) { sf::Time deltaTime = clock.restart(); sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Left) game.moveLeft(); else if (event.key.code == sf::Keyboard::Right) game.moveRight(); else if (event.key.code == sf::Keyboard::Up) game.rotate(); else if (event.key.code == sf::Keyboard::Down) game.moveDown(); else if (event.key.code == sf::Keyboard::Space && game.gameOver) game.reset(); } } game.update(deltaTime.asSeconds()); renderer.draw(game); window.display(); } return 0; } ``` This implementation covers all the core functionality of the Tetris game. You may need to adjust some details, such as file paths for textures and fonts, or fine-tune the game mechanics to match your exact requirements. Some notes: 1. Error handling is minimal here. In a production environment, you'd want to add more robust error checking and handling. 2. The rendering could be optimized further, especially for larger game fields. 3. You might want to add more features like a pause function, difficulty levels, or sound effects. Let me know if you need any clarification or have any questions about this implementation!
Leave a Comment