【c语言】飞机大战2

news2025/4/23 2:30:49

1.优化边界问题

之前视频中当使用drawAlpha函数时,是为了去除飞机后面变透明,当时当飞机到达边界的时候,会出现异常退出,这是因为drawAlpha函数不稳定,昨天试过制作掩码图,下载了一个ps,改的话,图片大小又变了,最后采用的方式是当飞机在窗口内的时候使用drawAlpha函数贴图,当飞机要出边缘的时候,使用putimage贴图,防止出现闪退,优化后飞机到边界的时候会出现黑框.

边界优化

对应的代码实现

void draw()
{
	putimage(0, 0, &img_bk);
	if (plane.x > -1 && plane.x < WIDTH && plane.y>-1 && plane.y + 48< HEIGHT)
	{
		drawAlpha(&img_plane, plane.x, plane.y);
	}
	else
	{
		putimage(plane.x, plane.y, &img_plane);
	}
	if (a.x > -1 && a.x < WIDTH && a.y>0&& a.y + 98 < HEIGHT)
	{
		drawAlpha(&img_a, a.x, a.y);
	}
	else
	{
		putimage(a.x, a.y, &img_a);

	}
	if (b.x > -1 && b.x < WIDTH && b.y>-1 && b.y +120 < HEIGHT)
	{
		drawAlpha(&img_b, b.x, b.y);
	}
	else
	{
		putimage(b.x, b.y, &img_b);

	}
	if (c.x > -1 && c.x < WIDTH && c.y>-1 && c.y + 120 < HEIGHT)
	{
		drawAlpha(&img_c, c.x, c.y);
	}
	else
	{
		putimage(c.x, c.y, &img_c);

	}



}

2.我方战机发射子弹

如果我们用数组存储子弹的信息的话,在不断发射子弹的过程中,不断的创建数组元素,会导致栈溢出,所以我们使用链表存储每个子弹的信息,当打出一个子弹时,会创建一个新的结点,并且尾插到头结点上去,当子弹出屏幕,或者隔一段时间,删除出屏幕的子弹,用到单链表节点的删除.

1.首先创建一个子弹的结构体,并创建我方飞机子弹的头节点

typedef struct bullet
{
	float x, y;
	float vx, vy;
	int  isexist;
	struct bullet* next;

}list;
list* planebullet = NULL;

2.创建新结点

list* BuyplanebulletNode(float vx, float vy)
{





	list* newnode = (list*)malloc(sizeof(list));//空间申请
	assert(newnode);//断言,新结点是否申请到了
	newnode->vx = vx;//数据赋值
	newnode->vy = vy;//数据赋值
	newnode->x = plane.x + plane.width / 2+17;
	newnode->y = plane.y;//让子弹的出生坐标在飞机中间
	newnode->isexist = 1;
	newnode->next = NULL;//指向的地址赋值
	return newnode;//将申请好的空间首地址返回回去



}

3 尾插新结点.

void pushback1(list** pphead,float vx,float vy)//尾插
{
	
	list* newnode = BuyplanebulletNode(vx, vy);
	
	if (*pphead == NULL)//链表无结点
	{
		*pphead = newnode;// 将创建好的头节点的地址给给*pphead,作为新头节点的地址
		
	}
	else
	{
		
		list* tail = *pphead;//定义一个指针,先指向头结点的地址
		while (tail->next != NULL)//循环遍历找尾结点
		{
			tail = tail->next;//指针指向下一个结点

		}
		tail->next = newnode;//找到尾结点,将尾结点的next存放新接结点的地址

	}

}

4.结点的删除

void removebullet(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	list* prev = NULL;
	while (cur != NULL)
	{
		if (cur->isexist == 0)
		{
			if (*pplist == cur)
			{
				*pplist = cur->next;
				free(cur);
				cur = *pplist;


			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = prev;




			}
		}
		else
		{
			prev = cur;
			cur = cur->next;


		}





	}






}

5.子弹位置改变参数设置

