C++ 贪吃蛇 Greedy Snake
代码整体功能概述
此代码构建了一个简易的控制台贪吃蛇游戏。游戏中,玩家借助 w
、s
、a
、d
键来操控蛇的移动方向,目标是让蛇吃到随机出现在游戏区域内的水果,每吃到一个水果,蛇的身体会增长一节,同时玩家得分增加 10 分。若蛇撞到边界或者自身身体,游戏就会结束。
各部分代码详细解析
1. 全局变量和枚举类型定义
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
gameOver
:用于标记游戏是否结束。width
和height
:定义游戏区域的宽度和高度。x
和y
:代表蛇头的坐标。fruitX
和fruitY
:表示水果的坐标。score
:记录玩家的得分。tailX
和tailY
:数组,用于存储蛇身体各节的坐标。nTail
:记录蛇身体的节数。eDirection
枚举类型:定义蛇的移动方向,包含停止、左、右、上、下。dir
:存储当前蛇的移动方向。
2. Setup
函数
void Setup() {gameOver = false;dir = STOP;x = width / 2;y = height / 2;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;score = 0;
}
- 该函数用于初始化游戏状态,把
gameOver
设为false
,蛇的初始移动方向设为停止,将蛇头置于游戏区域中央,随机生成水果的初始位置,并且把得分初始化为 0。
3. Draw
函数
void Draw() {system("cls");for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {if (j == 0)cout << "#";if (i == y && j == x)cout << "O";else if (i == fruitY && j == fruitX)cout << "F";else {bool print = false;for (int k = 0; k < nTail; k++) {if (tailX[k] == j && tailY[k] == i) {cout << "o";print = true;}}if (!print)cout << " ";}if (j == width - 1)cout << "#";}cout << endl;}for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;cout << "Score:" << score << endl;
}
- 此函数用于绘制游戏界面,先清屏,接着绘制游戏区域的边界,然后在相应位置绘制蛇头、水果以及蛇的身体,最后输出当前得分。
4. Input
函数
void Input() {if (_kbhit()) {switch (_getch()) {case 'a':dir = LEFT;break;case 'd':dir = RIGHT;break;case 'w':dir = UP;break;case 's':dir = DOWN;break;case 'x':gameOver = true;break;}}
}
- 该函数用于处理用户输入,当用户按下按键时,依据按键的不同改变蛇的移动方向,若按下
x
键,则结束游戏。
5. Logic
函数
void Logic() {int prevX = tailX[0];int prevY = tailY[0];int prev2X, prev2Y;tailX[0] = x;tailY[0] = y;for (int i = 1; i < nTail; i++) {prev2X = tailX[i];prev2Y = tailY[i];tailX[i] = prevX;tailY[i] = prevY;prevX = prev2X;prevY = prev2Y;}switch (dir) {case LEFT:x--;break;case RIGHT:x++;break;case UP:y--;break;case DOWN:y++;break;default:break;}// 撞到边界游戏结束if (x >= width || x < 0 || y >= height || y < 0)gameOver = true;// 撞到自己身体游戏结束for (int i = 0; i < nTail; i++)if (tailX[i] == x && tailY[i] == y)gameOver = true;if (x == fruitX && y == fruitY) {score += 10;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;nTail++;}
}
- 该函数实现游戏的核心逻辑:
- 先更新蛇身体各节的坐标。
- 依据当前蛇的移动方向更新蛇头的坐标。
- 检查蛇是否撞到边界或者自身身体,若撞到则游戏结束。
- 检查蛇头是否与水果的位置重合,若重合则得分增加 10 分,随机生成新的水果位置,并且蛇的身体增长一节。
6. main
函数
int main() {Setup();while (!gameOver) {Draw();Input();Logic();Sleep(100);}return 0;
}
- 这是程序的入口函数,先调用
Setup
函数初始化游戏,接着进入游戏主循环,在循环里不断调用Draw
函数绘制界面、Input
函数处理用户输入、Logic
函数更新游戏逻辑,每次循环之间暂停 100 毫秒,直到游戏结束。
总结
这段代码借助控制台实现了一个简单的贪吃蛇游戏,包含游戏初始化、界面绘制、用户输入处理以及游戏逻辑更新等功能。不过,代码还存在一些可以优化的地方,例如可以添加音效、优化界面显示、增加游戏难度等。
作者好久没更新了,这次更新给个赞吧~
代码
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
using namespace std;bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;void Setup() {gameOver = false;dir = STOP;x = width / 2;y = height / 2;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;score = 0;
}void Draw() {system("cls");for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {if (j == 0)cout << "#";if (i == y && j == x)cout << "O";else if (i == fruitY && j == fruitX)cout << "F";else {bool print = false;for (int k = 0; k < nTail; k++) {if (tailX[k] == j && tailY[k] == i) {cout << "o";print = true;}}if (!print)cout << " ";}if (j == width - 1)cout << "#";}cout << endl;}for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;cout << "Score:" << score << endl;
}void Input() {if (_kbhit()) {switch (_getch()) {case 'a':dir = LEFT;break;case 'd':dir = RIGHT;break;case 'w':dir = UP;break;case 's':dir = DOWN;break;case 'x':gameOver = true;break;}}
}void Logic() {int prevX = tailX[0];int prevY = tailY[0];int prev2X, prev2Y;tailX[0] = x;tailY[0] = y;for (int i = 1; i < nTail; i++) {prev2X = tailX[i];prev2Y = tailY[i];tailX[i] = prevX;tailY[i] = prevY;prevX = prev2X;prevY = prev2Y;}switch (dir) {case LEFT:x--;break;case RIGHT:x++;break;case UP:y--;break;case DOWN:y++;break;default:break;}// 撞到边界游戏结束if (x >= width || x < 0 || y >= height || y < 0)gameOver = true;// 撞到自己身体游戏结束for (int i = 0; i < nTail; i++)if (tailX[i] == x && tailY[i] == y)gameOver = true;if (x == fruitX && y == fruitY) {score += 10;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;nTail++;}
}int main() {Setup();while (!gameOver) {Draw();Input();Logic();Sleep(100);}return 0;
}