贪吃蛇
2026-07-03 17:11:19
发布于:广东
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdlib>
#include <ctime>
using namespace std;
#define WIDTH 30
#define HEIGHT 20
enum Dir { STOP = 0, LEFT, RIGHT, UP, DOWN };
Dir dir;
int snakeX[200], snakeY[200];
int len;
int foodX, foodY;
int score;
int delay = 120;
DWORD startTime; // 游戏启动时间戳
void GotoXY(int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO ci;
ci.dwSize = 1;
ci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
}
void SpawnFood()
{
bool overlap;
do
{
overlap = false;
foodX = rand() % (WIDTH - 2) + 1;
foodY = rand() % (HEIGHT - 2) + 1;
for (int i = 0; i < len; i++)
{
if (snakeX[i] == foodX && snakeY[i] == foodY)
{
overlap = true;
break;
}
}
} while (overlap);
}
void Init()
{
dir = STOP;
len = 4;
snakeX[0] = WIDTH / 2;
snakeY[0] = HEIGHT / 2;
snakeX[1] = snakeX[0] - 1;
snakeY[1] = snakeY[0];
snakeX[2] = snakeX[0] - 2;
snakeY[2] = snakeY[0];
snakeX[3] = snakeX[0] - 3;
snakeY[3] = snakeY[0];
score = 0;
delay = 120;
SpawnFood();
startTime = GetTickCount(); // 重置本局计时起点
}
void Draw()
{
GotoXY(0, 0);
for (int i = 0; i < WIDTH; i++)
cout << "#";
cout << endl;
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
{
if (x == 0 || x == WIDTH - 1)
cout << "#";
else if (x == foodX && y == foodY)
cout << "●";
else
{
bool body = false;
for (int i = 0; i < len; i++)
{
if (snakeX[i] == x && snakeY[i] == y)
{
if (i == 0) cout << "■";
else cout << "□";
body = true;
break;
}
}
if (!body) cout << " ";
}
}
cout << endl;
}
for (int i = 0; i < WIDTH; i++)
cout << "#";
cout << endl;
// 计算用时,静止时计时清零显示0
int timeUsed = 0;
if (dir != STOP)
timeUsed = (GetTickCount() - startTime) / 1000;
cout << "分数:" << score << " | 用时:" << timeUsed << "秒 | 延迟:" << delay << "ms" << endl;
cout << "方向键↑↓←→控制 | Q退出游戏";
if (dir == STOP)
cout << " 提示:请按方向键开始游戏!";
}
void Input()
{
if (_kbhit())
{
int key = _getch();
if (key == 224)
{
key = _getch();
switch (key)
{
case 72: if(dir != DOWN) dir = UP; break;
case 80: if(dir != UP) dir = DOWN; break;
case 75: if(dir != RIGHT) dir = LEFT; break;
case 77: if(dir != LEFT) dir = RIGHT; break;
}
}
else if (key == 'q' || key == 'Q')
{
exit(0);
}
}
}
void Logic()
{
if(dir == STOP)
return;
// 身体跟随
for (int i = len - 1; i > 0; i--)
{
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
// 移动头部
switch (dir)
{
case LEFT: snakeX[0]--; break;
case RIGHT: snakeX[0]++; break;
case UP: snakeY[0]--; break;
case DOWN: snakeY[0]++; break;
default: break;
}
// 撞墙判定
if (snakeX[0] <= 0 || snakeX[0] >= WIDTH - 1 ||
snakeY[0] <= 0 || snakeY[0] >= HEIGHT - 1)
{
int t = (GetTickCount() - startTime) / 1000;
GotoXY(5, HEIGHT + 3);
cout << "撞到墙壁!本局用时:" << t << "秒,按任意键重新开始";
_getch();
system("cls");
Init();
return;
}
// 撞到自身
for (int i = 1; i < len; i++)
{
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i])
{
int t = (GetTickCount() - startTime) / 1000;
GotoXY(5, HEIGHT + 3);
cout << "撞到自身!本局用时:" << t << "秒,按任意键重新开始";
_getch();
system("cls");
Init();
return;
}
}
// 吃到食物
if (snakeX[0] == foodX && snakeY[0] == foodY)
{
score += 10;
len++;
SpawnFood();
if (delay > 40) delay -= 4;
}
}
int main()
{
HideCursor();
srand((unsigned)time(NULL));
Init();
while (true)
{
Draw();
Input();
Logic();
Sleep(delay);
}
return 0;
}
这里空空如也
















有帮助,赞一个