void listchangexy(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	while (cur != NULL)
	{
		cur->x += cur->vx;
		cur->y += cur->vy;
		
		if ((cur->y<0 )|| (cur->y>HEIGHT) || (cur->x >0) || (cur->x <WIDTH))
			cur->isexist = 0;
		cur = cur->next;



	}










}

遍历子弹链表,使得每个子弹的位置属性发生变化,当子弹出屏幕时,将当前cur指向的子弹的exist==0,表示子弹消失,cur指向下一个子弹,改变子弹的位置坐标属性.
上面创建的链表存下了每个子弹的属性,然后我们遍历子弹链表,贴子弹上去。

6.贴子弹上去

void showbullet()
{
	static int count1 = 0;

	listchangexy(&planebullet);
	for (list* cur = planebullet; cur!= NULL; cur = cur ->next)
	{
		
		putimage(cur->x,cur->y, &img_planebullet);
		


	}
	
	if (++count1 == 100)
	{
		removebullet(&planebullet);
	
	}
	if (count1 > 99999)
	{
		count1 = 0;
	}



	}





}

这里定时清理一下出屏幕的子弹,要不然太占内存了.如果直接使用removebullet会出现错误
当然在player_move函数里面加

	if (GetAsyncKeyState(VK_SPACE))// && Timer(300, 1))
	{

		
			pushback1(&planebullet, 0, -20);
		
		

	}

我们可以使用空格开火,当空格按下一次,就尾插子弹信息到对应子弹的结点上去
总结
在这里插入图片描述

子弹发射

7.解决子弹太密集问题

使用定时器函数,隔一段时间才能发射子弹

bool Timer(int ms, int id)
{
	static DWORD t[10];

	if (clock() - t[id] > ms)
	{

		t[id] = clock();
		return true;
	}

	return false;
}

这个先记住就行,不用理解,参数第一个是定时时间,单位是ms,第二个我也不太清楚,传个1就行.

	if ((GetAsyncKeyState(VK_SPACE))&& Timer(300, 1))
	{

		
			pushback1(&planebullet, 0, -20);
			//pushback1(&planebullet, -10, -17.32);
			//pushback1(&planebullet, 10, -17.32);
		

	}

8.子弹升级

子弹升级

	if ((GetAsyncKeyState(VK_SPACE))&& Timer(300, 1))
	{

		
			pushback1(&planebullet, 0, -20);
			pushback1(&planebullet, -10, -17.32);
			pushback1(&planebullet, 10, -17.32);
		

	}

3.敌方的子弹发射

当我们会处理我方的子弹发射之后,敌方子弹的发射也是同样的道理

敌机a子弹的发射

敌机a子弹发射(步骤和我方战机相同)

list* abullet = NULL;
void pushback2(list** pphead, float vx, float vy);
list* BuyabulletNode(float vx, float vy)
{
	list* newnode = (list*)malloc(sizeof(list));//空间申请
	assert(newnode);//断言,新结点是否申请到了
	newnode->vx = vx;//数据赋值
	newnode->vy = vy;//数据赋值
	newnode->x = a.x + a.width / 2-10;
	newnode->y = a.y+80;
	newnode->isexist = 1;
	newnode->next = NULL;//指向的地址赋值
	return newnode;//将申请好的空间首地址返回回去



}
void pushback2(list** pphead, float vx, float vy)//尾插
{
	
	list* newnode = BuyabulletNode(vx, vy);

	if (*pphead == NULL)//链表无结点
	{
		*pphead = newnode;// 将创建好的头节点的地址给给*pphead,作为新头节点的地址

	}
	else
	{
		
		list* tail = *pphead;//定义一个指针,先指向头结点的地址
		while (tail->next != NULL)//循环遍历找尾结点
		{
			tail = tail->next;//指针指向下一个结点

		}
		tail->next = newnode;//找到尾结点,将尾结点的next存放新接结点的地址

	}

}
void removebullet(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	list* prev = NULL;
	while (cur != NULL)
	{
		if (cur->isexist == 0)
		{
			if (*pplist == cur)
			{
				*pplist = cur->next;
				free(cur);
				cur = *pplist;


			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = prev;




			}
		}
		else
		{
			prev = cur;
			cur = cur->next;


		}





	}






}
void listchangexy(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	while (cur != NULL)
	{
		cur->x += cur->vx;
		cur->y += cur->vy;
		
		if ((cur->y<0 )|| (cur->y>HEIGHT) || (cur->x >0) || (cur->x <WIDTH))
			cur->isexist = 0;
		cur = cur->next;



	}










}

