c++贪吃蛇代码500行
时间: 2023-10-14 15:14:42 浏览: 131
以下是一个基于C++的贪吃蛇代码,共计大约500行。代码中使用了Windows API库进行图形界面的实现,使用了链表数据结构来存储蛇的身体,同时使用了多线程来处理游戏逻辑和图形渲染。
```c++
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
#define WIDTH 60
#define HEIGHT 20
#define SNAKE_HEAD '*'
#define SNAKE_BODY 'O'
#define FOOD '$'
using namespace std;
// 食物结构体
struct Food {
int x, y;
};
// 蛇身结构体
struct SnakeBody {
int x, y;
SnakeBody* next;
};
// 蛇结构体
struct Snake {
SnakeBody* head;
SnakeBody* tail;
int length;
char direction;
};
// 游戏状态
enum GameState {
RUNNING,
PAUSED,
OVER
};
// 全局变量
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
HWND hWnd = GetConsoleWindow();
DWORD dwThreadId, dwThreadPriority;
Snake snake;
Food food;
GameState gameState = PAUSED;
bool isEaten = false;
int score = 0;
// 初始化游戏
void InitGame() {
// 初始化蛇
SnakeBody* body = new SnakeBody{ WIDTH / 2, HEIGHT / 2, nullptr };
snake.head = body;
snake.tail = body;
snake.length = 1;
snake.direction = 'D';
// 初始化食物
srand((unsigned)time(NULL));
food.x = rand() % WIDTH + 1;
food.y = rand() % HEIGHT + 1;
// 初始化游戏状态
gameState = RUNNING;
isEaten = false;
score = 0;
}
// 绘制地图
void DrawMap() {
system("cls");
for (int i = 0; i <= HEIGHT + 1; i++) {
for (int j = 0; j <= WIDTH + 1; j++) {
if (i == 0 || i == HEIGHT + 1 || j == 0 || j == WIDTH + 1) {
cout << "#";
}
else {
if (i == food.y && j == food.x) {
cout << FOOD;
}
else {
SnakeBody* p = snake.head;
bool isBody = false;
while (p != nullptr) {
if (p->x == j && p->y == i) {
cout << (isBody ? SNAKE_BODY : SNAKE_HEAD);
isBody = true;
}
p = p->next;
}
if (!isBody) {
cout << " ";
}
}
}
}
cout << endl;
}
cout << "Score: " << score << endl;
}
// 更新蛇的位置
void UpdateSnake() {
SnakeBody* newHead = new SnakeBody{ 0, 0, nullptr };
newHead->next = snake.head;
switch (snake.direction) {
case 'W':
newHead->y = snake.head->y - 1;
newHead->x = snake.head->x;
break;
case 'A':
newHead->y = snake.head->y;
newHead->x = snake.head->x - 1;
break;
case 'S':
newHead->y = snake.head->y + 1;
newHead->x = snake.head->x;
break;
case 'D':
newHead->y = snake.head->y;
newHead->x = snake.head->x + 1;
break;
}
snake.head = newHead;
// 判断是否吃到食物
if (newHead->x == food.x && newHead->y == food.y) {
isEaten = true;
score++;
food.x = rand() % WIDTH + 1;
food.y = rand() % HEIGHT + 1;
}
// 判断是否撞墙或撞到自己
SnakeBody* p = snake.head->next;
while (p != nullptr) {
if (p->x == newHead->x && p->y == newHead->y) {
gameState = OVER;
return;
}
p = p->next;
}
if (newHead->x == 0 || newHead->x == WIDTH + 1 || newHead->y == 0 || newHead->y == HEIGHT + 1) {
gameState = OVER;
return;
}
// 更新蛇的尾部
if (!isEaten) {
snake.tail = snake.tail->next;
}
else {
snake.length++;
isEaten = false;
}
}
// 处理键盘输入
void HandleInput() {
if (_kbhit()) {
char c = _getch();
switch (c) {
case 'W':
case 'w':
if (snake.direction != 'S') {
snake.direction = 'W';
}
break;
case 'A':
case 'a':
if (snake.direction != 'D') {
snake.direction = 'A';
}
break;
case 'S':
case 's':
if (snake.direction != 'W') {
snake.direction = 'S';
}
break;
case 'D':
case 'd':
if (snake.direction != 'A') {
snake.direction = 'D';
}
break;
case 'P':
case 'p':
gameState = PAUSED;
break;
case 'Q':
case 'q':
gameState = OVER;
break;
}
}
}
// 游戏线程
DWORD WINAPI GameThread(LPVOID lpParam) {
while (gameState == RUNNING) {
UpdateSnake();
DrawMap();
Sleep(100);
}
return 0;
}
// 消息循环线程
DWORD WINAPI MessageLoopThread(LPVOID lpParam) {
MSG msg;
while (GetMessage(&msg, hWnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// 主函数
int main() {
InitGame();
DrawMap();
// 创建游戏线程和消息循环线程
CreateThread(NULL, 0, GameThread, NULL, 0, &dwThreadId);
CreateThread(NULL, 0, MessageLoopThread, NULL, 0, &dwThreadId);
// 消息循环
while (gameState != OVER) {
HandleInput();
Sleep(10);
}
// 结束游戏
system("cls");
cout << "Game over!" << endl;
cout << "Your score: " << score << endl;
system("pause");
return 0;
}
```
阅读全文