C语言游戏实战(11):贪吃蛇大作战(多人对战)

news2024/7/6 17:40:55

   成果展示:

贪吃蛇(多人对战)

 前言:

这款贪吃蛇大作战是一款多人游戏,玩家需要控制一条蛇在地图上移动,吞噬其他蛇或者食物来增大自己的蛇身长度和宽度。本游戏使用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);
				}
				//重新生成ai
				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 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);
				}
				//重新生成ai
				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 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);
				}
				//重新生成ai
				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 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);
					}
					//重新生成ai
					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 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();

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1510094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

功能测试转自动化测试好不好转型?

手工测试做了好多年&#xff0c;点点点成了每天必须做的事情。但是随着自动化测试趋势的日渐明显&#xff0c;以及受到薪资、技能的双重考验&#xff0c;掌握自动化测试成为了必备技能。 手工转自动化测试&#xff0c;不是一蹴而就的。“预先善其事&#xff0c;必先利其器”&a…

C++中的RAII原则和资源管理如何提高程序效率和安全性?

文章目录 C中的RAII&#xff08;Resource Acquisition Is Initialization&#xff09;原则是一种编程范式&#xff0c;它确保资源在其生命周期内的有效管理。RAII的核心思想是在对象创建时&#xff08;初始化阶段&#xff09;获取资源&#xff0c;并在对象销毁时&#xff08;析…

C# 8.0+版本项目 string不可为空

1.在某一次新建项目的时候发现&#xff0c;新建的项目&#xff0c;写的测试接口&#xff0c;接口的入参有string的参数&#xff0c; 但是调用接口的时候string的参数没有传报了400&#xff0c;很奇怪&#xff0c;也没有语法错误之类的。 2.解决办法 在项目上右键->属性->…

HTML静态网页成品作业(HTML+CSS)——家乡漳州介绍设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Flink技术简介与入门实践

架构简介 Flink 是一个分布式流处理和批处理计算框架&#xff0c;具有高性能、容错性和灵活性。下面是 Flink 的架构概述&#xff1a; JobManager&#xff1a;JobManager 是 Flink 集群的主节点&#xff0c;负责接收和处理用户提交的作业。JobManager 的主要职责包括&#xff1…

NASA数据集——亚马逊盆地与其大气边界层之间各种气溶胶和气体交换率的估计值数据

简介 Pre-LBA ABLE-2A and ABLE-2B Expedition Data ABLE 2A 和 2B&#xff08;大气边界层实验&#xff09;数据包括亚马逊盆地与其大气边界层之间各种气溶胶和气体交换率的估计值&#xff0c;以及这些气溶胶和气体在边界层和自由对流层之间的移动过程。前言 – 人工智能教程…

HTML静态网页成品作业(HTML+CSS)——非遗昆曲介绍设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

如何查找、恢复误清空的 Android 回收站?

“我的回收站里有一些照片。当我点击“恢复”时&#xff0c;没有任何反应。我可以将我的 Android 手机插入我的电脑。这样我就可以手动恢复它们。但我在 Android 上找不到 bin 文件夹。我还可以做些什么&#xff1f;” 随着 Android 手机上的文件数量不断增加&#xff0c;了解…

SimplifyRODataLoads - 优化阅读笔记

// 只支持 X86 static cl::opt<bool> SimplifyRODataLoads("simplify-rodata-loads",cl::desc("通过用相应节中找到的常数替换内存操作数&#xff0c;简化来自只读节的加载"),cl::cat(BoltOptCategory));测试用例&#xff1a; ./build4/bin/llvm-li…

【汇编】#3 8086与数据有关的寻址方式

文章目录 操作码与操作数1. 8086处理器的与数据有关的寻址方式1.1 立即数寻址方式1.2 寄存器寻址方式 2. 有效&#xff08;偏移&#xff09;地址&#xff08;effective address&#xff0c;EA&#xff09;与缺省段寄存器选择tips:段跨越前缀2.1 直接寻址tips:直接寻址与立即寻址…

什么是农业气象站?——气象科普

农业气象站&#xff0c;也被称为田间气象站或农业小气候仪&#xff0c;是一款综合的物联网农业气象参数观测系统。它能够实时、准确、有针对性地监测农田区域内的多种气象参数&#xff0c;包括温湿度、光照、二氧化碳浓度、大气压、雨量、土壤温湿度、风速风向等。 农业气象站…

【MATLAB 】 EMD信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 展示出图效果 1 EMD信号分解算法 EMD 分解又叫经验模态分解&#xff0c;英文全称为 Empirical Mode Decomposition。 EMD 是一种信号分解方法&#xff0c;它将一个信号分解成有限个本质模态函数 (EMD) 的和&#xff0c…

【Linux】文件缓冲区|理解文件系统

目录 预备知识 观察现象 第一&#xff1a;携带\n&#xff0c;不使用fork()&#xff0c;打印到显示器 第二&#xff1a;携带\n&#xff0c;使用fork()&#xff0c;打印到显示器 第三&#xff1a;携带\n&#xff0c;使用fork()&#xff0c;打印到文件里 第四&#xff1a;不携…

【R语言实战】——金融时序分布拟合

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

常见的限流算法- python版本

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 在系统的稳定性设计中&#xff0c;需要考虑到的就是限流&#xff0c;避免高并发…

DC/DC高压模块直流升压可调稳压输出升压变换器5V12V24V48V转50V110V150V130V200V250V300V450V500V600V800V

特点 效率高达 80%以上1*2英寸标准封装单电压输出价格低稳压输出工作温度: -40℃~85℃阻燃封装&#xff0c;满足UL94-V0 要求温度特性好可直接焊在PCB 上 应用 HRB W2~40W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为&#xff1a;4.5~9V、9~18V、及18~36V、…

容量治理三板斧:扩容、限流与降级

前言 随着现代软件系统日益复杂和用户规模的不断增长&#xff0c;分布式架构成为了保持系统高可用性与高性能的标准解决方案。然而&#xff0c;随之而来的是对系统容量治理的新挑战。在这样的背景下&#xff0c;容量治理成为了分布式系统设计和运维中不可或缺的一环。要确保系…

【PyTorch][chapter 22][李宏毅深度学习]【无监督学习][ WGAN]【理论一】

简介&#xff1a; 2014年Ian Goodfellow提出以来&#xff0c;GAN就存在着训练困难、生成器和判别器的loss无法指示训练进程、生成样本缺乏多样性等问题。从那时起&#xff0c;很多论文都在尝试解决&#xff0c;但是效果不尽人意&#xff0c;比如最有名的一个改进DCGAN依靠的是对…

AI毕业设计生成器(基于AI大模型技术开发)支持Java和Python

这是一个辅助生成计算机毕业设计的工具&#xff0c;可以自动完成毕业设计的源码。它基于几百个github上面开源的java和python项目&#xff0c;运用tengsorflow技术&#xff0c;训练出了AI大模型。基本实现了计算机毕业设计生成器&#xff0c;能够初步生成Java或python基本源码。…

嵌入式驱动学习第三周——container_of()宏

前言 Linux内核编程中&#xff0c;会经常看见一个宏函数container_of&#xff0c;那么这究竟是什么呢&#xff0c;本篇博客记录学习container_of的过程。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可…