void showbullet()
{
	static int count1 = 0;

	listchangexy(&planebullet);
	if (++count1 == 100)
	{
		removebullet(&planebullet);
		removebullet(&abullet);
		removebullet(&bbullet);
	}
	if (count1 > 99999)
	{
		count1 = 0;
	}

	for (list* cur = planebullet; cur!= NULL; cur = cur ->next)
	{
		
		putimage(cur->x,cur->y, &img_planebullet);
		


	}
	
	listchangexy(&abullet);

	
	for (list* cur = abullet; cur != NULL; cur = cur->next)
	{
		//putimage(cur->x - 10, cur->y - 10, &img_planebullet);
		putimage(cur->x , cur->y, &img_abullet);

	}

	//listchangexy(&bbullet);
	//
	//for (list* cur = bbullet; cur != NULL; cur = cur->next)
	//{
	//	//putimage(cur->x - 10, cur->y - 10, &img_planebullet);
	//	putimage(cur->x, cur->y, &img_bbullet);

	//}





}

因为敌机a在移动中发射子弹,所以将puchback2放在ufoamove函数里面

void ufoamove()
{
	static int dir1 = 1;
	static int cnt = 0;

	if (a.bornflag == 1)
	{
		a.bornflag = 0;
		a.x = rand() % (WIDTH - a.width);
		a.y = -50;




	}
	if (a.y > 200)
	{
		dir1 = 0;
	}
	else if (a.y < -150)
	{
		dir1 = 1;
		a.bornflag = 1;
	}
	if (1 == dir1)
	{
		a.y += a.speed;

	}
	else
	{
		a.y -= a.speed;
	}
	if (++cnt % 50 == 0)
	{
		pushback2(&abullet, 0, 10);
	




	}
	if (cnt > 99999)
	{
		cnt = 0;
	}













}

设置一个静态变量cnt,当cnt%50取余==0时,发射子弹,这样也解决了子弹太密集(50可以修改,就相当于间隔),cnt为int,可能会溢出,所以>99999,将cnt=0;

敌机b子弹的发射

同理
在这里插入图片描述
包含头文件#include<math.h>

4.程序源码

#include<stdio.h>
#include <graphics.h>
#include <assert.h>
#include <stdlib.h>
#include<conio.h>//_getch();
#include <time.h>
#include <math.h>
#define PI 3.1415926
#define HEIGHT  503
#define WIDTH 700


