C语言游戏实战(11):贪吃蛇大作战(多人对战)
成果展示:
贪吃蛇(多人对战)
前言:
这款贪吃蛇大作战是一款多人游戏,玩家需要控制一条蛇在地图上移动,吞噬其他蛇或者食物来增大自己的蛇身长度和宽度。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。
在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:
1. 游戏界面:游戏界面是一个矩形区域,玩家可以在这个区域内控制蛇的移动。
2. 玩家贪吃蛇:玩家控制的小球可以在游戏界面内自由移动,按下空格键可以加速。
3. ai贪吃蛇:ai贪吃蛇会在游戏界面中随机移动。
4. 食物:食物会在游戏界面中随机生成一定的数量,贪吃蛇通过吃食物可以增加蛇的长度和宽度。
5. 贪吃蛇的淘汰:当某条贪吃蛇的头部碰到了其他蛇的尾部或游戏界面的边界,这条蛇就会立马死亡,并且在死亡的地方身体变为食物。
接下来,我们将通过以下几个步骤来实现这个游戏:
1. 初始化游戏基本要素的信息。
2. 处理键盘输入,实现玩家控制贪吃蛇的移动和加速。
3. 控制ai贪吃蛇的移动。
4. 检测贪吃蛇吞噬食物,并增加相应的长度和宽度。
5. 检测贪吃蛇的死亡。
通过学习这个游戏的开发过程,初学者将能够掌握C语言编程和easyx图形库的基本技巧。
1. 初始化基本要素的信息
这款游戏的主要要素有:蛇头、蛇身、食物,而蛇头又分为ai蛇头,与玩家1蛇头,蛇身分为ai蛇身,与玩家1蛇身,其中这些要素都是圆或者由圆组成的,而圆基本特点有半径、颜色、坐标,所以我们需要创建一个包含这几个特点的结构体。
struct ball
{int x;int y;float r;//存放颜色的变量DWORD color;
};
(1)初始化玩家贪吃蛇的信息
开始游戏的时候设置玩家1的位置为(Wide / 2,Hight / 2)(这个可以根据自己的意愿设置),然后就是设置蛇尾的位置了,蛇尾是许多圆相连而成的,所以我们需要设置一个存放蛇尾信息的结构体数组,然后将蛇尾数组的中每个初始化的元素(圆)“连接”在头的右侧,也就是使这个数组中的每个元素的x坐标从头部的坐标开始依次减去一定的值,我们将这个值设为一个圆的直径大小即可。
struct ball player;
struct ball player_body[9999];//玩家1-头
player.x = Wide / 2;
player.y = Hight / 2;
player.r = 10;
//玩家1——蛇身
player_body[0].x = player.x - player.r;
player_body[0].y = player.y;
player_body[0].r = player.r;
(2)初始化食物的信息
食物就是一些半径为5的圆,利用随机值将它们的位置随机分布在游戏地图中。为了使食物的颜色不这么单一,所以颜色也利用随机数随机生成RGB的参数,从而随机生成食物的颜色。
RGB色彩模式是一种工业标准,它通过红(R)、绿(G)、蓝(B)三个颜色通道的组合来表示不同的颜色。每个通道通常分配一个0到255之间的数值,其中0表示该颜色通道没有亮度,255表示该颜色通道的最大亮度。通过调整这三个通道的值,可以生成几乎所有人类视觉系统能够感知的颜色。
//食物for (int i = 0; i < food_num; i++){food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);}
(3)初始化ai贪吃蛇的信息
ai的数量不止一条所以,ai的蛇头也不止一个,所以我们需要创建一个结构体数组在存放蛇头的信息,之后就是生成蛇尾,蛇尾的信息则需要我们创建一个二维结构体数组来存放。
struct ball Ai[Ai_num];
struct ball Ai_body[Ai_num][9999];//ai头
for (int i = 0; i < Ai_num; i++)
{Ai[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;
}
//ai身体
for (int i = 0; i < Ai_num; i++)
{Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int j = 1; j < Ai_body_num[i]; j++){Ai_body[i][j].x = Ai_body[i][j - 1].x - Ai_body[i][j - 1].r;Ai_body[i][j].y = Ai_body[i][j - 1].y;Ai_body[i][j].r = Ai_body[i][j - 1].r;}
}
2. 显示在窗口绘制出主要元素的信息
在easyx图形库中提供了一个画实心圆的函数—solidcircle函数,通过它我们就可以在窗口中显示圆了,但显示出的圆默认颜色为白色,要想得到不同颜色的圆,我们还需使用setfillcolor函数来改变圆的颜色。因为显示的函数、玩家操作小球的函数等函数都是放在同一个while循环重复执行的,这样就会重复绘制信息,所以我们还需要用到一个清屏函数cleardevice。为了使游戏界面更美观可以使用setbkcolor函数修改窗口的背景颜色,以及使用line函数在窗口中画一些线,函数setlinecolor可以改变线的颜色。
void show()
{srand((unsigned)time(NULL));SetWorkingImage(&map);//清屏函数cleardevice();setbkcolor(RGB(236, 236, 244));//划线颜色setlinecolor(RGB(222, 222, 230));//划线for (int i = 0; i < Wide_map; i += 20){line(i, 0, i, Hight_map);}for (int i = 0; i < Hight_map; i += 20){line(0, i, Wide_map, i);}//食物for (int i = 0; i < food_num; i++){setfillcolor(food[i].color );solidcircle(food[i].x, food[i].y, food[i].r);}//玩家1——蛇头setfillcolor(RED);solidcircle(player.x, player.y, player.r);//玩家1——蛇身for (int i = 0; i < body_num; i++){setfillcolor(RGB(149, 236, 105));solidcircle(player_body[i].x, player_body[i].y, player_body[i].r);}//ai蛇头for (int i = 0; i < Ai_num; i++){setfillcolor(RGB(229, 0, 0));solidcircle(Ai[i].x, Ai[i].y, Ai[i].r);}//ai蛇身for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_num[i]; j++){setfillcolor(RGB(229, 196, 0));solidcircle(Ai_body[i][j].x, Ai_body[i][j].y, Ai_body[i][j].r);}}//蛇尸体for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){setfillcolor(Ai_body_food[i][j].color );solidcircle(Ai_body_food[i][j].x, Ai_body_food[i][j].y, Ai_body_food[i][j].r);}}}
3. 玩家控制贪吃蛇移动
控制蛇的移动分为两步进行操作,一步是玩家控值蛇头的移动,另一步则是蛇尾跟随蛇头的移动。
(1)玩家控制蛇头的移动
在这里需要用到GetAsyncKeyState(vk virtual key)函数获取异步按键状态,其中vk virtual key是虚拟键值,如果接受到这个虚拟键值,它会返回真。0x20、0x41、0x44、0x57、83分别是空格键、a、d、w、s的虚拟键值。
为了保持蛇运动的持续性,不管我们按不按移动键蛇头的坐标都是应该变化的即在游戏的每次循环中都是应该执行蛇头的x坐标+=一个值,蛇头的y坐标+=一个值这两个表达式的,其中这两个值等于蛇的移动速度大小,或者0,且这两个值不能同时为0。通过按键改变这两个值的正负号或者令其中一个值为零,则可以改变蛇头移动的方向
//蛇速度
int player_speed = 10;int playerSpeedCol = 0;
int playerSpeedRow = 0;void Player_move1()
{//蛇头移动//玩家1//上左if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x41)){playerSpeedCol = -player_speed;playerSpeedRow = -player_speed;}//上右else if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x44)){playerSpeedCol = -player_speed;playerSpeedRow = player_speed;}//下右else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x44)){playerSpeedCol = player_speed;playerSpeedRow = player_speed;}//下左else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x41)){playerSpeedCol = player_speed;playerSpeedRow = -player_speed;}//左else if (GetAsyncKeyState(0x41)){playerSpeedRow = -player_speed;playerSpeedCol = 0;}//下else if (GetAsyncKeyState(83)){playerSpeedCol = player_speed;playerSpeedRow = 0;}//右else if (GetAsyncKeyState(0x44)){playerSpeedRow = player_speed;playerSpeedCol = 0;}//上else if (GetAsyncKeyState(0x57)){playerSpeedCol = -player_speed;playerSpeedRow = 0;}//加速if (GetAsyncKeyState(0x20)){if (playerSpeedRow > 0)playerSpeedRow = player_speed + 5;if (playerSpeedCol > 0)playerSpeedCol = player_speed + 5;if (playerSpeedRow < 0)playerSpeedRow = -player_speed - 5;if (playerSpeedCol < 0)playerSpeedCol = -player_speed - 5;}else{if (playerSpeedRow > 0)playerSpeedRow = player_speed;if (playerSpeedCol > 0)playerSpeedCol = player_speed;if (playerSpeedRow < 0)playerSpeedRow = -player_speed;if (playerSpeedCol < 0)playerSpeedCol = -player_speed;}//尾部处理int m = player.x;int n = player.y;player.x += playerSpeedRow;player.y += playerSpeedCol;int x = player_body[0].x;int y = player_body[0].y;player_body[0].x = m;player_body[0].y = n;for (int i = 1; i < body_num; i++){int a, b;if (i % 2 == 1){a = player_body[i].x;b = player_body[i].y;player_body[i].x = x;player_body[i].y = y;}else{x = player_body[i].x;y = player_body[i].y;player_body[i].x = a;player_body[i].y = b;}}
}
(2)蛇尾跟随蛇头
蛇头移动后,蛇尾圆1(也就紧贴蛇头的蛇尾圆)则移动到蛇头移动前的位置,然后蛇尾圆2(也就是紧贴蛇尾圆1的蛇尾圆)则移动到蛇尾1移动前的位置,按照这种方式移动最终将所有的蛇尾圆移动完后,就完成了蛇尾的移动了。具体操作是蛇尾圆1移动前,我们需要用两个变量m,n将蛇尾圆1的x,y值(坐标值)记录下来,然后再用两个变量a,b将蛇尾圆2移动前的坐标值记录下来,最后将m、n的值传递给蛇尾圆2,这样就完成了蛇尾圆2的移动,移动完蛇尾圆2后m、n这两个变量就空了下来,就可以让这两个值记录下一个要移动的圆的坐标,然后重复上面的移动就可以移动完整个蛇尾了,所以整个蛇尾移动的过程中我们只需要设置四个变量就可以了。
4. 地图与玩家视角的设置
由于窗口的大小有限,要想增加游戏的活动面积,我们可以使用IMAGE map(Wide_map, Hight_map) (其中 Wide_map 代表图像的宽度,而 Hight_map 代表图像的高度)创建一个地图。
创建完地图后使用SetWorkingImage(&map)函数,将map的地址作为参数传递给SetWorkingImage函数。这个函数的作用是将map作为当前操作的对象,以便在后续的图像处理过程中使用。最后使用putimage(0, 0, Wide, Hight, &map, x, y) 将地址绘制到窗口上,其中要让玩家小球始终出现在窗口的中央位置,那么其中的x=player.x - (Wide / 2);y=player.y - (Hight / 2);但是单单这样写就会出现窗口越界的情况,所以我们还需要限制x和y的范围:
putimage(0, 0, Wide, Hight, &map, x, y) 这个函数调用是用于在屏幕上的特定位置绘制或显示一个图像。下面是对这个函数调用中各个参数的具体解释:(0, 0):这是图像要绘制的目标位置的左上角坐标,即x=0和y=0,通常表示屏幕的左上角。
Wide:这个参数指定了要绘制的图像的宽度。
Hight:这个参数指定了要绘制的图像的高度。
&map:这是一个指向图像内存地址的指针,该图像将被绘制到屏幕上。在这个上下文中,map可能是一个包含了图像数据的数据结构或数组。
x:这个参数通常指定了要开始绘制图像的起始点的x坐标(在图像数据中)。
y:这个参数通常指定了要开始绘制图像的起始点的y坐标(在图像数据中)。
//玩家1视角int x = player.x - (Wide / 2) ;int y = player.y - (Hight / 2);//防止窗口越界if (x < -Wide / 4){x = -Wide / 4;}if (y < 0){y = 0;}if (x > Wide_map - Wide){x = Wide_map - Wide;}if (y > Hight_map - Hight){y = Hight_map - Hight;}//在地图上绘制字体settextcolor(RGB(7, 19, 62));TCHAR buffer[50];TCHAR buffer1[50];swprintf_s(buffer, _T("%d"), score);swprintf_s(buffer1, _T("%d"), kill);setbkmode(TRANSPARENT);settextstyle(20, 0, _T("宋体"));outtextxy(player.x, player.y - player.r * 4 - 20, _T("长度:"));outtextxy(player.x + 50, player.y - player.r * 4 - 20, buffer);outtextxy(player.x, player.y - player.r * 4, _T("击杀:"));outtextxy(player.x + 50, player.y - player.r * 4, buffer1);SetWorkingImage();//把map输出到窗口上putimage(0, 0, Wide / 2, Hight, &map, x + Wide / 4, y);
5. ai贪吃蛇的移动
在这里ai贪吃蛇移动主要有三个特点:
(1)一般情况下,ai贪吃蛇是随机移动的,具体操作为:
蛇在移动的时候无非就只有八种方向:上左、上右、上、下、下左、下右、左、右,这时我们就可以用rand函数得到0-7的随机,每一个随机数对应一种移动方向,这样就完成了蛇的随机移动。
(2)当ai贪吃蛇蛇头靠近玩家的蛇尾时会远离蛇尾,具体操作为:
为了判断蛇头是否靠近了蛇尾,我们需要先写一个计算不同的两个圆的圆心距的函数,来计算蛇头与蛇尾圆之间的距离。而两圆的圆心距就是两圆的圆心坐标的x相减的平方加上y相减的平方再开根号。其中开根号的函数为sqrt,它的头文件是<math.h>。
//距离
int Distance(int x, int y, int x1, int y1)
{return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
计算好距离后就可以判断是否靠近了,靠近了就远离,例如,如果蛇头的x坐标值小于玩家蛇尾圆的 x坐标值,也就是说ai蛇头在玩家蛇尾圆的左侧,要想远离这个玩家蛇尾圆我们ai蛇头就应该向左移动。
(3)当ai贪吃蛇蛇头靠近地图边界时会远离边界,具体步骤为:
方法同上。
//ai移动
void Ai_move()
{srand((unsigned)time(NULL));int count[Ai_num] = { 0 };for (int i = 0; i < Ai_num; i++){//随机移动count[i] = rand() % 8;//蛇头移动//上左if (count[i] == 0){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = -player_speed;}//上右else if (count[i] == 1){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = player_speed;}//下右else if (count[i] == 2){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = player_speed;}//下左else if (count[i] == 3){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = -player_speed;}//左else if (count[i] == 4){AiSpeedRow[i] = -player_speed;AiSpeedCol[i] = 0;}//下else if (count[i] == 5){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = 0;}//右else if (count[i] == 6){AiSpeedRow[i] = player_speed;AiSpeedCol[i] = 0;}//上else if (count[i] == 7){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = 0;}//ai不触碰边界if (Ai[i].x >= Wide_map - player_speed){//左AiSpeedRow[i] = -player_speed;}else if (Ai[i].y >= Hight_map - player_speed){//上AiSpeedCol[i] = -player_speed;}else if (Ai[i].y <= player_speed){//下AiSpeedCol[i] = player_speed;}else if (Ai[i].x <= player_speed){//右AiSpeedRow[i] = player_speed;}//ai躲避玩家1身体for (int j = 0; j < body_num; j++){if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20){//左if (Ai[i].x < player_body[j].x){AiSpeedRow[i] = -player_speed;}//上if (Ai[i].y < player_body[j].y){AiSpeedCol[i] = -player_speed;}//下if (Ai[i].x > player_body[j].x){AiSpeedCol[i] = player_speed;}//右if (Ai[i].y > player_body[j].y){AiSpeedRow[i] = player_speed;}}}//ai躲避玩家2身体for (int j = 0; j < body_num2; j++){if (Distance(player_body2[j].x, player_body2[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body2[i].r + 20){//左if (Ai[i].x < player_body2[j].x){AiSpeedRow[i] = -player_speed;}//上if (Ai[i].y < player_body2[j].y){AiSpeedCol[i] = -player_speed;}//下if (Ai[i].x > player_body2[j].x){AiSpeedCol[i] = player_speed;}//右if (Ai[i].y > player_body2[j].y){AiSpeedRow[i] = player_speed;}}}//尾部处理int m = Ai[i].x;int n = Ai[i].y;Ai[i].x += AiSpeedRow[i];Ai[i].y += AiSpeedCol[i];int x = Ai_body[i][0].x;int y = Ai_body[i][0].y;Ai_body[i][0].x = m;Ai_body[i][0].y = n;for (int j = 1; j < Ai_body_num[i]; j++){int a, b;if (j % 2 == 1){a = Ai_body[i][j].x;b = Ai_body[i][j].y;Ai_body[i][j].x = x;Ai_body[i][j].y = y;}else{x = Ai_body[i][j].x;y = Ai_body[i][j].y;Ai_body[i][j].x = a;Ai_body[i][j].y = b;}}}
}
6.检测贪吃蛇吞噬食物,并增加相应的长度和宽度。
当贪吃蛇靠近食物一定距离时,蛇尾圆的半径和数量就增加,然后被靠近的那个食物就重新生成,这样就完成了一次对食物的吞噬。
void eatfood()
{srand((unsigned)time(NULL));for (int i = 0; i < food_num; i++){//玩家1吃食物if (Distance(food[i].x, food[i].y, player.x, player.y) < player.r + food[i].r + player_speed){score += 3;player.r += 0.01;player_body[0].r = player.r;for (int j = 1; j < body_num; j++){player_body[j].r = player_body[j - 1].r;}food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;body_num += 1;player_body[body_num - 1].x = player_body[body_num - 2].x - player_body[body_num - 2].r;player_body[body_num - 1].y = player_body[body_num - 2].y;player_body[body_num - 1].r = player_body[body_num - 2].r;}//ai吃食物for (int j = 0; j < Ai_num; j++){if (Distance(food[i].x, food[i].y, Ai[j].x, Ai[j].y) <= Ai[i].r + food[i].r + player_speed * 3){Ai[j].r += 0.01;Ai_body[j][0].r = Ai[j].r;for (int z = 1; z < Ai_body_num[j]; z++){Ai_body[j][z].r = Ai_body[j][z - 1].r;}food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);Ai_body_num[j] += 1;Ai_body[j][Ai_body_num[j] - 1].x = Ai_body[j][Ai_body_num[j] - 2].x - Ai_body[j][Ai_body_num[j] - 2].r;Ai_body[j][Ai_body_num[j] - 1].y = Ai_body[j][Ai_body_num[j] - 2].y;Ai_body[j][Ai_body_num[j] - 1].r = Ai_body[j][Ai_body_num[j] - 2].r;}}}for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){//玩家1吃尸体if (Distance(Ai_body_food[i][j].x, Ai_body_food[i][j].y, player.x, player.y)< player.r + Ai_body_food[i][j].r + player_speed){int v = rand() % food_num;score += Ai_body_food[i][j].r / 5 * 3;player.r += Ai_body_food[i][j].r / 5 * 0.01;player_body[0].r = player.r;for (int z = 1; z < body_num; z++){player_body[z].r = player_body[z - 1].r;}Ai_body_food[i][j].x = food[v].x;Ai_body_food[i][j].y = food[v].y;Ai_body_food[i][j].r = food[v].r;Ai_body_food[i][j].color = food[v].color;body_num += Ai_body_food[i][j].r / 5;player_body[body_num - 1].x = player_body[body_num - 2].x - player_body[body_num - 2].r;player_body[body_num - 1].y = player_body[body_num - 2].y;player_body[body_num - 1].r = player_body[body_num - 2].r;}}}//ai吃尸体for (int p = 0; p < Ai_num; p++){for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){if (Distance(Ai_body_food[i][j].x, Ai_body_food[i][j].y, Ai[p].x, Ai[p].y) <Ai[p].r + Ai_body_food[i][j].r + player_speed){int v = rand() % food_num;Ai[p].r += Ai_body_food[i][j].r / 5 * 0.01;Ai_body[p][0].r = Ai[p].r;for (int z = 1; z < Ai_body_num[p]; z++){Ai_body[p][z].r = Ai_body[p][z - 1].r;}Ai_body_food[i][j].x = food[v].x;Ai_body_food[i][j].y = food[v].y;Ai_body_food[i][j].r = food[v].r;Ai_body_food[i][j].color = food[v].color;Ai_body_num[p] += Ai_body_food[i][j].r / 5;Ai_body[p][Ai_body_num[p] - 1].x = Ai_body[p][Ai_body_num[p] - 2].x - Ai_body[p][Ai_body_num[p] - 2].r;Ai_body[p][Ai_body_num[p] - 1].y = Ai_body[p][Ai_body_num[p] - 2].y;Ai_body[p][Ai_body_num[p] - 1].r = Ai_body[p][Ai_body_num[p] - 2].r;}}}}
}
7. 检测贪吃蛇的死亡。
蛇头碰到别蛇的蛇尾后,该蛇的身体变为尸体,同时重新生成这条蛇。这里我们需要在创建一个结构体数组来专门存放蛇尸体的信息,数组中的每个元素对应着唯一的一条蛇,蛇死了这条蛇的信息就传给放尸体的数组,如果尸体被吃了,就变成食物随机分布在整个游戏界面。
void SnakeOut()
{//玩家1碰到边界if (player.x > Wide_map || player.x <0 || player.y >Hight_map || player.y < 0){body_num = 5;score = 100;kill = 0;//蛇player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}}for (int i = 0; i < Ai_num; i++){//ai碰到边界if (Ai[i].x > Wide_map || Ai[i].x <0 || Ai[i].y >Hight_map || Ai[i].y < 0){//身体变成食物Ai_body_food_num[i] = Ai_body_num[i];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}Ai[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int j = 1; j < Ai_body_num[i]; j++){Ai_body[i][j].x = Ai_body[i][j - 1].x - Ai_body[i][j - 1].r;Ai_body[i][j].y = Ai_body[i][j - 1].y;Ai_body[i][j].r = Ai_body[i][j - 1].r;}}//ai碰玩家1蛇尾for (int j = 0; j < body_num; j++){if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r){kill += 1;//尾部变成食物Ai_body_food_num[i] = Ai_body_num[i];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}//重新生成aiAi[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int z = 1; z < Ai_body_num[i]; z++){Ai_body[i][z].x = Ai_body[i][z - 1].x - Ai_body[i][z - 1].r;Ai_body[i][z].y = Ai_body[i][z - 1].y;Ai_body[i][z].r = Ai_body[i][z - 1].r;}}}//玩家1碰ai蛇尾for (int j = 0; j < Ai_body_num[i]; j++){if (Distance(Ai_body[i][j].x, Ai_body[i][j].y, player.x, player.y) < player.r + Ai_body[i][j].r){body_num = 5;score = 100;kill = 0;//蛇player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}}}}
}
8. 增加玩家
要想增加玩家就将玩家1的内容名字写改了然后重复写一遍就行了,想加几个玩家,就写重复写几遍,然后给每一个玩家都给一个视角就行了。
//玩家1视角
int x = player.x - (Wide / 2) ;
int y = player.y - (Hight / 2);//玩家2视角
int x2 = player2.x - (Wide / 2);
int y2 = player2.y - (Hight / 2);SetWorkingImage();//把map输出到窗口上
putimage(0, 0, Wide / 2, Hight, &map, x + Wide / 4, y);
putimage(Wide/2, 0, Wide/2, Hight, &map, x2 + Wide / 4, y2);
源码:
#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<math.h>#define Wide 1420
#define Hight 660
#define Wide_map Wide*5
#define Hight_map Hight*5
#define food_num 2000
#define Ai_num 98
#define Ai_num2 100
IMAGE map(Wide_map, Hight_map);
int player_speed = 10;
int body_num = 5;int body_num2 = 5;int playerSpeedCol = 0;
int playerSpeedRow = 0;int playerSpeedCol2 = 0;
int playerSpeedRow2 = 0;int AiSpeedCol[Ai_num] = { 0 };
int AiSpeedRow[Ai_num] = { 0 };
int Ai_body_num[Ai_num] = { 0 };
int Ai_body_food_num[Ai_num] = { 0 };int score = 100;
int kill = 0;int score2 = 100;
int kill2 = 0;struct ball
{int x;int y;float r;DWORD color;
};
struct ball player;
struct ball player2;
struct ball Ai[Ai_num];
struct ball food[food_num];
struct ball player_body[9999];
struct ball player_body2[9999];
struct ball Ai_body[Ai_num][9999];
struct ball Ai_body_food[Ai_num][9999];
void init()
{srand((unsigned)time(NULL));//玩家1-头player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//玩家1——蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}//玩家2-头player2.x = Wide;player2.y = Hight / 2;player2.r = 10;//玩家2——蛇身player_body2[0].x = player2.x - player2.r;player_body2[0].y = player2.y;player_body2[0].r = player2.r;for (int i = 1; i < body_num2; i++){player_body2[i].x = player_body2[i - 1].x - player_body2[i - 1].r;player_body2[i].y = player_body2[i - 1].y;player_body2[i].r = player_body2[i - 1].r;}//食物for (int i = 0; i < food_num; i++){food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);}//ai头for (int i = 0; i < Ai_num; i++){Ai[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;}//ai身体for (int i = 0; i < Ai_num; i++){Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int j = 1; j < Ai_body_num[i]; j++){Ai_body[i][j].x = Ai_body[i][j - 1].x - Ai_body[i][j - 1].r;Ai_body[i][j].y = Ai_body[i][j - 1].y;Ai_body[i][j].r = Ai_body[i][j - 1].r;}}
}
//距离
int Distance(int x, int y, int x1, int y1)
{return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
//玩家操作
void Player_move1()
{//蛇头移动//玩家1//上左if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x41)){playerSpeedCol = -player_speed;playerSpeedRow = -player_speed;}//上右else if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x44)){playerSpeedCol = -player_speed;playerSpeedRow = player_speed;}//下右else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x44)){playerSpeedCol = player_speed;playerSpeedRow = player_speed;}//下左else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x41)){playerSpeedCol = player_speed;playerSpeedRow = -player_speed;}//左else if (GetAsyncKeyState(0x41)){playerSpeedRow = -player_speed;playerSpeedCol = 0;}//下else if (GetAsyncKeyState(83)){playerSpeedCol = player_speed;playerSpeedRow = 0;}//右else if (GetAsyncKeyState(0x44)){playerSpeedRow = player_speed;playerSpeedCol = 0;}//上else if (GetAsyncKeyState(0x57)){playerSpeedCol = -player_speed;playerSpeedRow = 0;}//加速if (GetAsyncKeyState(0x20)){if (playerSpeedRow > 0)playerSpeedRow = player_speed + 5;if (playerSpeedCol > 0)playerSpeedCol = player_speed + 5;if (playerSpeedRow < 0)playerSpeedRow = -player_speed - 5;if (playerSpeedCol < 0)playerSpeedCol = -player_speed - 5;}else{if (playerSpeedRow > 0)playerSpeedRow = player_speed;if (playerSpeedCol > 0)playerSpeedCol = player_speed;if (playerSpeedRow < 0)playerSpeedRow = -player_speed;if (playerSpeedCol < 0)playerSpeedCol = -player_speed;}//尾部处理int m = player.x;int n = player.y;player.x += playerSpeedRow;player.y += playerSpeedCol;int x = player_body[0].x;int y = player_body[0].y;player_body[0].x = m;player_body[0].y = n;for (int i = 1; i < body_num; i++){int a, b;if (i % 2 == 1){a = player_body[i].x;b = player_body[i].y;player_body[i].x = x;player_body[i].y = y;}else{x = player_body[i].x;y = player_body[i].y;player_body[i].x = a;player_body[i].y = b;}}//玩家2//上左if (GetAsyncKeyState(VK_UP) && GetAsyncKeyState(VK_LEFT)){playerSpeedCol2 = -player_speed;playerSpeedRow2 = -player_speed;}//上右else if (GetAsyncKeyState(VK_UP) && GetAsyncKeyState(VK_RIGHT)){playerSpeedCol2 = -player_speed;playerSpeedRow2 = player_speed;}//下右else if (GetAsyncKeyState(VK_DOWN) && GetAsyncKeyState(VK_RIGHT)){playerSpeedCol2 = player_speed;playerSpeedRow2 = player_speed;}//下左else if (GetAsyncKeyState(VK_DOWN) && GetAsyncKeyState(VK_LEFT)){playerSpeedCol2 = player_speed;playerSpeedRow2 = -player_speed;}//左else if (GetAsyncKeyState(VK_LEFT)){playerSpeedRow2 = -player_speed;playerSpeedCol2 = 0;}//下else if (GetAsyncKeyState(VK_DOWN)){playerSpeedCol2 = player_speed;playerSpeedRow2 = 0;}//右else if (GetAsyncKeyState(VK_RIGHT)){playerSpeedRow2 = player_speed;playerSpeedCol2 = 0;}//上else if (GetAsyncKeyState(VK_UP)){playerSpeedCol2 = -player_speed;playerSpeedRow2 = 0;}//加速if (GetAsyncKeyState(0x4D)){if (playerSpeedRow2 > 0)playerSpeedRow2 = player_speed + 5;if (playerSpeedCol2 > 0)playerSpeedCol2 = player_speed + 5;if (playerSpeedRow2 < 0)playerSpeedRow2 = -player_speed - 5;if (playerSpeedCol2 < 0)playerSpeedCol2 = -player_speed - 5;}else{if (playerSpeedRow2 > 0)playerSpeedRow2 = player_speed;if (playerSpeedCol2 > 0)playerSpeedCol2 = player_speed;if (playerSpeedRow2 < 0)playerSpeedRow2 = -player_speed;if (playerSpeedCol2 < 0)playerSpeedCol2 = -player_speed;}//尾部处理int m2 = player2.x;int n2 = player2.y;player2.x += playerSpeedRow2;player2.y += playerSpeedCol2;int x2 = player_body2[0].x;int y2 = player_body2[0].y;player_body2[0].x = m2;player_body2[0].y = n2;for (int i = 1; i < body_num2; i++){int a, b;if (i % 2 == 1){a = player_body2[i].x;b = player_body2[i].y;player_body2[i].x = x2;player_body2[i].y = y2;}else{x2 = player_body2[i].x;y2 = player_body2[i].y;player_body2[i].x = a;player_body2[i].y = b;}}
}//ai移动
void Ai_move()
{srand((unsigned)time(NULL));int count[Ai_num] = { 0 };for (int i = 0; i < Ai_num; i++){//随机移动count[i] = rand() % 8;//蛇头移动//上左if (count[i] == 0){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = -player_speed;}//上右else if (count[i] == 1){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = player_speed;}//下右else if (count[i] == 2){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = player_speed;}//下左else if (count[i] == 3){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = -player_speed;}//左else if (count[i] == 4){AiSpeedRow[i] = -player_speed;AiSpeedCol[i] = 0;}//下else if (count[i] == 5){AiSpeedCol[i] = player_speed;AiSpeedRow[i] = 0;}//右else if (count[i] == 6){AiSpeedRow[i] = player_speed;AiSpeedCol[i] = 0;}//上else if (count[i] == 7){AiSpeedCol[i] = -player_speed;AiSpeedRow[i] = 0;}//ai不触碰边界if (Ai[i].x >= Wide_map - player_speed){//左AiSpeedRow[i] = -player_speed;}else if (Ai[i].y >= Hight_map - player_speed){//上AiSpeedCol[i] = -player_speed;}else if (Ai[i].y <= player_speed){//下AiSpeedCol[i] = player_speed;}else if (Ai[i].x <= player_speed){//右AiSpeedRow[i] = player_speed;}//ai躲避玩家1身体for (int j = 0; j < body_num; j++){if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20){//左if (Ai[i].x < player_body[j].x){AiSpeedRow[i] = -player_speed;}//上if (Ai[i].y < player_body[j].y){AiSpeedCol[i] = -player_speed;}//下if (Ai[i].x > player_body[j].x){AiSpeedCol[i] = player_speed;}//右if (Ai[i].y > player_body[j].y){AiSpeedRow[i] = player_speed;}}}//ai躲避玩家2身体for (int j = 0; j < body_num2; j++){if (Distance(player_body2[j].x, player_body2[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body2[i].r + 20){//左if (Ai[i].x < player_body2[j].x){AiSpeedRow[i] = -player_speed;}//上if (Ai[i].y < player_body2[j].y){AiSpeedCol[i] = -player_speed;}//下if (Ai[i].x > player_body2[j].x){AiSpeedCol[i] = player_speed;}//右if (Ai[i].y > player_body2[j].y){AiSpeedRow[i] = player_speed;}}}//尾部处理int m = Ai[i].x;int n = Ai[i].y;Ai[i].x += AiSpeedRow[i];Ai[i].y += AiSpeedCol[i];int x = Ai_body[i][0].x;int y = Ai_body[i][0].y;Ai_body[i][0].x = m;Ai_body[i][0].y = n;for (int j = 1; j < Ai_body_num[i]; j++){int a, b;if (j % 2 == 1){a = Ai_body[i][j].x;b = Ai_body[i][j].y;Ai_body[i][j].x = x;Ai_body[i][j].y = y;}else{x = Ai_body[i][j].x;y = Ai_body[i][j].y;Ai_body[i][j].x = a;Ai_body[i][j].y = b;}}}
}
void eatfood()
{srand((unsigned)time(NULL));for (int i = 0; i < food_num; i++){//玩家1吃食物if (Distance(food[i].x, food[i].y, player.x, player.y) < player.r + food[i].r + player_speed){score += 3;player.r += 0.01;player_body[0].r = player.r;for (int j = 1; j < body_num; j++){player_body[j].r = player_body[j - 1].r;}food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;body_num += 1;player_body[body_num - 1].x = player_body[body_num - 2].x - player_body[body_num - 2].r;player_body[body_num - 1].y = player_body[body_num - 2].y;player_body[body_num - 1].r = player_body[body_num - 2].r;}//玩家2吃食物if (Distance(food[i].x, food[i].y, player2.x, player2.y) < player2.r + food[i].r + player_speed){score2 += 3;player2.r += 0.01;player_body2[0].r = player2.r;for (int j = 1; j < body_num2; j++){player_body2[j].r = player_body2[j - 1].r;}food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;body_num2 += 1;player_body2[body_num2 - 1].x = player_body2[body_num2 - 2].x - player_body2[body_num2 - 2].r;player_body2[body_num2 - 1].y = player_body2[body_num2 - 2].y;player_body2[body_num2 - 1].r = player_body2[body_num2 - 2].r;}//ai吃食物for (int j = 0; j < Ai_num; j++){if (Distance(food[i].x, food[i].y, Ai[j].x, Ai[j].y) <= Ai[i].r + food[i].r + player_speed * 3){Ai[j].r += 0.01;Ai_body[j][0].r = Ai[j].r;for (int z = 1; z < Ai_body_num[j]; z++){Ai_body[j][z].r = Ai_body[j][z - 1].r;}food[i].x = rand() % Wide_map;food[i].y = rand() % Hight_map;food[i].r = 5;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);Ai_body_num[j] += 1;Ai_body[j][Ai_body_num[j] - 1].x = Ai_body[j][Ai_body_num[j] - 2].x - Ai_body[j][Ai_body_num[j] - 2].r;Ai_body[j][Ai_body_num[j] - 1].y = Ai_body[j][Ai_body_num[j] - 2].y;Ai_body[j][Ai_body_num[j] - 1].r = Ai_body[j][Ai_body_num[j] - 2].r;}}}for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){//玩家1吃尸体if (Distance(Ai_body_food[i][j].x, Ai_body_food[i][j].y, player.x, player.y)< player.r + Ai_body_food[i][j].r + player_speed){int v = rand() % food_num;score += Ai_body_food[i][j].r / 5 * 3;player.r += Ai_body_food[i][j].r / 5 * 0.01;player_body[0].r = player.r;for (int z = 1; z < body_num; z++){player_body[z].r = player_body[z - 1].r;}Ai_body_food[i][j].x = food[v].x;Ai_body_food[i][j].y = food[v].y;Ai_body_food[i][j].r = food[v].r;Ai_body_food[i][j].color = food[v].color;body_num += Ai_body_food[i][j].r / 5;player_body[body_num - 1].x = player_body[body_num - 2].x - player_body[body_num - 2].r;player_body[body_num - 1].y = player_body[body_num - 2].y;player_body[body_num - 1].r = player_body[body_num - 2].r;}//玩家2吃尸体if (Distance(Ai_body_food[i][j].x, Ai_body_food[i][j].y, player2.x, player2.y)< player2.r + Ai_body_food[i][j].r + player_speed){int v = rand() % food_num;score2 += Ai_body_food[i][j].r / 5 * 3;player2.r += Ai_body_food[i][j].r / 5 * 0.01;player_body2[0].r = player2.r;for (int z = 1; z < body_num2; z++){player_body2[z].r = player_body2[z - 1].r;}Ai_body_food[i][j].x = food[v].x;Ai_body_food[i][j].y = food[v].y;Ai_body_food[i][j].r = food[v].r;Ai_body_food[i][j].color = food[v].color;body_num2 += Ai_body_food[i][j].r / 5;player_body2[body_num2 - 1].x = player_body2[body_num2 - 2].x - player_body2[body_num2 - 2].r;player_body2[body_num2 - 1].y = player_body2[body_num2 - 2].y;player_body2[body_num2 - 1].r = player_body2[body_num2 - 2].r;}}}//ai吃尸体for (int p = 0; p < Ai_num; p++){for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){if (Distance(Ai_body_food[i][j].x, Ai_body_food[i][j].y, Ai[p].x, Ai[p].y) <Ai[p].r + Ai_body_food[i][j].r + player_speed){int v = rand() % food_num;Ai[p].r += Ai_body_food[i][j].r / 5 * 0.01;Ai_body[p][0].r = Ai[p].r;for (int z = 1; z < Ai_body_num[p]; z++){Ai_body[p][z].r = Ai_body[p][z - 1].r;}Ai_body_food[i][j].x = food[v].x;Ai_body_food[i][j].y = food[v].y;Ai_body_food[i][j].r = food[v].r;Ai_body_food[i][j].color = food[v].color;Ai_body_num[p] += Ai_body_food[i][j].r / 5;Ai_body[p][Ai_body_num[p] - 1].x = Ai_body[p][Ai_body_num[p] - 2].x - Ai_body[p][Ai_body_num[p] - 2].r;Ai_body[p][Ai_body_num[p] - 1].y = Ai_body[p][Ai_body_num[p] - 2].y;Ai_body[p][Ai_body_num[p] - 1].r = Ai_body[p][Ai_body_num[p] - 2].r;}}}}
}
void SnakeOut()
{//玩家1碰到边界if (player.x > Wide_map || player.x <0 || player.y >Hight_map || player.y < 0){body_num = 5;score = 100;kill = 0;//蛇player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}}//玩家2碰到边界if (player2.x > Wide_map || player2.x <0 || player2.y >Hight_map || player2.y < 0){body_num2 = 5;score2 = 100;kill2 = 0;//蛇player2.x = Wide;player2.y = Hight / 2;player2.r = 10;//蛇身player_body2[0].x = player2.x - player2.r;player_body2[0].y = player2.y;player_body2[0].r = player2.r;for (int i = 1; i < body_num2; i++){player_body2[i].x = player_body2[i - 1].x - player_body2[i - 1].r;player_body2[i].y = player_body2[i - 1].y;player_body2[i].r = player_body2[i - 1].r;}}//玩家1吃玩家2蛇尾for (int i = 0; i < body_num2; i++){if (Distance(player_body2[i].x, player_body2[i].y, player.x, player.y) < player_body[i].r + player.r ){kill2 += 1;body_num = 5;score = 100;kill = 0;//蛇player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}}}//玩家2吃玩家1蛇尾for (int i = 0; i < body_num; i++){if (Distance(player_body[i].x, player_body[i].y, player2.x, player2.y) < player_body[i].r + player2.r){kill += 1;body_num2 = 5;score2 = 100;kill2 = 0;//蛇player2.x = Wide;player2.y = Hight / 2;player2.r = 10;//蛇身player_body2[0].x = player2.x - player2.r;player_body2[0].y = player2.y;player_body2[0].r = player2.r;for (int i = 1; i < body_num2; i++){player_body2[i].x = player_body2[i - 1].x - player_body2[i - 1].r;player_body2[i].y = player_body2[i - 1].y;player_body2[i].r = player_body2[i - 1].r;}}}for (int i = 0; i < Ai_num; i++){//ai碰到边界if (Ai[i].x > Wide_map || Ai[i].x <0 || Ai[i].y >Hight_map || Ai[i].y < 0){//身体变成食物Ai_body_food_num[i] = Ai_body_num[i];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}Ai[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int j = 1; j < Ai_body_num[i]; j++){Ai_body[i][j].x = Ai_body[i][j - 1].x - Ai_body[i][j - 1].r;Ai_body[i][j].y = Ai_body[i][j - 1].y;Ai_body[i][j].r = Ai_body[i][j - 1].r;}}//ai碰玩家1蛇尾for (int j = 0; j < body_num; j++){if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r){kill += 1;//尾部变成食物Ai_body_food_num[i] = Ai_body_num[i];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}//重新生成aiAi[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int z = 1; z < Ai_body_num[i]; z++){Ai_body[i][z].x = Ai_body[i][z - 1].x - Ai_body[i][z - 1].r;Ai_body[i][z].y = Ai_body[i][z - 1].y;Ai_body[i][z].r = Ai_body[i][z - 1].r;}}}//ai碰玩家2蛇尾for (int j = 0; j < body_num2; j++){if (Distance(player_body2[j].x, player_body2[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body2[i].r) {kill2 += 1;//尾部变成食物Ai_body_food_num[i] = Ai_body_num[i];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}//重新生成aiAi[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int z = 1; z < Ai_body_num[i]; z++){Ai_body[i][z].x = Ai_body[i][z - 1].x - Ai_body[i][z - 1].r;Ai_body[i][z].y = Ai_body[i][z - 1].y;Ai_body[i][z].r = Ai_body[i][z - 1].r;}}}//玩家1碰ai蛇尾for (int j = 0; j < Ai_body_num[i]; j++){if (Distance(Ai_body[i][j].x, Ai_body[i][j].y, player.x, player.y) < player.r + Ai_body[i][j].r){body_num = 5;score = 100;kill = 0;//蛇player.x = Wide / 2;player.y = Hight / 2;player.r = 10;//蛇身player_body[0].x = player.x - player.r;player_body[0].y = player.y;player_body[0].r = player.r;for (int i = 1; i < body_num; i++){player_body[i].x = player_body[i - 1].x - player_body[i - 1].r;player_body[i].y = player_body[i - 1].y;player_body[i].r = player_body[i - 1].r;}}}//玩家2碰ai蛇尾for (int j = 0; j < Ai_body_num[i]; j++){if (Distance(Ai_body[i][j].x, Ai_body[i][j].y, player2.x, player2.y) < player2.r + Ai_body[i][j].r){body_num2 = 5;score2 = 100;kill2 = 0;//蛇player2.x = Wide / 2;player2.y = Hight / 2;player2.r = 10;//蛇身player_body2[0].x = player2.x - player2.r;player_body2[0].y = player2.y;player_body2[0].r = player2.r;for (int i = 1; i < body_num2; i++){player_body2[i].x = player_body2[i - 1].x - player_body2[i - 1].r;player_body2[i].y = player_body2[i - 1].y;player_body2[i].r = player_body2[i - 1].r;}}}//ai碰ai/* for (int p = 0; p < Ai_num; p++){for (int j = 0; j < Ai_body_num[i]; j++){if (Distance(Ai_body[p][j].x, Ai_body[p][j].y, Ai[i].x, Ai[i].y) < Ai[i].r + Ai_body[p][j].r && i != p){//尾部变成食物Ai_body_food_num[i] = Ai_body_num[p];for (int z = 1; z < Ai_body_num[i]; z++){Ai_body_food[i][z].x = Ai_body[i][z].x;Ai_body_food[i][z].y = Ai_body[i][z].y;Ai_body_food[i][z].r = Ai_body[i][z].r;Ai_body_food[i][z].color = RGB(rand() % 256, rand() % 256, rand() % 256);}//重新生成aiAi[i].x = rand() % Wide_map;Ai[i].y = rand() % Hight_map;Ai[i].r = 10;//ai身体Ai_body_num[i] = 5;Ai_body[i][0].x = Ai[i].x - Ai[i].r;Ai_body[i][0].y = Ai[i].y;Ai_body[i][0].r = Ai[i].r;for (int z = 1; z < Ai_body_num[i]; z++){Ai_body[i][z].x = Ai_body[i][z - 1].x - Ai_body[i][z - 1].r;Ai_body[i][z].y = Ai_body[i][z - 1].y;Ai_body[i][z].r = Ai_body[i][z - 1].r;}}}}*/}
}void show()
{srand((unsigned)time(NULL));SetWorkingImage(&map);cleardevice();setbkcolor(RGB(236, 236, 244));//划线颜色setlinecolor(RGB(222, 222, 230));//划线for (int i = 0; i < Wide_map; i += 20){line(i, 0, i, Hight_map);}for (int i = 0; i < Hight_map; i += 20){line(0, i, Wide_map, i);}//食物for (int i = 0; i < food_num; i++){setfillcolor(food[i].color );solidcircle(food[i].x, food[i].y, food[i].r);}//玩家1——蛇头setfillcolor(RED);solidcircle(player.x, player.y, player.r);//玩家1——蛇身for (int i = 0; i < body_num; i++){setfillcolor(RGB(149, 236, 105));solidcircle(player_body[i].x, player_body[i].y, player_body[i].r);}//玩家2——蛇头setfillcolor(RGB(221, 221, 2));solidcircle(player2.x, player2.y, player2.r);//玩家2——蛇身for (int i = 0; i < body_num2; i++){setfillcolor(RGB(149, 236, 105));solidcircle(player_body2[i].x, player_body2[i].y, player_body2[i].r);}//ai蛇头for (int i = 0; i < Ai_num; i++){setfillcolor(RGB(229, 0, 0));solidcircle(Ai[i].x, Ai[i].y, Ai[i].r);}//ai蛇身for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_num[i]; j++){setfillcolor(RGB(229, 196, 0));solidcircle(Ai_body[i][j].x, Ai_body[i][j].y, Ai_body[i][j].r);}}//蛇尸体for (int i = 0; i < Ai_num; i++){for (int j = 0; j < Ai_body_food_num[i]; j++){setfillcolor(Ai_body_food[i][j].color );solidcircle(Ai_body_food[i][j].x, Ai_body_food[i][j].y, Ai_body_food[i][j].r);}}//玩家1视角int x = player.x - (Wide / 2) ;int y = player.y - (Hight / 2);//防止窗口越界if (x < -Wide / 4){x = -Wide / 4;}if (y < 0){y = 0;}if (x > Wide_map - Wide){x = Wide_map - Wide;}if (y > Hight_map - Hight){y = Hight_map - Hight;}//玩家2视角int x2 = player2.x - (Wide / 2);int y2 = player2.y - (Hight / 2);//防止窗口越界if (x2 < -Wide / 4){x2 = -Wide / 4;}if (y2 < 0){y2 = 0;}if (x2 > Wide_map - Wide){x2 = Wide_map - Wide;}if (y2 > Hight_map - Hight){y2 = Hight_map - Hight;}settextcolor(RGB(7, 19, 62));TCHAR buffer[50];TCHAR buffer1[50];swprintf_s(buffer, _T("%d"), score);swprintf_s(buffer1, _T("%d"), kill);setbkmode(TRANSPARENT);settextstyle(20, 0, _T("宋体"));outtextxy(player.x, player.y - player.r * 4 - 20, _T("长度:"));outtextxy(player.x + 50, player.y - player.r * 4 - 20, buffer);outtextxy(player.x, player.y - player.r * 4, _T("击杀:"));outtextxy(player.x + 50, player.y - player.r * 4, buffer1);TCHAR buffer2[50];TCHAR buffer3[50];swprintf_s(buffer2, _T("%d"), score2);swprintf_s(buffer3, _T("%d"), kill2);outtextxy(player2.x, player2.y - player2.r * 4 - 20, _T("长度:"));outtextxy(player2.x + 50, player2.y - player2.r * 4 - 20, buffer2);outtextxy(player2.x, player2.y - player2.r * 4, _T("击杀:"));outtextxy(player2.x + 50, player2.y - player2.r * 4, buffer3);SetWorkingImage();//把map输出到窗口上putimage(0, 0, Wide / 2, Hight, &map, x + Wide / 4, y);putimage(Wide/2, 0, Wide/2, Hight, &map, x2 + Wide / 4, y2);
}int main()
{init();initgraph(Wide, Hight);BeginBatchDraw();while (1){Sleep(10);show();Player_move1();eatfood();SnakeOut();Ai_move();FlushBatchDraw();}closegraph();}
相关文章:
C语言游戏实战(11):贪吃蛇大作战(多人对战)
成果展示: 贪吃蛇(多人对战) 前言: 这款贪吃蛇大作战是一款多人游戏,玩家需要控制一条蛇在地图上移动,吞噬其他蛇或者食物来增大自己的蛇身长度和宽度。本游戏使用C语言和easyx图形库编写,旨在…...
腾讯测试岗位的面试经历与经验分享【一面、二面与三面】
腾讯两个月的实习一转眼就结束了,回想起当时面试的经过,感觉自己是跌跌撞撞就这么过了,多少有点侥幸.马上腾讯又要来校招了,对于有意愿想投腾讯测试岗位的同学们,写了一些那时候面试的经历和自己的想法,算不上经验,仅供参考吧! 一面 — —技术基础,全面…...
手机移动端网卡信息获取原理分析
有些场景我们需要获取当前手机上的网卡信息(如双卡双待、Wifi等)。本文准备研究一下这块的原理,以便更好的掌握相关技术原理。 1、底层系统接口 getifaddrs 使用 getifaddrs 接口可以达到我们的目的,该接口会返回本地所有网卡的信…...
无人新零售引领的创新浪潮
无人新零售引领的创新浪潮 在数字化时代加速演进的背景下,无人新零售作为商业领域的一股新兴力量,正以其独特的高效性和便捷性重塑着传统的购物模式,开辟了一条充满创新潜力的发展道路。 依托人脸识别、物联网等尖端技术,无人新…...
SD-WAN提升企业网络体验
在现代企业中,网络体验已成为提升工作效率与业务质量的关键因素。SD-WAN技术的出现,以其独特的优势,为企业提供了优化网络连接、加速数据传输、提升服务质量和应用访问体验,以及增强网络稳定性的解决方案。接下来,我们…...
Docker搭建Let‘s Encrypt
Let’s Encrypt是一个免费、开放和自动化的证书颁发机构(CA),它提供了一种简单、无需重复的机制来获取和更新SSL/TLS证书。Let’s Encrypt Docker镜像允许用户在容器化环境中轻松部署和使用Let’s Encrypt的服务。 主要功能包括:…...
单链表讲解
一.链表的概念以及结构 链表是一种物理结构上不连续,逻辑结构上连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表的结构与火车是类似的,一节一节的,数据就像乘客一样在车厢中一样。 与顺序表不同的…...
DFS算法系列 回溯
DFS算法系列-回溯 文章目录 DFS算法系列-回溯1. 算法介绍2. 算法应用2.1 全排列2.2 组合2.3 子集 3. 总结 1. 算法介绍 回溯算法是一种经典的递归算法,通常被用来解决排列问题、组合问题和搜索问题 基本思想 从一个初始状态开始,按一定的规则向前搜索&…...
Linux C应用编程:MQTT物联网
1 MQTT通信协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传 输)是一种基于客户端-服务端架构的消息传输协议,如今,MQTT 成为了最受欢迎的物联网协议,已广泛应用于车联网、智能家居、即时聊…...
企业常用Linux文件命令相关知识+小案例
远程连接工具无法连接VMWARE: 如果发现连接工具有时连不上,ip存在,这时候我们查看网络编辑器,更多配置,看vnet8是不是10段,nat设置是否是正确的? 软件重启一下虚机还原一下网络编辑器 查看文件…...
Istio介绍
1.什么是Istio Istio是一个开源的服务网格(Service Mesh)框架,它提供了一种简单的方式来为部署在Kubernetes等容器编排平台上的微服务应用添加网络功能。Istio的核心功能包括: 服务治理:Istio能够帮助管理服务之间的…...
代码随想录算法训练营第四十七天|leetcode115、392题
一、leetcode第392题 本题要求判断s是否为t的子序列,因此设置dp数组,dp[i][j]的含义是下标为i-1的子串与下标为j-1的子串相同字符的个数,可得递推公式是通过s[i-1]和t[j-1]是否相等区分。 具体代码如下: class Solution { publ…...
将Ubuntu18.04默认的python3.6升级到python3.8
1、查看现有的 python3 版本 python3 --version 2、安装 python3.8 sudo apt install python3.8 3、将 python3.6 和 3.8 添加到 update-alternatives sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 sudo update-alternatives --insta…...
Python和Java哪个更适合后端开发?
Python和Java都是强大的后端开发语言,它们各自有鲜明的特点和适用场景。选择哪一个更适合后端开发,主要取决于具体的项目需求、团队技术栈、个人技能偏好以及长期发展考虑等因素。 下面是两者在后端开发中的优势和劣势: 「Python࿱…...
Python+pytest接口自动化之cookie绕过登录(保持登录状态)
前言 我们今天来聊聊pythonpytest接口自动化之cookie绕过登录(保持登录状态),在编写接口自动化测试用例或其他脚本的过程中,经常会遇到需要绕过用户名/密码或验证码登录,去请求接口的情况,一是因为有时验证…...
什么数据集成(Data Integration):如何将业务数据集成到云平台?
说到数据集成(Data Integration),简单地将所有数据倒入数据湖并不是解决办法。 在这篇文章中,我们将介绍如何轻松集成数据、链接不同来源的数据、将其置于合适的环境中,使其具有相关性并易于使用。 数据集成࿱…...
国外EDM邮件群发多少钱?哪个软件好?
在当今全球化市场环境下,电子邮件营销作为最有效的数字营销渠道之一,其影响力不容忽视。而高效精准的EDM(Electronic Direct Mail)邮件营销策略更是企业拓展海外市场、提升品牌知名度的关键手段。云衔科技以其创新的智能EDM邮件营…...
C语言入门算法——回文数
题目描述: 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。 例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个…...
OceanBase—操作实践
文档结构 1、概念简介2、核心设计3、操作实践3.3、数据同步 官方文档:https://www.oceanbase.com/docs/oceanbase-database-cn 1、概念简介 版本分为社区版和企业版,其中企业版兼容MySQL 和Oracle数据库语法; 2、核心设计 存储层 复制层 …...
智慧用电安全管理系统
智慧用电安全管理系统 智慧用电安全管理系统是智能电网中客户侧关键的构成部分,是基本建设新型智慧城市的基本,将完成地区内各种各样用电设备的智能化系统监管,完成地区内日常生活与工作中安全性、舒服。 一、智慧用电安全管理系统介绍 …...
Rust语言入门第二篇-Cargo教程
文章目录 Rust语言入门第二篇-Cargo教程一,Cargo 是什么二,Cargo教程Cargo.toml文件src/main.rs 文件构建并运行Cargo项目 Rust语言入门第二篇-Cargo教程 本节提供对cargo命令行工具的快速了解。我们演示了它为我们生成新包的能力,它在包内编…...
测试用例的编写方式
学习目标 能对穷举场景设计测试点能对限定边界规则设计测试点能对多条件依赖关系进行设计测试点能对于项目业务进行设计测试点 目录 等价类划分法案例 等价类划分 说明:在所有测试数据中,具有某种共同特征的数据集合进行划分分类: 有效等…...
HarmonyOS实战开发-状态管理、通过使用页面级的状态变量 和应用级的状态变量 来实现应用的状态管理。
介绍 本示例通过使用页面级的状态变量 和应用级的状态变量 来实现应用的状态管理。 效果预览 使用说明 1.点击首页中的基本类型进入对应页面,点击按钮可以更改圆形的颜色;点击查看源码可以展示基本类型功能效果的源码。 2.点击首页中的数组类型进入对…...
【Java开发指南 | 第二篇】标识符、Java关键字及注释
专栏:Java开发指南 CSDN秋说 文章目录 标识符Java关键字Java注释 标识符 Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线&…...
3D可视化技术:研发基地的科技新篇章
在科技日新月异的今天,我们生活在一个充满无限可能性的时代。而在这个时代中,3D可视化技术正以其独特的魅力,引领着科技领域的新一轮变革。 3D可视化技术通过三维图像的方式,将现实世界或虚拟世界中的物体、场景等以立体、逼真的形…...
蓝旭前端05:JavaScript进阶
蓝旭前端05:JavaScript进阶 基础简单复习 数据类型 基本数据类型:Number、String、Boolean、Null、Undefined等。引用数据类型:Object、Array、Function等。typeof操作符:返回数据类型的字符串形式。 变量 变量声明࿱…...
【docker-compose】安装及配置
目录 安装在线安装离线安装 配置mysql5.7bitnami/mysql8.3redisweb前后台分离部署前端https(SSL)配置nginx动态传参资源限制:内存、cpunacossentinelgateway 问题汇总iptables No chain/target/match by that namedocker-compose.yml修改mysql密码,重启后…...
【第十五届】蓝桥杯省赛C++b组
今年的蓝桥杯省赛已经结束了,与以往不同,今年又回到了8道题,而22,23年出现了10道题 大家觉得难度怎么样,欢迎进来讨论,博主今年没参加哈,大家聊聊,我听听大家的意见和看法哈 试题A:…...
thinkphp6 Driver [Think] not supported.
问题的原因:使用view这个类但相应的库未安装(新版仅内置了PHP原生模板引擎) 官方解释:视图功能由\think\View类配合视图驱动(也即模板引擎驱动)类一起完成,新版仅内置了PHP原生模板引擎&#x…...
爱自然生命力专项基金:“爱·启航”残障家庭教育援助项目帮扶上万残障家庭
为进一步积极践行社会责任,助力公益慈善事业,2017年2月爱自然生命力体系与中国下一代教育基金会开展相关合作,共同启动了中国下一代教育基金会爱自然生命力专项基金,并启动了基金第一个项目“爱启航残障家庭教育援助项目”&#x…...
静态页面网站怎么做/石家庄百度关键词优化
SecureCRT端口转发配置 背景: 现在有一个平台 A 和平台 B 。平台 A 有公网地址,面平台 B 没有公网地址,但是平台 A 和 B 可以通过内网互访( A 和 B 都是双 IP ,一个公网一个内网)。这时候就可以用到端口转发…...
在百度上做网站有用吗/衡阳seo服务
一、摘要 本章笔者将详细介绍组织测试代码的相关内容,所用的测试例子会是冒泡排序,笔者在从业这么久之后回想很多面试都要问冒泡排序,虽然不知道为什么要问这个,但还是希望大家掌握,它与自动化测试关系不大属于python的…...
网站建设定制/微信管理系统登录
要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原。前面说过,编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系。JavaScript就是把数据和代码都简化到最原始的程度。 JavaScript中的数…...
宜宾建设招标网站/搜索广告是什么
2018年中考学校录取分数线尚未公布,以下是2017年录取分数线,仅供参考!菏泽二中统招线:613.5。指标生调剂线:604。最低线:513.5。体育:481。音乐:475.5。美术:428。曹州一…...
wordpress自定义文章列表/seo长尾快速排名
声明:本博客为原创博客,未经同意。不得转载!大多数人最经常使用的截屏方法可能就是利用手机的快捷按键了,可是那样假设要导入到电脑中效率会比較低。实际上有更好的截屏方式,最简单的当然就是利用Eclipse中的DDMS进行截…...
新建的网站怎么上首页/分析网站推广和优化的原因
数组: 1.push(): 向数组尾部添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。 1 var arr [1,2,3]; 2 console.log(arr); // [1, 2, 3] 3 var b arr.push(4); 4 console.log(b); // 4 //表示当前数组长度 5 con…...