谁说程序员不浪漫——给女友放个烟花,安排!安排!
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谁说程序员不浪漫——给女友放个烟花,安排!安排!相关的知识,希望对你有一定的参考价值。
效果图(有背景音乐呦)
项目链接
https://download.csdn.net/download/weixin_45525272/18558896
搞起来
编译环境:vs2017 & EasyX
没有EasyX的小伙伴可以点击下面网盘链接进行下载安装,点击exe运行,选择你对应的vs版本点击安装即可
链接:https://pan.baidu.com/s/1pQbktxBd9u2gObg84eGRxg
提取码:za2k
复制这段内容后打开百度网盘手机App,操作更方便哦–来自百度网盘超级会员V4的分享
代码
注释比较详细,就不进行讲解了
#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;
}
以上是关于谁说程序员不浪漫——给女友放个烟花,安排!安排!的主要内容,如果未能解决你的问题,请参考以下文章
程序员的专属浪漫——用3D Engine 5分钟实现烟花绽放效果