传统的贪吃蛇小游戏
2020-7-15
(0)
说明
这是一个传统的贪吃蛇小游戏,使用 a、s、d、w 四个按键控制蛇的移动,不要让蛇头碰到边界,也不要让蛇头碰到自己的身体。每吃一个食物就会长一节身体。第一次写的小程序,做的不好,请见谅。
效果图
游戏说明
键盘在小写模式下按 a、w、s、d 改变移动方向。
代码
/////////////////////////////////////////////////////////////
// 程序名称:贪吃蛇
// 编译环境:Visual Studio 2019, EasyX_20211109
// 作 者:心跳C<halt_233@qq.com>
// 最后修改:2020-7-15
//
// 头文件
#include <graphics.h>
#include <conio.h>
#include <ctime>
// 窗口大小
int windowX = 640, windowY = 480;
int FoodPosX()
{
// 定义随机数
srand((int)time(0));
int foodPosX;
foodPosX = (rand() % (windowX / 20 - 2) + 1) * 20 + 10;
return foodPosX;
}
int FoodPosY()
{
// 定义随机数
srand((int)time(0));
int foodPosY;
foodPosY = (rand() % (windowY / 20 - 2) + 1) * 20 + 10;
return foodPosY;
}
int main()
{
//
bool startGame = false;
// 颜色设定
COLORREF backgroundColor = RGB(10, 10, 10);
COLORREF limitColor = RGB(255, 150, 50);
COLORREF snakeColor = RGB(50, 250, 100);
COLORREF foodColor = RGB(255, 255, 255);
// 最大长度为沾满屏幕的所以格子
int snakeMaxLength = ((windowX / 20) - 1) * ((windowY / 20) - 1);
// 定义当前长度
int snakeLength;
// 食物坐标
int foodX, foodY;
// 蛇的坐标信息
int* snakeX = new int[snakeMaxLength];
int* snakeY = new int[snakeMaxLength];
// 蛇的朝向
int tower;
// 绘制边界的变量
int bjx, bjy;
// 获取当前操作的变量
char ch = 'd';
// 绘制窗口
initgraph(windowX, windowY);
setbkcolor(backgroundColor);
cleardevice();
// food 生成相关
bool foodCanPut = false;
reStrat:
// 定义初始长度,小于 (windowX / 2) - 2
snakeLength = 3;
// 定义初始坐标
for (int i = snakeLength - 1; i >= 0; i--)
{
snakeX[i] = 30 + 20 * (snakeLength - i - 1);
snakeY[i] = 70;
}
// 定义初始朝向
tower = 4;
// 设定初始食物坐标
foodX = FoodPosX();
foodY = FoodPosY();
while (foodCanPut == false)
{
for (int i = 0; i < snakeLength; i++)
{
if (foodX != snakeX[i] || foodY != snakeX[i])
{
foodCanPut = true;
}
else if (foodX == snakeX[i] && foodY == snakeX[i])
{
foodX = FoodPosX();
foodY = FoodPosY();
foodCanPut = false;
}
}
}
// 开始菜单
settextstyle(20, 0, _T("Consolas"));
cleardevice();
outtextxy(windowX / 2 - 50, windowY / 2, _T("按任意键继续开始"));
system("pause");
cleardevice();
// 绘制边界
setlinecolor(limitColor);
for (int i = 10; i <= windowX - 10; i += 20)
{
bjx = i;
if (i == 10 || i == windowX - 10)
{
for (int j = 10; j <= windowY - 10; j += 20)
{
bjy = j;
rectangle(bjx - 9, bjy - 9, bjx + 9, bjy + 9);
}
}
rectangle(bjx - 9, bjy - 9, bjx + 9, bjy + 9);
rectangle(bjx - 9, 10 - 9, bjx + 9, 10 + 9);
Sleep(windowX / 20);
}
// 倒计时动画
settextstyle(72, 0, _T("Consolas"));
outtextxy(windowX / 2 - 10, windowY / 2 - 40, _T("3"));
Sleep(1000);
clearrectangle(20, 20, windowX - 20, windowY - 20);
outtextxy(windowX / 2 - 10, windowY / 2 - 40, _T("2"));
Sleep(1000);
clearrectangle(20, 20, windowX - 20, windowY - 20);
outtextxy(windowX / 2 - 10, windowY / 2 - 40, _T("1"));
Sleep(1000);
clearrectangle(20, 20, windowX - 20, windowY - 20);
settextstyle(20, 0, _T("Consolas"));
int ctrl = 0;
// 游戏主体
while (1)
{
if (_kbhit())
{
ch = _getch();
}
ctrl++;
while (ctrl > 100)
{
ctrl = 0;
// 清理除边界外的所有
clearrectangle(20, 20, windowX - 20, windowY - 20);
// 目前方向
switch (ch)
{
case 'a':
if (tower != 4)
{
tower = 1;
}
break;
case 'w':
if (tower != 3)
{
tower = 2;
}
break;
case 's':
if (tower != 2)
{
tower = 3;
}
break;
case 'd':
if (tower != 1)
{
tower = 4;
}
break;
default:
break;
}
// 判定吃食物
if (snakeX[0] == foodX && snakeY[0] == foodY)
{
snakeLength++;
foodX = FoodPosX();
foodY = FoodPosY();
while (foodCanPut == false)
{
for (int i = 0; i < snakeLength; i++)
{
if (foodX != snakeX[i] || foodY != snakeX[i])
{
foodCanPut = true;
}
else if (foodX == snakeX[i] && foodY == snakeX[i])
{
foodX = FoodPosX();
foodY = FoodPosY();
foodCanPut = false;
}
}
}
}
// 计算尾巴坐标
for (int i = snakeLength - 1; i >= 0; i--)
{
if (i != 0)
{
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
}
// 蛇头坐标
switch (tower)
{
case 1:
snakeX[0] -= 20;
break;
case 2:
snakeY[0] -= 20;
break;
case 3:
snakeY[0] += 20;
break;
case 4:
snakeX[0] += 20;
break;
}
// 判断撞身体
for (int i = 0; i < snakeLength; i++)
{
if (i != 0 && snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0])
{
snakeX[0] = 10;
}
}
// 结束菜单
if (snakeLength == snakeMaxLength)
{
outtextxy(windowX / 2 - 50, windowY / 2 + 20, _T("胜利!"));
outtextxy(windowX / 2 - 50, windowY / 2, _T("按任意键继续"));
system("pause");
cleardevice();
outtextxy(windowX / 2 - 50, (windowY / 2) - 10, _T("按“Y”重玩"));
outtextxy(windowX / 2 - 50, (windowY / 2) + 10, _T("按“N”结束"));
while (1)
{
ch = _getch();
if (ch == 'y' || ch == 'Y')
{
goto reStrat;
}
else if (ch == 'n' || ch == 'N')
{
goto endGame;
}
}
}
// 判断撞墙
if (snakeX[0] >= windowX - 10 || snakeX[0] <= 10 || snakeY[0] >= windowY - 10 || snakeY[0] <= 10)
{
cleardevice();
outtextxy(windowX / 2 - 35, windowY / 2 - 20, _T("你失败了"));
outtextxy(windowX / 2 - 50, windowY / 2, _T("按任意键继续"));
system("pause");
cleardevice();
outtextxy(windowX / 2 - 50, (windowY / 2) - 10, _T("按“Y”重玩"));
outtextxy(windowX / 2 - 50, (windowY / 2) + 10, _T("按“N”结束"));
while (1)
{
ch = _getch();
if (ch == 'y' || ch == 'Y')
{
goto reStrat;
}
else if (ch == 'n' || ch == 'N')
{
goto endGame;
}
}
}
BeginBatchDraw();
// 绘制食物
setlinecolor(foodColor);
rectangle(foodX - 8, foodY - 8, foodX + 8, foodY + 8);
// 绘制蛇
setlinecolor(snakeColor);
for (int i = 0; i < snakeLength; i++)
{
rectangle(snakeX[i] - 8, snakeY[i] - 8, snakeX[i] + 8, snakeY[i] + 8);
}
EndBatchDraw();
// 速度
Sleep(100);
}
}
endGame:
delete[] snakeX;
delete[] snakeY;
return 0;
}
添加评论
取消回复