IMAGE img_bk, img_plane, img_a, img_b, img_c, img_abullet, img_bbullet, img_cbullet, img_planebullet,img_tmp;
typedef struct bullet
{
	float x, y;
	float vx, vy;
	int  isexist;
	struct bullet* next;

}list;
list* planebullet = NULL;
list* abullet = NULL;
list* bbullet = NULL;
void pushback2(list** pphead, float vx, float vy);
void pushback3(list** pphead, float vx, float vy);
void pushback(list** pphead, list* newnode);//尾插;
struct aircraft
{
	int x, y;
	int width;
	int height;
	int speed;
	int bornflag;

};
aircraft plane, a, b, c;
void datainit()
{
	plane = { 150,150 };
	//a = { 0,0 };
	/*b = { 300,0 };*/
	/*c = { 450,0 };*/
	a.speed = 1;
	a.bornflag = 1;
	b.bornflag = 1;
	c.bornflag = 1;
	a.width = 100;
	a.height = 100;
	b.speed = 1;
	b.width = 80;
	b.height = 100;
	c.height = 70;
	c.width = 70;
	c.speed = 3;











}
list* BuyabulletNode(float vx, float vy)
{
	list* newnode = (list*)malloc(sizeof(list));//空间申请
	assert(newnode);//断言,新结点是否申请到了
	newnode->vx = vx;//数据赋值
	newnode->vy = vy;//数据赋值
	newnode->x = a.x + a.width / 2-10;
	newnode->y = a.y+80;
	newnode->isexist = 1;
	newnode->next = NULL;//指向的地址赋值
	return newnode;//将申请好的空间首地址返回回去



}
list* BuybbulletNode(float vx, float vy)
{
	list* newnode = (list*)malloc(sizeof(list));//空间申请
	assert(newnode);//断言,新结点是否申请到了
	newnode->vx = vx;//数据赋值
	newnode->vy = vy;//数据赋值
	newnode->x = b.x + b.width / 2 - 10;
	newnode->y = b.y + 80;
	newnode->isexist = 1;
	newnode->next = NULL;//指向的地址赋值
	return newnode;//将申请好的空间首地址返回回去



}
list* BuyplanebulletNode(float vx, float vy)
{





	list* newnode = (list*)malloc(sizeof(list));//空间申请
	assert(newnode);//断言,新结点是否申请到了
	newnode->vx = vx;//数据赋值
	newnode->vy = vy;//数据赋值
	newnode->x = plane.x + plane.width / 2+17;
	newnode->y = plane.y;
	newnode->isexist = 1;
	newnode->next = NULL;//指向的地址赋值
	return newnode;//将申请好的空间首地址返回回去



}
void drawAlpha(IMAGE* picture, int  picture_x, int picture_y) //x为载入图片的X坐标,y为Y坐标
{
	// 变量初始化
	DWORD* dst = GetImageBuffer();    // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带
	DWORD* draw = GetImageBuffer();
	DWORD* src = GetImageBuffer(picture); //获取picture的显存指针
	int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带
	int picture_height = picture->getheight(); //获取picture的高度,EASYX自带
	int graphWidth = getwidth();       //获取绘图区的宽度,EASYX自带
	int graphHeight = getheight();     //获取绘图区的高度,EASYX自带
	int dstX = 0;    //在显存里像素的角标

	// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算
	for (int iy = 0; iy < picture_height; iy++)
	{
		for (int ix = 0; ix < picture_width; ix++)
		{
			int srcX = ix + iy * picture_width; //在显存里像素的角标
			int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度
			int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R
			int sg = ((src[srcX] & 0xff00) >> 8);   //G
			int sb = src[srcX] & 0xff;              //B
			if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
			{
				if ((ix + picture_x) >= 0 && (ix + picture_x) <= graphWidth)	//防止出边界后循环显示
				{
					dstX = (ix + picture_x) + (iy + picture_y) * graphWidth; //在显存里像素的角标
					int dr = ((dst[dstX] & 0xff0000) >> 16);
					int dg = ((dst[dstX] & 0xff00) >> 8);
					int db = dst[dstX] & 0xff;
					draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)  //公式: Cp=αp*FP+(1-αp)*BP  ; αp=sa/255 , FP=sr , BP=dr
						| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)         //αp=sa/255 , FP=sg , BP=dg
						| (sb * sa / 255 + db * (255 - sa) / 255);              //αp=sa/255 , FP=sb , BP=db
				}
			}
		}
	}
}


