Setup
函数)dir = STOP;
: 初始化蛇的移动方向为停止状态。snake.clear();
: 清空蛇的身体。snake.push_back({ WIDTH / 2, HEIGHT / 2 });
: 将蛇的头部放置在游戏区域的中心。score = 0;
: 重置分数。food = { rand() % WIDTH, rand() % HEIGHT };
: 随机生成食物的位置。gameOver = false;
: 游戏状态设置为“未结束”。Draw
函数)system("cls");
: 清除控制台屏幕。for (int i = 0; i < WIDTH + 2; i++) cout << "#";
: 绘制游戏区域的边框。for (int y = 0; y < HEIGHT; y++) { ... }
: 绘制游戏区域的每一行。if (x == food.x && y == food.y) cout << "F";
: 在食物位置绘制F
。if (x == 0) cout << "#";
: 绘制左边框。if (x == WIDTH - 1) cout << "#";
: 绘制右边框。if (gameOver) { ... }
: 如果游戏结束,显示游戏结束消息。Input
函数)if (_kbhit()) { char c = _getch(); ... }
: 检测并读取用户的键盘输入。case 'a':
: 处理向左移动。case 'd':
: 处理向右移动。case 'w':
: 处理向上移动。case 's':
: 处理向下移动。case 'x':
: 处理退出游戏。Logic
函数)Point prev = snake[0];
: 保存蛇头的当前坐标。snake[0].x += (dir == RIGHT) - (dir == LEFT);
: 根据当前方向更新蛇头的x坐标。snake[0].y += (dir == DOWN) - (dir == UP);
: 根据当前方向更新蛇头的y坐标。if (snake[0].x >= WIDTH || snake[0].x < 0 || snake[0].y >= HEIGHT || snake[0].y < 0)
: 检查蛇是否走出边界。if (snake[0].x == food.x && snake[0].y == food.y)
: 检查蛇是否吃到食物。for (int i = 1; i < snake.size(); i++)
: 检查蛇是否碰到自己。for (int i = 1; i < snake.size(); i++) { prev2 = snake[i]; snake[i] = prev; prev = prev2; }
: 移动蛇的身体。原理: 通过控制光标的位置来实现清屏和更新内容,而不是使用 system("cls")
这样的全屏清除方法。
实现:
gotoxy(int x, int y)
函数移动光标到指定位置。(0, 0)
清除内容,然后绘制新的内容。优点: 避免了整个屏幕的清除和重绘,减少了闪烁。
编译时在连接器命令行加入以下命令
-std=c++11
#include
#include // 用于 _getch() 读取键盘输入
#include // 用于 Sleep() 暂停游戏
#include
#include
#include
using namespace std;
// 定义游戏常量
const int WIDTH = 15; // 游戏区域的宽度
const int HEIGHT = 15; // 游戏区域的高度
int score = 0; // 玩家得分
bool gameOver = false; // 游戏是否结束的标志
// 定义方向控制的枚举
enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN };
Direction dir; // 当前蛇的移动方向
// 表示二维空间中的一个点
struct Point {
int x, y;
};
// 存储蛇的身体段的向量
vector snake;
Point food; // 当前食物的位置
// 函数声明
void Setup();
void Draw();
void Input();
void Logic();
void gotoxy(int x, int y); // 函数声明:移动光标到指定位置
// 初始化游戏状态的函数
void Setup() {
dir = STOP; // 设置蛇的初始移动方向为停止
snake.clear(); // 清空蛇的身体
snake.push_back({ WIDTH / 2, HEIGHT / 2 }); // 将蛇的头部放置在游戏区域的中心
score = 0; // 重置分数
food = { rand() % WIDTH, rand() % HEIGHT }; // 随机生成食物的位置
gameOver = false; // 游戏状态设置为“未结束”
}
// 移动光标到指定位置
void gotoxy(int x, int y) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备的句柄
COORD pos = { static_cast(x), static_cast(y) }; // 设置光标位置
SetConsoleCursorPosition(handle, pos); // 移动光标
}
// 绘制游戏界面的函数
void Draw() {
gotoxy(0, 0); // 移动光标到控制台的左上角
// 绘制游戏区域的上边框
for (int i = 0; i < WIDTH + 2; i++)
cout << "#";
cout << endl;
// 绘制游戏区域的每一行
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
if (x == 0)
cout << "#"; // 绘制左边框
if (x == food.x && y == food.y)
cout << "F"; // 绘制食物
else {
bool print = false;
// 检查当前坐标是否被蛇的身体占据
for (auto s : snake) {
if (s.x == x && s.y == y) {
cout << "O"; // 绘制蛇的身体段
print = true;
}
}
if (!print)
cout << " "; // 空白区域
}
if (x == WIDTH - 1)
cout << "#"; // 绘制右边框
}
cout << endl;
}
// 绘制游戏区域的下边框
for (int i = 0; i < WIDTH + 2; i++)
cout << "#";
cout << endl;
// 显示当前得分
cout << "Score: " << score << endl;
// 如果游戏结束,显示“游戏结束”消息
if (gameOver) {
cout << "Game Over! Press any key to exit..." << endl;
}
}
// 处理用户输入的函数
void Input() {
if (_kbhit()) { // 检测是否有键盘输入
char c = _getch(); // 获取按下的键
switch (c) {
case 'a': // 向左移动
if (dir != RIGHT) // 确保蛇不会反向移动
dir = LEFT;
break;
case 'd': // 向右移动
if (dir != LEFT)
dir = RIGHT;
break;
case 'w': // 向上移动
if (dir != DOWN)
dir = UP;
break;
case 's': // 向下移动
if (dir != UP)
dir = DOWN;
break;
case 'x': // 退出游戏
gameOver = true;
break;
}
}
}
// 更新游戏逻辑的函数
void Logic() {
if (gameOver) return; // 如果游戏结束,跳过逻辑更新
// 更新蛇头的位置
Point prev = snake[0];
Point prev2;
snake[0].x += (dir == RIGHT) - (dir == LEFT); // 根据方向更新蛇头的x坐标
snake[0].y += (dir == DOWN) - (dir == UP); // 根据方向更新蛇头的y坐标
// 检查蛇是否超出边界
if (snake[0].x >= WIDTH || snake[0].x < 0 || snake[0].y >= HEIGHT || snake[0].y < 0) {
gameOver = true; // 游戏结束
}
// 检查蛇是否碰到自己
for (int i = 1; i < snake.size(); i++) {
if (snake[i].x == snake[0].x && snake[i].y == snake[0].y) {
gameOver = true; // 游戏结束
}
}
// 检查蛇是否吃到食物
if (snake[0].x == food.x && snake[0].y == food.y) {
score++; // 增加分数
food = { rand() % WIDTH, rand() % HEIGHT }; // 生成新的食物位置
snake.push_back(prev); // 将新的一节添加到蛇的身体
}
// 移动蛇的身体
for (int i = 1; i < snake.size(); i++) {
prev2 = snake[i];
snake[i] = prev;
prev = prev2;
}
}
// 主函数
int main() {
srand(static_cast(time(0))); // 用当前时间作为随机数生成的种子
Setup(); // 初始化游戏
while (!gameOver) { // 游戏循环
Draw(); // 绘制游戏界面
Input(); // 处理用户输入
Logic(); // 更新游戏逻辑
Sleep(100); // 暂停100毫秒
}
Draw(); // 绘制结束界面显示“游戏结束”
_getch(); // 等待用户输入后退出程序
return 0;
}
C++控制台去呈现一些图形游戏确实不太方便,最好可以使用EASYX/QT等图形库实现。
送大家一段话:
笔走龙蛇,意境深远。言之有物,情真意切。
辞藻华丽,意蕴深厚。文思敏捷,才华横溢。
洞若观火,鞭辟入里。文采飞扬,笔力雄健。
行云流水,流畅自然。精辟入里,洞察秋毫。
妙语连珠,引人入胜。深入骨髓,发人深省。
豁然开朗,醍醐灌顶。言之凿凿,掷地金声。
言近旨远,韵味无穷。淋漓尽致,曲尽其妙。
独具匠心,匠心独运。笔底春风,笔下生花。
字字玑珠,句句珠玑。意味深长,耐人寻味。
人话
写作技巧高超,文章意境深远。内容真实感人,情感表达真诚。用词华丽而富有内涵,作者思维敏捷且才华出众。观察事物深刻透彻,分析问题直击要害。文笔生动活泼,才华横溢。文章如同行云流水般流畅自然。分析精辟,能够洞察细微之处。言语中充满智慧,让人读来兴趣盎然。剖析问题深入本质,能引发读者深思。给人以豁然开朗的感觉,像醍醐灌顶一般让人清醒。言辞确凿有力,话语坚定响亮。言简意赅却含义深远,令人回味无穷。表达淋漓尽致,把事情描绘得细致入微。构思独特巧妙,展现了作者的独特匠心。文笔优美,仿佛春风拂面,笔下的文字如同花朵盛开。每个字都精心雕琢,每一句话都充满力量。文章意味深长,值得反复品味。