【c语言】飞机大战2

1.优化边界问题

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

边界优化

对应的代码实现

c 复制代码
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.首先创建一个子弹的结构体,并创建我方飞机子弹的头节点

c 复制代码
typedef struct bullet
{
	float x, y;
	float vx, vy;
	int  isexist;
	struct bullet* next;

}list;
list* planebullet = NULL;

2.创建新结点

c 复制代码
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 尾插新结点.

c 复制代码
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.结点的删除

c 复制代码
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.子弹位置改变参数设置

c 复制代码
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.贴子弹上去

c 复制代码
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函数里面加

c 复制代码
	if (GetAsyncKeyState(VK_SPACE))// && Timer(300, 1))
	{

		
			pushback1(&planebullet, 0, -20);
		
		

	}

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

子弹发射

7.解决子弹太密集问题

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

c 复制代码
bool Timer(int ms, int id)
{
	static DWORD t[10];

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

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

	return false;
}

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

c 复制代码
	if ((GetAsyncKeyState(VK_SPACE))&& Timer(300, 1))
	{

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

	}

8.子弹升级

子弹升级

c 复制代码
	if ((GetAsyncKeyState(VK_SPACE))&& Timer(300, 1))
	{

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

	}

3.敌方的子弹发射

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

敌机a子弹的发射

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

c 复制代码
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函数里面

c 复制代码
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.程序源码

c 复制代码
#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.效果演示

效果演示

相关推荐
Reese_Cool13 分钟前
【C++】从C语言到C++学习指南
c语言·c++·1024程序员节
skaiuijing2 小时前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
Ocean☾4 小时前
C语言-详细讲解-P1217 [USACO1.5] 回文质数 Prime Palindromes
c语言·数据结构·算法
Non importa5 小时前
汉诺塔(hanio)--C语言函数递归
c语言·开发语言·算法·学习方法
搬砖的小码农_Sky6 小时前
C语言:字符串
c语言·开发语言
qiaoqiaohonghu8 小时前
c/c++ 用easyx图形库写一个射击游戏
c语言·c++·游戏
2401_858286119 小时前
L13.【LeetCode笔记】合并两个有序数组
c语言·开发语言·数据结构·笔记·算法·leetcode
Legendary_00811 小时前
LDR6020驱动的Type-C接口显示器解决方案
c语言·开发语言·计算机外设
苏言の狗11 小时前
CCF认证202406-01 | 矩阵重塑(其一)
c语言·数据结构·c++·算法·矩阵
java 乐山11 小时前
ThinkPad t61p 作SMB服务器,打印服务器,pc ,android ,ipad利用此服务器互传文件
c语言