void load()
{
	loadimage(&img_bk, "./back.png");
	loadimage(&img_plane, "./1.png");
	loadimage(&img_a, "./2.png");
	loadimage(&img_b, "./3.png");
	loadimage(&img_c, "./4.png");
	loadimage(&img_abullet, "./5.png");
	loadimage(&img_bbullet, "./6.png");
	loadimage(&img_cbullet, "./7.png");
	loadimage(&img_planebullet, "./8.png");


}
void draw()
{
	putimage(0, 0, &img_bk);
	if (plane.x > -1 && plane.x < WIDTH && plane.y>-1 && plane.y + 48< HEIGHT)
	{
		drawAlpha(&img_plane, plane.x, plane.y);
	}
	else
	{
		putimage(plane.x, plane.y, &img_plane);
	}
	if (a.x > -1 && a.x < WIDTH && a.y>0&& a.y + 98 < HEIGHT)
	{
		drawAlpha(&img_a, a.x, a.y);
	}
	else
	{
		putimage(a.x, a.y, &img_a);

	}
	if (b.x > -1 && b.x < WIDTH && b.y>-1 && b.y +120 < HEIGHT)
	{
		drawAlpha(&img_b, b.x, b.y);
	}
	else
	{
		putimage(b.x, b.y, &img_b);

	}
	if (c.x > -1 && c.x < WIDTH && c.y>-1 && c.y + 120 < HEIGHT)
	{
		drawAlpha(&img_c, c.x, c.y);
	}
	else
	{
		putimage(c.x, c.y, &img_c);

	}



	
	
	
	/*drawAlpha(&img_a, a.x, a.y);
	drawAlpha(&img_b, b.x, b.y);
	drawAlpha(&img_c, c.x, c.y);
	drawAlpha(&img_abullet, 400, 0);
	drawAlpha(&img_bbullet, 400, 50);
	drawAlpha(&img_cbullet, 400, 100);
	drawAlpha(&img_planebullet, 400, 150);*/











 /*       putimage(plane.x, plane.y, &img_plane); 
		putimage(a.x, a.y ,&img_a);
		putimage(b.x, b.y ,&img_b );
		putimage(c.x, c.y, &img_c );
	
		putimage(400, 50 ,&img_bbullet);
		putimage(400, 100 ,&img_cbullet );*/
		




}

void ufoamove()
{
	static int dir1 = 1;
	static int cnt = 0;

	if (a.bornflag == 1)
	{
		a.bornflag = 0;
		a.x = rand() % (WIDTH - a.width);
		a.y = -50;




	}
	if (a.y > 200)
	{
		dir1 = 0;
	}
	else if (a.y < -150)
	{
		dir1 = 1;
		a.bornflag = 1;
	}
	if (1 == dir1)
	{
		a.y += a.speed;

	}
	else
	{
		a.y -= a.speed;
	}
	if (++cnt % 50 == 0)
	{
		pushback2(&abullet, 0, 10);
	




	}
	if (cnt > 99999)
	{
		cnt = 0;
	}













}
void ufobmove()
{
	static int num = 0;
	static int step = b.speed;
	if (b.bornflag == 1)
	{
		b.bornflag = 0;
		b.x = rand() % (WIDTH - b.width);
		b.y = -b.height;




	}
	if (b.x <= 0 || b.x + b.width >= WIDTH)
	{
		step = -step;



	}
	b.x += step;
	b.y++;
	if (b.y >= HEIGHT)
	{
		b.bornflag = 1;


	}

	if (++num % 200 == 0)
	{
		for (int i = 0; i < 10; i++)
		{
			float angle = i * 2 * PI / 10;
			float vx = 1* sin(angle);
			float vy = 1 * cos(angle);
			pushback3(&bbullet, vx, vy);




		}


	}
	if (num > 99999)
	{
		num = 0;
	}






}


