使用c++编写一个俄罗斯方块程序
时间: 2024-02-03 13:12:02 浏览: 141
以下是一个简单的俄罗斯方块程序,使用C++语言和SFML库。
```c++
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include <ctime>
const int WIDTH = 300;
const int HEIGHT = 600;
const int BLOCK_SIZE = 30;
const int BOARD_WIDTH = 10;
const int BOARD_HEIGHT = 20;
const int SCORE_SIZE = 20;
const int LEVEL_SIZE = 20;
const int FPS = 60;
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Tetris");
sf::Font font;
sf::Text scoreText, levelText;
int board[BOARD_HEIGHT][BOARD_WIDTH] = {0};
int currentBlock[4][4];
int currentBlockX, currentBlockY, currentBlockType, currentBlockRotation;
int score = 0, level = 1;
int blockTypes[7][4][4] = {
{
{0, 0, 0, 0},
{1, 1, 1, 1},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 2, 2, 0},
{0, 2, 2, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 3, 3, 0},
{3, 3, 0, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{4, 4, 0, 0},
{0, 4, 4, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 5, 0, 0},
{5, 5, 5, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 6, 0, 0},
{0, 6, 6, 0},
{0, 6, 0, 0}
},
{
{0, 0, 0, 0},
{0, 7, 0, 0},
{0, 7, 7, 0},
{0, 0, 7, 0}
}
};
void init();
void newBlock();
bool canMove(int x, int y, int rotation);
void move(int x, int y, int rotation);
void checkLines();
void draw();
int main() {
init();
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
break;
}
if (event.type == sf::Event::KeyPressed) {
switch (event.key.code) {
case sf::Keyboard::Left:
if (canMove(currentBlockX - 1, currentBlockY, currentBlockRotation)) {
move(currentBlockX - 1, currentBlockY, currentBlockRotation);
}
break;
case sf::Keyboard::Right:
if (canMove(currentBlockX + 1, currentBlockY, currentBlockRotation)) {
move(currentBlockX + 1, currentBlockY, currentBlockRotation);
}
break;
case sf::Keyboard::Up:
if (canMove(currentBlockX, currentBlockY, (currentBlockRotation + 1) % 4)) {
move(currentBlockX, currentBlockY, (currentBlockRotation + 1) % 4);
}
break;
case sf::Keyboard::Down:
if (canMove(currentBlockX, currentBlockY + 1, currentBlockRotation)) {
move(currentBlockX, currentBlockY + 1, currentBlockRotation);
}
break;
}
}
}
if (canMove(currentBlockX, currentBlockY + 1, currentBlockRotation)) {
move(currentBlockX, currentBlockY + 1, currentBlockRotation);
} else {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (currentBlock[i][j] != 0) {
board[currentBlockY + i][currentBlockX + j] = currentBlock[i][j];
}
}
}
checkLines();
newBlock();
}
draw();
sf::sleep(sf::milliseconds(1000 / FPS));
}
return 0;
}
void init() {
srand(time(NULL));
if (!font.loadFromFile("font.ttf")) {
std::cerr << "Failed to load font file." << std::endl;
exit(EXIT_FAILURE);
}
scoreText.setFont(font);
scoreText.setCharacterSize(SCORE_SIZE);
scoreText.setPosition(10, HEIGHT - SCORE_SIZE - 10);
levelText.setFont(font);
levelText.setCharacterSize(LEVEL_SIZE);
levelText.setPosition(WIDTH - LEVEL_SIZE * 4 - 10, HEIGHT - LEVEL_SIZE - 10);
newBlock();
}
void newBlock() {
currentBlockType = rand() % 7;
currentBlockRotation = rand() % 4;
currentBlockX = BOARD_WIDTH / 2 - 2;
currentBlockY = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
currentBlock[i][j] = blockTypes[currentBlockType][i][j];
}
}
}
bool canMove(int x, int y, int rotation) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (currentBlock[i][j] != 0) {
if (x + j < 0 || x + j >= BOARD_WIDTH || y + i >= BOARD_HEIGHT) {
return false;
}
if (y + i >= 0 && board[y + i][x + j] != 0) {
return false;
}
}
}
}
return true;
}
void move(int x, int y, int rotation) {
currentBlockX = x;
currentBlockY = y;
currentBlockRotation = rotation;
}
void checkLines() {
int linesCleared = 0;
for (int i = BOARD_HEIGHT - 1; i >= 0; i--) {
bool lineFull = true;
for (int j = 0; j < BOARD_WIDTH; j++) {
if (board[i][j] == 0) {
lineFull = false;
break;
}
}
if (lineFull) {
linesCleared++;
for (int k = i; k > 0; k--) {
for (int j = 0; j < BOARD_WIDTH; j++) {
board[k][j] = board[k - 1][j];
}
}
for (int j = 0; j < BOARD_WIDTH; j++) {
board[0][j] = 0;
}
i++;
}
}
if (linesCleared > 0) {
score += linesCleared * linesCleared * 100;
level = 1 + score / 1000;
scoreText.setString("Score: " + std::to_string(score));
levelText.setString("Level: " + std::to_string(level));
}
}
void draw() {
window.clear();
for (int i = 0; i < BOARD_HEIGHT; i++) {
for (int j = 0; j < BOARD_WIDTH; j++) {
if (board[i][j] != 0) {
sf::RectangleShape block(sf::Vector2f(BLOCK_SIZE, BLOCK_SIZE));
block.setPosition(j * BLOCK_SIZE, i * BLOCK_SIZE);
block.setFillColor(sf::Color::White);
window.draw(block);
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (currentBlock[i][j] != 0) {
sf::RectangleShape block(sf::Vector2f(BLOCK_SIZE, BLOCK_SIZE));
block.setPosition((currentBlockX + j) * BLOCK_SIZE, (currentBlockY + i) * BLOCK_SIZE);
block.setFillColor(sf::Color::White);
window.draw(block);
}
}
}
window.draw(scoreText);
window.draw(levelText);
window.display();
}
```
这个程序使用了SFML库来进行游戏窗口和绘图的操作。游戏逻辑主要是在 `newBlock()`、`canMove()`、`move()` 和 `checkLines()` 函数中实现的,其中 `newBlock()` 用于生成新方块,`canMove()` 用于判断方块是否可以移动到某个位置,`move()` 用于移动方块,`checkLines()` 用于检查是否有满行并清除它们。最后,`draw()` 函数用于在窗口中绘制游戏界面和文字。
阅读全文
相关推荐











