烟花

520马上就要到了,学完c语言想要自己尝试给女朋友一个惊喜,属于程序员的浪漫,今天三玖就带你手把手打出烟花代码
学完c的小伙伴对于easyx有不懂的地方可以进入easyx的官网下载文档,里面对它的各种函数都进行了解释。
先准备两张图片
在这里插入图片描述

1.首先下载easyx库,在我们学习的初期,我们身为初学者要想尝试一些小项目,easyx是一个不错的选择。
2.安装完easyx后,我们打开自己的编译器,创建一个cpp的小项目,准备开始写代码。
3.首先将我们需要用到的头文件声明。

#include
#include
#include
#include
#include
#include//创建一个窗口及其进行一系列的操作
#define NUM 13//最多13个烟花

4.`在主函数内创建一个窗口

initgraph(1200, 800);

开始定义一个烟花的结构体
思考烟花有何属性
(1)坐标表示其位置
(2)存在最高点
(3)发射状态
(4)出现及消失时间等

struct Jet
{
     
	int x;
	int y;
	int hx;
	int hy;
	bool shoot;
	DWORD t1, t2, dt;
	MAGE img[2];
	byte n : 1;
}Jet[NUM];//烟花炸弹数组

5.初始化烟花
(1)烟花的出现时间不同;
(2)烟花的上升速度也不同等

void Init(int i)
{
     
	Jet[i].t1 = GetTickCount();
	Jet[i].dt = rand() % 10 + 1;//1-10ms
	Jet[i].n = 0;
	Jet[i].shoot = false;
}

6.将图片加载到窗口中
(1)首先将图片制定为一个文件夹,复制进入你的项目文件夹中去确保能够访问到图片
(2)`

void Loadimg()
{
     
	IMAGE image;//定义图片
	loadimage(&image, "./烟花/shoot.jpg", 200, 50);
	SetWorkingImage(&image);
	int n;
	for (int i = 0; i < NUM; i++)
	{
     
		n = rand() % 5;//0-4
		getimage(&Jet[i].img[0],n*20,0,20,50);
		getimage(&Jet[i].img[1], (n+5)*20,0,20,50);
	}
	SetWorkingImage(NULL);
	IMAGE Fireimg;
	IMAGE img;
	loadimage(&Fireimg, "./烟花/shoot2.jpg",3120,240);
	for (int i = 0; i < NUM; i++)
	{
     
		SetWorkingImage(&Fireimg);
		getimage(&img, i * 240, 0, 240, 240);
		SetWorkingImage(&img);

		for (int a = 0; a < 240; a++)
		{
     
			for (int b = 0; b < 240; b++)
			{
     
				Fire[i].xy[a][b] = getpixel(a, b);
			}
		}
	}
	SetWorkingImage(NULL);

}

7.烟花炸弹的定义及初始化同上

struct FIRE
{
     
	int r;
	int max_r;
	int x, y;//烟花爆炸点相对于窗口初始的坐标
	int cenx, ceny;//烟花中心相对于烟花图片的坐标
	int width, height;//图片高度及宽度
	int xy[240][240];//像素
	bool show;//是否开始显示
	bool draw;//是否开始渲染
	DWORD t1, t2, dt;
}Fire[NUM];
void Init(int i)
{
     
Fire[i].cenx=120;
	Fire[i].ceny=120;
	Fire[i].max_r = 120;
	Fire[i].width=240;
	Fire[i].height=240;
	Fire[i].dt=5;
	Fire[i].r=0;
	Fire[i].t1=GetTickCount();
	Fire[i].show=false;
}

8.开始考虑如何选择烟花
(1)很明显烟花的出现时间不同,存在时间间隔;
(2)在图片中有13张烟花,所以我们需要考虑随机取(rand);
(3)我们在开始时定义了窗口的大小,随机取必须考虑到取到窗口外的情况;
(4)下面我们考虑烟花是否发射时,在这必须保证它可以开始发射;