void pushback1(list** pphead,float vx,float vy)//尾插
{
	
	list* newnode = BuyplanebulletNode(vx, vy);
	
	if (*pphead == NULL)//链表无结点
	{
		*pphead = newnode;// 将创建好的头节点的地址给给*pphead,作为新头节点的地址
		
	}
	else
	{
		
		list* tail = *pphead;//定义一个指针,先指向头结点的地址
		while (tail->next != NULL)//循环遍历找尾结点
		{
			tail = tail->next;//指针指向下一个结点

		}
		tail->next = newnode;//找到尾结点,将尾结点的next存放新接结点的地址

	}

}
void pushback2(list** pphead, float vx, float vy)//尾插
{
	
	list* newnode = BuyabulletNode(vx, vy);

	if (*pphead == NULL)//链表无结点
	{
		*pphead = newnode;// 将创建好的头节点的地址给给*pphead,作为新头节点的地址

	}
	else
	{
		
		list* tail = *pphead;//定义一个指针,先指向头结点的地址
		while (tail->next != NULL)//循环遍历找尾结点
		{
			tail = tail->next;//指针指向下一个结点

		}
		tail->next = newnode;//找到尾结点,将尾结点的next存放新接结点的地址

	}

}
void pushback3(list** pphead, float vx, float vy)//尾插
{
	
	list* newnode = BuybbulletNode(vx, vy);

	if (*pphead == NULL)//链表无结点
	{
		*pphead = newnode;// 将创建好的头节点的地址给给*pphead,作为新头节点的地址

	}
	else
	{
		
		list* tail = *pphead;//定义一个指针,先指向头结点的地址
		while (tail->next != NULL)//循环遍历找尾结点
		{
			tail = tail->next;//指针指向下一个结点

		}
		tail->next = newnode;//找到尾结点,将尾结点的next存放新接结点的地址

	}

}
void removebullet(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	list* prev = NULL;
	while (cur != NULL)
	{
		if (cur->isexist == 0)
		{
			if (*pplist == cur)
			{
				*pplist = cur->next;
				free(cur);
				cur = *pplist;


			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = prev;




			}
		}
		else
		{
			prev = cur;
			cur = cur->next;


		}





	}






}
void listchangexy(list** pplist)
{
	if (*pplist == NULL)
		return;
	list* cur = *pplist;
	while (cur != NULL)
	{
		cur->x += cur->vx;
		cur->y += cur->vy;
		
		if ((cur->y<0 )|| (cur->y>HEIGHT) || (cur->x >0) || (cur->x <WIDTH))
			cur->isexist = 0;
		cur = cur->next;



	}










}
void showbullet()
{
	static int count1 = 0;

	listchangexy(&planebullet);
	if (++count1 == 100)
	{
		removebullet(&planebullet);
		removebullet(&abullet);
		removebullet(&bbullet);
	}
	if (count1 > 99999)
	{
		count1 = 0;
	}

	for (list* cur = planebullet; cur!= NULL; cur = cur ->next)
	{
		
		putimage(cur->x,cur->y, &img_planebullet);
		


	}
	
	listchangexy(&abullet);

	
	for (list* cur = abullet; cur != NULL; cur = cur->next)
	{
		//putimage(cur->x - 10, cur->y - 10, &img_planebullet);
		putimage(cur->x , cur->y, &img_abullet);

	}

	listchangexy(&bbullet);
	
	for (list* cur = bbullet; cur != NULL; cur = cur->next)
	{
		//putimage(cur->x - 10, cur->y - 10, &img_planebullet);
		putimage(cur->x, cur->y, &img_bbullet);

	}





}


void ufocmove()
{


	static float disx = 0, disy = 0;
	static float tmpx = 0, tmpy = 0;
	static float vx = 0, vy = 0;
	float step = 1000 / c.speed;
	if (1 == c.bornflag)
	{
		c.bornflag = 0;
		tmpx = rand() % (WIDTH - c.width);
		tmpy = -c.height;
		disx = plane.x - tmpx;
		disy = plane.y - tmpy;
		vx = disx / step;
		vy = disy / step;




	}
	tmpx += vx;
	tmpy += vy;
	c.x = (int)(tmpx + 0.5);
	c.y = (int)(tmpy + 0.5);
	if (c.x < -c.width)
	{
		c.bornflag = 1;
	}
	else if (c.x > WIDTH)
	{
		c.bornflag = 1;

	}
	if (c.y > HEIGHT)
	{
		c.bornflag = 1;

	}






}
bool Timer(int ms, int id)
{
	static DWORD t[10];

	if (clock() - t[id] > ms)
	{

		t[id] = clock();
		return true;
	}

	return false;
}
void player_move(int speed) //处理飞机移动
{
	int reload_time = 100;
	static int fire_start = 0;
	int tmp = clock();
	if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W'))
	{
		if (plane.y > 0)
			plane.y -= speed;
	}
	if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S'))
	{
		if (plane.y + 51 < HEIGHT)
			plane.y += speed;
	}
	if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
	{
		if (plane.x > 0)
			plane.x -= speed;
	}
	if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
	{
		if (plane.x + 51 < WIDTH)
			plane.x += speed;
	}
	if ((GetAsyncKeyState(VK_SPACE))&& Timer(300, 1))
	{

		
			pushback1(&planebullet, 0, -20);
			pushback1(&planebullet, -10, -17.32);
			pushback1(&planebullet, 10, -17.32);
		

	}

}

