谁说程序员不浪漫——给女友放个烟花,安排!安排!

2021/6/12 20:27:33

本文主要是介绍谁说程序员不浪漫——给女友放个烟花,安排!安排!,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

 

效果图(有背景音乐呦)

在这里插入图片描述
在这里插入图片描述

 

代码

注释比较详细,就不进行讲解了

#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <graphics.h>  // 头文件
#pragma comment(lib,"Winmm.lib")

#define NUM 13

// 烟花弹的结构体
struct Jet
{
	int     x, y;           // 当前的坐标
	int     hx, hy;         // 最高点的x y
	bool    shoot;          // 是否发射
	DWORD   t1, t2, dt;     // 发射速度!!  t1 t2 发射速度
	IMAGE   img[2];         // 两张小图片
	byte    n : 1;          // 位段 n是一个变量 1个位。
}jet[NUM];

// 烟花去图片里截取
struct Fire
{
	int     r;
	int     max_r;
	int     cen_x, cen_y;   // 圆心
	int     x, y;           // 图片在界面中的 坐标
	int     width, height;  // 图片的宽度 高度
	int     xy[240][240];   // 像素矩阵

	bool   show;
	bool   draw;
	DWORD  t1, t2, dt;		// 绽放的速度   就可以相当于像素
}fire[NUM];

void LoadImg()
{
	// EasyX 中的图片类型
	IMAGE allflowers, flower;
	loadimage(&allflowers, L"flower.jpg", 3120, 240);

	for (int i = 0; i < NUM; i++)
	{
		SetWorkingImage(&allflowers);				// 设置当前绘图设备 为 所有的烟花 
		getimage(&flower, i * 240, 0, 240, 240);	// 截取小烟花
		SetWorkingImage(&flower);					// 从flower 像素点保存在一个二维数组 并 设置为当前绘图设备

		for (int x = 0; x < 240; x++)
		{
			for (int y = 0; y < 240; y++)
			{
				fire[i].xy[x][y] = getpixel(x, y);	// 获取点的颜色 到每个小flower矩阵中
			}
		}
	}

	IMAGE jetImg;  // 图片类型
	loadimage(&jetImg, L"shoot.jpg", 200, 50);	
	SetWorkingImage(&jetImg); // 从jetImg去获取小图片
	// 13种
	for (int i = 0; i < NUM; i++)
	{
		int 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);
}

void GameInit(int n)
{
	// 13个烟花的半径  中心坐标
	int r[13] = { 120, 120, 155, 123, 130, 147, 138, 138, 130, 135, 140, 132, 155 };
	int x[13] = { 120, 120, 110, 117, 110, 93, 102, 102, 110, 105, 100, 108, 110 };
	int y[13] = { 120, 120, 85, 118, 120, 103, 105, 110, 110, 120, 120, 104, 85 };

	fire[n].cen_x = x[n];
	fire[n].cen_y = y[n];
	fire[n].max_r = r[n];
	fire[n].show = false;
	fire[n].width = 240;
	fire[n].height = 240;
	fire[n].dt = 5;
	fire[n].r = 0;
	fire[n].t1 = GetTickCount();

	// 简单的初始化了一些数据
	jet[n].dt = rand() % 10 + 1;  // 1-10ms
	jet[n].n = 0;
	jet[n].t1 = GetTickCount();
	jet[n].shoot = false;
}

// 选择烟花弹 
void Chiosejet(DWORD& t1)  // t1 t2做产生新的烟花弹的间隔。
{
	DWORD t2 = GetTickCount();

	if (t2 - t1 > 100)  // 100ms 产生一个新的 烟花弹
	{
		// rand()%13;  0-12
		int n = rand() % NUM;  // 随机选一个
		if (jet[n].shoot == false && fire[n].show == false)  // 判断是否发射 未发射的状态
		{
			jet[n].x = rand() % 1200;
			jet[n].y = rand() % 100 + 600; // 600-699
			jet[n].hx = jet[n].x;
			jet[n].hy = rand() % 400;     // 0-399
			jet[n].shoot = true;            // 选中
			putimage(jet[n].x, jet[n].y, &jet[n].img[jet[n].n], SRCINVERT);
		}
		t1 = t2;
	}
}

// 显存  
void Shootjet()
{
	for (int n = 0; n < NUM; n++)
	{
		jet[n].t2 = GetTickCount();
		if (jet[n].t2 - jet[n].t1 >= jet[n].dt&&jet[n].shoot == true)
		{
			putimage(jet[n].x, jet[n].y, &jet[n].img[jet[n].n], SRCINVERT);
			if (jet[n].y >= jet[n].hy)
			{
				jet[n].y -= 5;  // 上升
				jet[n].n++;     // 闪烁
			}
			putimage(jet[n].x, jet[n].y, &jet[n].img[jet[n].n], SRCINVERT);

			if (jet[n].y <= jet[n].hy) // 说明已经上升到最高点
			{
				putimage(jet[n].x, jet[n].y, &jet[n].img[jet[n].n], SRCINVERT);
				jet[n].shoot = false;
				fire[n].x = jet[n].hx;
				fire[n].y = jet[n].hy;
				fire[n].show = true;
				// 爆炸
			}
			jet[n].t1 = jet[n].t2;
		}
	}
}

// 烟花显示
void ShowFire(DWORD* pmem)
{
	int drt[16] = { 5, 5, 5, 5, 5, 6, 25, 25, 25, 25, 55, 55, 55, 55, 65, 65 };

	// 实践出真知
	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;
				GameInit(i);
			}
			fire[i].t1 = fire[i].t2;
		}

		if (fire[i].draw)
		{
			// 弧度
			for (double a = 0; a <= 6.28; a += 0.01)
			{
				// 圆的参数方程
				int x1 = (int)(fire[i].cen_x + fire[i].r*cos(a));
				int y1 = (int)(fire[i].cen_y + fire[i].r*sin(a));

				if (x1 > 0 && x1 < fire[i].width&&y1>0 && y1 < fire[i].height)
				{
					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 xx = (int)(fire[i].x + fire[i].r*cos(a));
					int yy = (int)(fire[i].y + fire[i].r*sin(a));

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

int main()
{
	// 初始化图形界面 打开一个窗口。1200  800
	initgraph(1200, 800);        // 1200*800
	mciSendString(L"open 小幸运.mp3 alias bgm", 0, 0, 0);
	mciSendString(L"play bgm", 0, 0, 0);

	DWORD t1 = GetTickCount();
	DWORD *pmem = GetImageBuffer();  //  获取绘图设备的显存指针
	// 随机数的种子
	srand((unsigned int)time(NULL));
	// 处理加载图片
	LoadImg();

	for (int i = 0; i < NUM; i++)
	{
		GameInit(i);
	}
	BeginBatchDraw();	// 开始批量绘制
	while (1)
	{
		Chiosejet(t1);
		Shootjet();
		ShowFire(pmem);
		FlushBatchDraw();
	}
	return 0;
}

 



这篇关于谁说程序员不浪漫——给女友放个烟花,安排!安排!的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程