void Choice(DWORD  &t1)
{
     
	DWORD t2 = GetTickCount();
	if (t2 - t1 > 100)//时间间隔
	{
     
		int n = rand() % NUM;//随机
			if (Jet[n].shoot == false&&Fire[n].show==false)
			{
     
				Jet[n].x = rand() % 1180;
				Jet[n].y = rand() % 100 + 600;//
				Jet[n].hx = Jet[n].x;
				Jet[n].hy =rand()%400;
				Jet[n].shoot = true;
				putimage(Jet[n].x, Jet[n].y, &Jet[n].img[Jet[n].n], SRCINVERT);
			}
			
			t1 = t2;
	}
}

9.开始考虑发射状态的烟花
(1)首先思考烟花的状态是否满足发射;
(2)发射后到达最高点时该怎么处理;
(3)开始承接烟花爆炸的开始;

void Shoot()
{
     
	for (int i = 0; i < NUM; i++)
	{
     
		//速度     //是否发射
		Jet[i].t2 = GetTickCount();
		if (Jet[i].t2 - Jet[i].t1 > Jet[i].dt && Jet[i].shoot == true)
		{
     
			putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT);
			if (Jet[i].y >= Jet[i].hy)
			{
     
				Jet[i].y -= 5;//上升
				Jet[i].n++;
			}
			putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT);
			if (Jet[i].y <= Jet[i].hy)//到达最高点
			{
     
				putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT);
				Fire[i].x=Jet[i].x;
				Fire[i].y = Jet[i].y;//传递给烟花的最高点
				Fire[i].show = true;
				Jet[i].shoot = false;
			}
			Jet[i].t1 = Jet[i].t2;
		}
	}
}

10.烟花到达最高点烟花炸弹开始准备
(1)首先考虑爆炸的速度是否相同;
(2)烟花到达最高点烟花及烟花炸弹的半径的判断及处理;
(3)判断是否开始渲染像素
(4)利用位字段开始将图片渲染;

void SHOWFIRE(DWORD* pmem)
{
     
	int drt[16] = {
      5,5,5,5,5,8,25,25,25,25,55,55,65,65,65,70 };//爆炸速度
	for (int i = 0; i < NUM; i++)
	{
     
		Fire[i].t2 = GetTickCount();
		if (Fire[i].t2 - Fire[i].t1 >= Fire[i].dt && Fire[i].show == true)
		{
     
			if (Fire[i].r < Fire[i].max_r)
			{
     
				Fire[i].r++;
				Fire[i].dt = drt[Fire[i].r / 10];
				Fire[i].draw = true;
			}
			if (Fire[i].r >= Fire[i].max_r - 1)//爆炸到最大半径
			{
     
				Fire[i].draw = false;
				Init(i);
			}
			Fire[i].t1 = Fire[i].t2;
		}
		if (Fire[i].draw)
		{
     
			for (double a = 0; a <= 6.28; a += 0.01)
			{
     
				int x1 =  Fire[i].cenx+Fire[i].r * cos(a);
				int y1 =  Fire[i].ceny+ Fire[i].r * sin(a);
				if (x1 > 0 && x1 < 240 && y1>0 && y1 < 240)
				{
     
					int b = Fire[i].xy[x1][y1] & 0xff;
					int g= Fire[i].xy[x1][y1] >>8 & 0xff;
					int r= Fire[i].xy[x1][y1]>>16;
					int x2 = Fire[i].x + Fire[i].r * cos(a);
					int y2 = Fire[i].y + Fire[i].r * sin(a);

					if (r > 0x20 && g > 0x20 && b > 0x20 && x2 > 0 && x2 < 1200 && y2>0 && y2 < 800)
					{
     
						pmem[y2 * 1200 + x2] = BGR(Fire[i].xy[x1][y1]);
					}
				}
			}
			Fire[i].draw = false;
		}
	}
}

11.主函数内函数调用

int main(void)
{
     
	initgraph(1200, 800);
	srand(time(NULL));
	DWORD t1 = GetTickCount();
	DWORD* pmem = GetImageBuffer();
	Loadimg();
	for (int i = 0; i < NUM; i++)
	{
     
		Init(i);
	}
	BeginBatchDraw();
	while (1)
	{
     
		Choice( t1);
		Shoot();
		SHOWFIRE(pmem);
		FlushBatchDraw();
	}
	getchar();
	return 0;
}

12.最后新手发表,不喜勿喷。(此代码均为自己查询资料,搜集视频,纯手打)

你可能感兴趣的:(笔记,c语言)