int main()
 {

	initgraph(WIDTH, HEIGHT,CONSOLE_FULLSCREEN);
	BeginBatchDraw();
	datainit();
	while (1)
	{
		load();
		draw();
		ufoamove();
		ufobmove();
		ufocmove();
		player_move(5);
		

	
		showbullet();
	FlushBatchDraw();
	}
	EndBatchDraw();


	getchar();









}

5.剩下的发在下篇

6.效果演示

效果演示

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

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

相关文章

黑马程序员SSM框架-SpringBoot

SpringBoot简介 入门程序 也可以基于官网创建项目。 SpringBoot项目快速启动 下面的插件将项目运行所需的依赖jar包全部加入到了最终运行的jar包中&#xff0c;并将入口程序指定。 SpringBoot概述 基础配置 配置文件格式 自动提示消失解决方案。将新建的配置文件加入到配置文…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的固定帧率(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的固定帧率&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的固定帧率功能的技术背景CameraExplorer如何查看相机固定帧率功能在NEOAPI SDK里通过函数设置相机固定帧率 Baumer工业相机通过NEOAPI SDK设置相机固定…

使用anaconda创建notebook工程

1.由于每个工程使用的环境都可能不一样&#xff0c;因此一个好的习惯就是不同的工程都创建属于自己的环境&#xff0c;在anaconda中默认的环境是base&#xff1a; //括号中名字&#xff0c;代表当前的环境 (base)dragonmachine: $ conda create --nameexample2.激活环境 // 环…

Python 编辑器pycharm下载与安装

使用python语言编程&#xff0c;可以使用pycharm或者sublime等编辑器。 我这里选择pycharm编辑器。 1、下载 登录官网&#xff1a;JetBrains: Essential tools for software developers and teams 点击【Developer Tools】菜单按钮&#xff0c;可以直接找到pycharm&#xff…

高斯泼溅的全面概述

一、说明 高斯泼溅是一种用于表示 3D 场景和渲染新颖视图的方法&#xff0c;在“实时辐射场渲染的 3D 高斯泼溅”中引入。它可以被认为是 NeRF 类模型的替代品&#xff0c;就像当年的 NeRF 一样&#xff0c;高斯分布导致了许多新的研究工作&#xff0c;这些工作选择将其用作各种…

鸿蒙 Window 环境的搭建

鸿蒙操作系统是国内自研的新一代的智能终端操作系统&#xff0c;支持多种终端设备部署&#xff0c;能够适配不同类别的硬件资源和功能需求。是一款面向万物互联的全场景分布式操作系统。 下载、安装与配置 DevEco Studio支持Windows系统和macOS系统 Windows系统配置华为官方推…

