【c语言】飞机大战2

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.mfbz.cn/a/281735.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

centos7安装nginx并安装部署前端

目录&#xff1a; 一、安装nginx第一种方式&#xff08;外网&#xff09;第二种方式&#xff08;内网&#xff09; 二、配置前端项目三、Nginx相关命令 好久不用再次使用生疏&#xff0c;这次记录一下 一、安装nginx 第一种方式&#xff08;外网&#xff09; 1、下载nginx ng…

Jenkins基础教程

目录 第一章、快速了解Jenkins1.1&#xff09;Jenkins中一些概念介绍1.2&#xff09;Jenkins和maven用途上的区别1.3&#xff09;为什么使用Jenkins1.4&#xff09;学习过程中的疑问 第二章、安装Jenkins2.1&#xff09;安装之前的准备2.2&#xff09;Windows中Jenkins下载安装…

DrGraph原理示教 - OpenCV 4 功能 - 单通道图

通道 OpenCV的核心处理对象是Mat&#xff0c;大体是一个二维数组&#xff0c;加上了各种功能函数。 很多的图像处理&#xff0c;会在单通道或二值化的基础上进行&#xff0c;比如连通域、目标识别等。这里的通道就是channels。 不同的图像处理算法可能对通道数有特定的要求。例…

计算机组成原理复习6

总线结构与控制练习题 计算机系统为什么采用总线结构&#xff1f; 解析&#xff1a;在冯诺依曼计算机体系当中&#xff0c;把计算机基本组成分成了五大部分。运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设备和输出设备。我们可以把运算器和控制器制作在一个芯…

字符串与模拟法

加密英文 输入一个字符串可用getline(cin,数组名) 字典序 在字符串中寻找子字符串 分糖果 代码 猴子选大王 代码 如果n号猴子被选中&#xff0c;则使得n号的猴子变成false&#xff0c;未出局的猴子为true。 if(pn1) p1;这个是将超出的下标重新变回1号&#xff0c;使其重新循…

DNS域名查询过程

目录 DNS&#xff08;Domain Names System&#xff09; 域名转IP IP转域名 域名 域名查询流程 浏览器DNS缓存 操作系统缓存 本地host文件 完整流程 递归查询 迭代查询 DNS&#xff08;Domain Names System&#xff09; 域名系统&#xff0c;将域名和 IP 地址进行转…

模型 冰山理论

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。冰山下面才是重点。 1 冰山理论的应用 1.1 冰山理论在生活中的常见应用 人际交往&#xff1a;在人际交往中&#xff0c;很多人只关注表面的行为和语言&#xff0c;而忽略了内在的情感和动…

免费的云服务器推荐~三丰云

对于许多初创企业和小型公司来说&#xff0c;寻找一个经济实惠且可靠的云服务提供商是至关重要的。在这方面&#xff0c;三丰云以其免费虚拟主机和云服务器吸引了大量用户。 1. 注册与界面 注册三丰云的账户过程简单明了&#xff0c;只需按照步骤填写必要信息即可。其界面设计…

Unity之地形的构建

PS&#xff1a;公司没活干&#xff0c;好无聊偷偷摸鱼学Unity&#xff0c;害怕自己学完之后忘记&#xff0c;写下这一篇博客 先来看一下效果图&#xff1a;有山有水有树有草地 创建一个新的Unity3D项目 这里要用到Unity官方的免费资源包&#xff08;现在好像已经下架了百度网盘…

Mybatis分页插件之PageHelper生效and失效原理解析

文章目录 前言整合PageHelperPageHelper生效原理PageHelper的分页参数和线程绑定核心拦截逻辑生成分页SQLdialect.afterAll() PageHelper失效原理分页失效案例分页失效原理总结 Mybatis拦截器系列文章&#xff1a;从零开始的 MyBatis 拦截器之旅&#xff1a;实战经验分享 构建自…

S32K312使用ITCM向FLASH代码区写入数据

使用C40_IP的系列方法向FLASH代码区写入数据时&#xff0c;程序会卡死在读取写操作的状态C40_Ip_MainInterfaceWriteStatus()这个方法中。本文主要介绍S32K312通过ITCM的方式&#xff0c;通过C40_IP的方法向FLASH代码区成功写入数据的方法和步骤。 首先&#xff0c;验证一下C4…

macos下php 5.6 7.0 7.4 8.0 8.3 8.4全版本PHP开发环境安装方法

在macos中如果使用brew 官方默认的core tap 只可以安装官方最新的稳定版PHP, 如果想要安装 php 5.6 或者 php 8.4版本的PHP就需要使用第三方的tap , 这里分享一个比较全面的brew tap shivammathur/php 这个tap里面包含了从php5.6到最新版php8.4的所有可用最新版本PHP, 而且是同…

python大于等于小于等于,python大于等于怎么写

大家好&#xff0c;小编为大家解答python中大于等于且小于等于的问题。很多人还不知道python大于号小于号如何运用&#xff0c;现在让我们一起来看看吧&#xff01; 大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python中大于并小于一个数代码&#xff0c;python 大…

数据结构【线性表篇】(二)

数据结构【线性表篇】(二&#xff09; 文章目录 数据结构【线性表篇】(二&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录一、单链表(一)、单链表的定义(二)、单链表的建立(三)、单链表的插入删除(四)、单链表的查找 二、主函…

springBoot2.3-基本介绍及入门案例

本次学习雷丰阳springBoot(2.3版本)。建议先修ssm 一、SpringBoot基本介绍 springBoot是当今最为流行的java开发框架。 1、springBoot的底层是spring&#xff0c; 因此继承了spring的粘合其他框架的能力。 2、本质上还是其他框架包括spring在工作 , springBoot起到一个整合其他…

LeetCode刷题--- 黄金矿工

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述…

基于SSM的学生信息管理系统

基于SSM的学生信息管理系统资源-CSDN文库 项目介绍 学生管理系统是我从自己学校的综合信息平台得到灵感&#xff0c;于是使用学习过的Spring、SpringMVC、Mybatis框架LayUI完成了这么一套系统。 项目整体难度不大&#xff0c;部署简单&#xff0c;界面友好&#xff0c;代码结…

免费API-JSONPlaceholder使用手册

官方使用指南快速索引>>点这里 快速导览&#xff1a; 什么是JSONPlaceholder?有啥用?如何使用JSONPlaceholder? 关于“增”关于“改”关于“查”关于“删”关于“分页查”关于“根据ID查多个” 尝试自己搭一个&#xff1f;扩展的可能&#xff1f; 什么是JSONPlaceho…

机器学习(一) -- 概述

系列文章目录 机器学习&#xff08;一&#xff09; -- 概述 机器学习&#xff08;二&#xff09; -- 数据预处理 未完待续…… 目录 系列文章目录 前言 一、机器学习定义&#xff08;是什么&#xff09; 二、机器学习的应用&#xff08;能做什么&#xff09; 三、***机器…

ArkUI动画概述

目录 1、按照页面分类 2、按照功能分类 3、显示动画 4、属性动画 动画的原理是在一个时间段内&#xff0c;多次改变UI外观&#xff0c;由于人眼会产生视觉暂留&#xff0c;所以最终看到的就是一个“连续”的动画。UI的一次改变称为一个动画帧&#xff0c;对应一次屏幕刷新&a…
最新文章