ADD file via upload

main
pjvrmisk8 6 months ago
parent 8581c61bca
commit 046b9e0cb5

@ -0,0 +1,282 @@
#include<iostream>
using namespace std;
#include<easyx.h> //包含图形库头文件
#include<stdlib.h>
#include<time.h>
#define WIDTH 1040 //定义场景大小
#define HEIGHT 640
#define SIZE 20 //定义食物以及蛇的大小 一个格子的大小
#define UP 1 //定义蛇的朝向
#define DOWN -1
#define LEFT 2
#define RIGHT -2
#define MAX 2000 //蛇的最大长度
typedef struct
{
int x;
int y;
}SnakeNode;
SnakeNode temp[MAX]; //用另外一个数组来存储蛇原来的位置
int speed = 150; //蛇的速度
//创建蛇的类
class Snake
{
friend class Food;
public:
Snake(); //初始化
void Move(); //移动
void Draw(); //绘制蛇
bool Eat(Food food); //吃食物
bool Defeat(); //失败判定
private:
int dirt; //朝向
int length; //长度
SnakeNode node[MAX]; //蛇的坐标
};
//创建食物的类
class Food
{
friend class Snake;
public:
Food(Snake snake); //食物初始化
void Draw(); //绘制食物
private:
int x, y; //坐标
};
//蛇的初始化
Snake::Snake()
{
dirt = RIGHT;
length = 3;
//下标是0的位置为蛇的头部
for (int i = 0; i < length; i++)
{
node[i].x = 60 - ((i + 1) * SIZE);//坐标带上20
node[i].y = 0;
} //固定刚开始蛇的位置
//蛇一开始从屏幕的左上角出现
}
//移动
void Snake::Move()
{
for (int i = 0; i < length; i++) //将原来的蛇结点拷贝一份
{
temp[i].x = node[i].x;
temp[i].y = node[i].y;
}
int status = 0; //用来判断是否点击了转向按键
if (dirt == RIGHT) //四个方向,讨论现在的方向,分别判断是否转向,不能反向。
{
//判断是否转向
if (GetAsyncKeyState('W') && status == 0) //捕捉键盘输入为weasyx 判断转向
{
dirt = UP; //去了if(dirt==up)的else
status = 1;
}
else if (GetAsyncKeyState('S') && status == 0)
{
dirt = DOWN;
status = 1;
}
else
{
node[0].x = node[0].x + SIZE;
}
}
if (dirt == DOWN)
{
//判断是否转向
if (GetAsyncKeyState('A') && status == 0)
{
dirt = LEFT;
status = 1;
}
else if (GetAsyncKeyState('D') && status == 0)
{
node[0].x = node[0].x + SIZE;
dirt = RIGHT;
status = 1;
}
else
{
node[0].y = node[0].y + SIZE;
}
}
if (dirt == LEFT)
{
//判断是否转向
if (GetAsyncKeyState('W') && status == 0)
{
dirt = UP;
status = 1;
}
else if (GetAsyncKeyState('S') && status == 0)
{
node[0].y = node[0].y + SIZE;
dirt = DOWN;
status = 1;
}
else
{
node[0].x -= SIZE;
}
}
if (dirt == UP)
{
//判断是否转向
if (GetAsyncKeyState('A') && status == 0)
{
node[0].x = node[0].x - SIZE;
dirt = LEFT;
status = 1;
}
else if (GetAsyncKeyState('D') && status == 0)
{
node[0].x = node[0].x + SIZE;
dirt = RIGHT;
status = 1;
}
else
{
node[0].y = node[0].y - SIZE;
//改变坐标
}
}
//移动
for (int i = 1; i < length; i++)
{
node[i].x = temp[i - 1].x;
node[i].y = temp[i - 1].y;
}
Sleep(speed); //休眠这么长时间,停顿一下
}
//绘制蛇
void Snake::Draw()
{
cleardevice(); //清空原先的绘图
srand((unsigned)time(NULL)); //设置颜色随机数setfillcolor)时用
for (int i = 0; i < length; i++)
{
setfillcolor(RGB(rand() % 256, rand() % 256, rand() % 256)); //五颜六色的蛇
fillrectangle(node[i].x, node[i].y, node[i].x + SIZE, node[i].y + SIZE);
}
}
//吃食物
bool Snake::Eat(Food food)
{
if (food.x == node[0].x && food.y == node[0].y) //头有没有碰到食物
{
if (node[length - 1].x - node[length - 2].x == 0 && node[length - 1].y - node[length - 2].y == -20)
{
//判断蛇尾巴的方向(数组最后两个点的位置关系),新点加在尾巴后面
length++;
node[length - 1].x = node[length - 2].x;
node[length - 1].y = node[length - 2].y - SIZE;
}
else if (node[length - 1].x - node[length - 2].x == 0 && node[length - 1].y - node[length - 2].y == 20)
{
length++;
node[length - 1].x = node[length - 2].x;
node[length - 1].y = node[length - 2].y + SIZE;
}
else if (node[length - 1].x - node[length - 2].x == 20 && node[length - 1].y - node[length - 2].y == 0)
{
length++;
node[length - 1].x = node[length - 2].x + SIZE;
node[length - 1].y = node[length - 2].y;
}
else if (node[length - 1].x - node[length - 2].x == -20 && node[length - 1].y - node[length - 2].y == 0)
{
length++;
node[length - 1].x = node[length - 2].x - SIZE;
node[length - 1].y = node[length - 2].y;
}
return true;
}
return false;
}
//失败判定
bool Snake::Defeat()
{
//碰到边界
if (node[0].x < 0 || node[0].x >= WIDTH || node[0].y < 0 || node[0].y >= HEIGHT)
return true;
//碰到自己的身体
for (int i = 1; i < length; i++)
{
if (node[0].x == node[i].x && node[0].y == node[i].y)
return true;
}
return false;
}
//食物的初始化
Food::Food(Snake snake)
{
table:
srand((unsigned)time(NULL)); //设计随机种子,产生随机数
x = (rand() % (WIDTH / SIZE)) * SIZE;
y = (rand() % (HEIGHT / SIZE)) * SIZE;
for (int i = 0; i < snake.length; i++)
{
if (snake.node[i].x == x && snake.node[i].y == y)
goto table; //如果食物在蛇身上,则重新初始化
}
}
//绘制食物
void Food::Draw()
{
setfillcolor(GREEN); //食物是绿色
fillrectangle(x, y, x + SIZE, y + SIZE); //绘制食物为矩形,四个顶点坐标。
}
int main()
{
initgraph(WIDTH, HEIGHT);
Snake snake;
table:
Food food(snake);
while (1)
{
BeginBatchDraw();
FlushBatchDraw(); //双缓冲,防止屏幕一闪一闪的
snake.Draw();
food.Draw();
FlushBatchDraw(); //双缓冲,防止屏幕一闪一闪的
EndBatchDraw();
/*双缓冲,防止屏幕一闪一闪的*/
if (snake.Eat(food))
{
goto table; //如果吃到食物,就再设置一个食物
}
if (snake.Defeat())
{
break;
}
snake.Move();
}
HWND window = GetHWnd(); //弹窗,提示游戏失败
SetWindowText(window, L"提示"); //修改窗口标题,设置成提示
MessageBox(window, L"游戏失败", L"提示", MB_OKCANCEL);
//提示失败信息 MB_OKCANCEL下面有两个按键确定或取消
return 0;
}
Loading…
Cancel
Save