Markdown之YAML效果图语法介绍(二十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

C#进阶-IIS应用程序池崩溃的解决方案

IIS是微软开发的Web服务器软件&#xff0c;被广泛用于Windows平台上的网站托管。在使用IIS过程中&#xff0c;可能会遇到应用程序池崩溃的问题&#xff0c;原因可能有很多&#xff0c;包括代码错误、资源不足、进程冲突等。本文将为大家介绍IIS应用程序池崩溃的问题分析和解决方…

缓存cache和缓冲buffer的区别

近期被这两个词汇困扰了&#xff0c;感觉有本质的区别&#xff0c;搜了一些资料&#xff0c;整理如下 计算机内部的几个部分图如下 缓存&#xff08;cache&#xff09; https://baike.baidu.com/item/%E7%BC%93%E5%AD%98 提到缓存&#xff08;cache&#xff09;&#xff0c;就…

【web安全】验证码识别-burp的captcha-killer-modified插件教程(基于百度接口)(总结一些坑)

前言 菜某分享 captcha-killer-modified插件的安装教程 整体安装教程可以看他的 安装captcha-killer-modified插件&#xff08;windospython环境&#xff09;_aptcha-killer-modified的安装-CSDN博客 但是有一点补充。 这个里面的codereg.py文件有个问题 可能是版本的问…

千里马2023年终总结-android framework实战

背景&#xff1a; hi粉丝朋友们&#xff1a; 2023年马上就过去了&#xff0c;很多学员朋友也都希望马哥这边写个年终总结&#xff0c;因为这几个月时间都忙于新课程halsystracesurfaceflinger专题的开发&#xff0c;差点都忘记了这个事情了&#xff0c;今天特别花时间来写个bl…

推荐系统中的 业务指标 覆盖率

覆盖率&#xff08;Coverage&#xff09;是推荐系统评估指标之一&#xff0c;用于衡量推荐系统是否能够覆盖物品空间中的多样性&#xff0c;即是否能够推荐系统中的每个物品都能够被推荐给用户。覆盖率通常是一个百分比&#xff0c;表示被推荐的物品占总物品集合的比例。 覆盖…

系统稳定性建设浅谈

系统稳定性是指系统在受到外部环境变化或内部参数变化时&#xff0c;能够保持其功能和性能的稳定性。它是一种系统的性能指标&#xff0c;可以用来衡量系统的可靠性和可控性。系统稳定性的高低可以反映出系统的可靠性和可控性&#xff0c;从而为系统的设计和运行提供参考。 202…

代码随想录刷题笔记(DAY4)

今日总结&#xff1a;今天把中心放在前端学习上&#xff0c;最后一个题没有完全理解&#xff0c;明天早起补上吧。勉强算完成任务。&#xff08;已补上&#xff09; Day 4 01. 两两交换链表中的节点&#xff08;No. 24&#xff09; 题目链接 代码随想录题解 1.1 题目 给你…

jmeter安装、下载

JDK安装 因为Jmeter是java开发的&#xff0c;有一个特点就是得装一个java环境才能运行 需要安装一个JDK&#xff08;建议安装版本为 8,因为企业用得最多的都是在用这个版本&#xff09; 网址&#xff1a;Java Downloads | Oracle 解压下载下来的安装包&#xff0c;到自己的目…

虚拟化分类和实现原理

6、虚拟化分类 &#xff08;1&#xff09;完全虚拟化 直接将Hypervisor跑在0环内核态&#xff0c;客户机os跑在1环&#xff0c;一旦触发敏感指令&#xff0c;由0环的VMM进行捕获翻译&#xff0c;从而模 拟这些指令。而运行在1环的GuestOS永远都不知道自己是个虚拟机。是完全…

Stable Diffusion 系列教程 - 5 ControlNet

ControlNet和LORA的定位都是对大模型做微调的额外网络。作为入门SD的最后一块拼图是必须要去了解和开发的。为什么ControlNet的影响力如此的大&#xff1f;在它之前&#xff0c;基于扩散模型的AIGC是非常难以控制的&#xff0c;扩散整张图像的过程充满了随机性。这种随机性并不…

MySQL多表查询的方法(含例子)

我们查两张及以上表的时候&#xff0c;普通的查询语法(select * from 表名&#xff09;不能发挥作用。下面我演示两张表和三张表的查询方法。 前提&#xff1a; 如图存在三张表a&#xff0c;b&#xff0c;c&#xff1a;a表是学生基础信息&#xff0c;b表是教师学科信息&#…

想要学会JVM调优,先掌握JVM内存模型和JVM运行原理

1、前言 今天将和你一起探讨Java虚拟机&#xff08;JVM&#xff09;的性能调优。 JVM算是面试中的高频问题了&#xff0c;通常情况下总会有人问到&#xff1a;请你讲解下 JVM 的内存模型&#xff0c;JVM 的 性能调优做过&#xff1f; 2、为什么 JVM 在 Java 中如此重要 首…

近 300 个假冒应用程序泛滥成灾,淹没伊朗银行业

内容概述&#xff1a; 近期&#xff0c;针对伊朗银行业的大规模活动规模不断扩大&#xff0c;近 300 个恶意 Android 应用程序针对用户的账户凭据、信用卡和加密钱包发起攻击。四个月前&#xff0c;Sophos 的研究人员详细介绍了一场漫长的活动&#xff0c;涉及 40 个恶意银行应…