• Dev-C++使用EGE绘图库实现燃放灿烂烟花的编写和发布


    Dev-C++使用EGE绘图库实现燃放灿烂烟花的编写和发布


    前提是为Dev-C++配置EGE绘图库,详见
    Dev-C++ 使用EGE绘图库编程入门  https://blog.csdn.net/cnds123/article/details/109982100

    灿烂烟花程序的编写

    灿烂烟花程序的目录结构:

    背景图片:

     背景音乐自己找个吧,文件名 背景音乐.mp3

    燃放烟花.cpp 文件内容如下:

    1. #include
    2. #include
    3. #include "fireworks.cpp"
    4. #include "fireworks.h"
    5. #define NUM_FIREWORKS 12 //烟花数量,12左右比较好,多了太密集
    6. int main()
    7. {
    8. initgraph(860, 660, INIT_RENDERMANUAL);
    9. srand((unsigned)time(NULL));
    10. //烟花
    11. Fireworks* fireworks = new Fireworks[NUM_FIREWORKS];
    12. //背景图(860 x 660)
    13. PIMAGE bgPimg = newimage();
    14. getimage(bgPimg, "背景图片.jpg");
    15. //先绘制一下,不然前面有空白期
    16. putimage(0, 0, bgPimg);
    17. delay_ms(0);
    18. //背景音乐
    19. MUSIC bgMusic;
    20. bgMusic.OpenFile("背景音乐.mp3");
    21. bgMusic.SetVolume(1.0f);
    22. if (bgMusic.IsOpen()) {
    23. bgMusic.Play(0);
    24. }
    25. //图像缓存, 因为要加背景图,直接加模糊滤镜会把背景图模糊掉
    26. //所以另设一个图像缓存来绘制烟花并加模糊滤镜,再绘制到窗口
    27. PIMAGE cachePimg = newimage(860, 660);
    28. //计时用,主要用来定时检查音乐播放
    29. int timeCount = 0;
    30. for (; is_run(); delay_fps(60))
    31. {
    32. //隔1秒检查一下,如果播放完了,重新播放
    33. if ((++timeCount % 60 == 0) && (bgMusic.GetPlayStatus() == MUSIC_MODE_STOP)) {
    34. bgMusic.Play(0);
    35. }
    36. //更新位置
    37. for (int i = 0; i < NUM_FIREWORKS; i++) {
    38. fireworks[i].update();
    39. }
    40. //绘制背景
    41. putimage(0, 0, bgPimg);
    42. //绘制烟花到图像缓存中
    43. for (int i = 0; i < NUM_FIREWORKS; i++) {
    44. fireworks[i].draw(cachePimg);
    45. }
    46. //模糊滤镜,拖尾效果
    47. //第二个参数,模糊度,越大越模糊,粒子也就越粗
    48. //第三个参数,亮度,越大拖尾越长
    49. //可以试试一下其它参数搭配,例如以下几组:
    50. //0x03, 0xff
    51. //0x0b, 0xe0
    52. //0xff, 0xff
    53. imagefilter_blurring(cachePimg, 0x0a, 0xff);
    54. //缓存绘制到窗口,模式为(最终颜色 = 窗口像素颜色 Or 图像像素颜色), 这样颜色会叠加起来
    55. putimage(0, 0, cachePimg, SRCPAINT);
    56. }
    57. delete[] fireworks;
    58. delimage(bgPimg);
    59. delimage(cachePimg);
    60. bgMusic.Close();
    61. closegraph();
    62. return 0;
    63. }

    fireworks.cpp 文件内容如下:

    1. #include
    2. #define SHOW_CONSOLE
    3. #include "fireworks.h"
    4. const double Fireworks::particleSpeed = 3.0f;
    5. Fireworks::Fireworks()
    6. {
    7. init();
    8. }
    9. void Fireworks::init()
    10. {
    11. delayTime = rand() % 300 + 20;
    12. riseTime = rand() % 80 + 160;
    13. bloomTime = 160;
    14. risePos.x = rand() % 450 + 300.0f;
    15. risePos.y = GROUND;
    16. riseSpeed.y = myrand(1.0f) - 3.0f; //上升速度,根据坐标系需要是负的
    17. riseSpeed.x = myrand(0.4f) - 0.2f; //可稍微倾斜
    18. //随机颜色
    19. color = HSVtoRGB(myrand(360.0f), 1.0f, 1.0f);
    20. //给每一个粒子设置初始速度
    21. for (int i = 0; i < NUM_PARTICLE - 1; i += 2)
    22. {
    23. //为了球状散开,设初始速度大小相等
    24. //初始随机速度水平角度和垂直角度,因为看到是平面的,所以求x, y分速度
    25. double levelAngle = randomf() * 360;
    26. double verticalAngle = randomf() * 360;
    27. //速度投影到xOy平面
    28. double xySpeed = particleSpeed * cos(verticalAngle);
    29. //求x, y分速度
    30. p[i].speed.x = xySpeed * cos(levelAngle);
    31. p[i].speed.y = xySpeed * sin(levelAngle);
    32. //动量守恒,每对速度反向
    33. if (i + 1 < NUM_PARTICLE) {
    34. p[i + 1].speed.x = -p[i].speed.x;
    35. p[i + 1].speed.y = -p[i].speed.y;
    36. }
    37. }
    38. }
    39. void Fireworks::draw(PIMAGE pimg)
    40. {
    41. //未开始
    42. if (delayTime > 0)
    43. return;
    44. //烟花上升阶段
    45. else if (riseTime > 0) {
    46. setfillcolor(color, pimg);
    47. //画四个点,这样大一些
    48. bar(risePos.x, risePos.y, risePos.x + 2, risePos.y + 2, pimg);
    49. }
    50. //烟花绽放阶段
    51. else {
    52. setfillcolor(color, pimg);
    53. for (int i = 0; i < NUM_PARTICLE; i++) {
    54. bar(p[i].pos.x, p[i].pos.y, p[i].pos.x + 2, p[i].pos.y + 2, pimg);
    55. }
    56. }
    57. }
    58. //更新位置等相关属性
    59. void Fireworks::update()
    60. {
    61. if (delayTime-- > 0)
    62. return;
    63. //处于上升阶段,只更新烟花位置
    64. else if (riseTime > 0) {
    65. risePos.x += riseSpeed.x;
    66. risePos.y += riseSpeed.y;
    67. //重力作用
    68. riseSpeed.y += 0.005;
    69. //上升完毕,到达爆炸阶段
    70. if (--riseTime <= 0) {
    71. //设粒子初始位置为烟花当前位置
    72. for (int i = 0; i < NUM_PARTICLE; i++) {
    73. p[i].pos.x = risePos.x;
    74. p[i].pos.y = risePos.y;
    75. }
    76. }
    77. }
    78. //烟花绽放阶段
    79. else if (bloomTime-- > 0) {
    80. //粒子散开,更新粒子位置
    81. for (int i = 0; i < NUM_PARTICLE; i++) {
    82. p[i].pos.x += p[i].speed.x;
    83. p[i].pos.y += p[i].speed.y;
    84. //重力作用
    85. p[i].speed.y += 0.005;
    86. //速度减慢
    87. p[i].speed.x *= 0.982;
    88. p[i].speed.y *= 0.982;
    89. }
    90. }
    91. else {
    92. //烟花重新开始
    93. init();
    94. }
    95. }

    fireworks.h 文件内容如下:

    1. #pragma once
    2. #ifndef FIREWORKS_H_
    3. #define FIREWORKS_H_
    4. #include
    5. #define myrand(m) ((float)rand() * m / 36565)
    6. struct Speed {
    7. double x, y;
    8. };
    9. struct Pos {
    10. double x, y;
    11. };
    12. struct Particle
    13. {
    14. Pos pos;
    15. Speed speed;
    16. };
    17. #define GROUND 580 //地面位置
    18. class Fireworks//烟花类
    19. {
    20. private:
    21. static const int NUM_PARTICLE = 200;
    22. static const double particleSpeed;
    23. Particle p[NUM_PARTICLE];
    24. color_t color;
    25. int delayTime; //延迟时间
    26. int riseTime; //上升时间
    27. int bloomTime; //爆炸时间
    28. Pos risePos; //上升阶段位置
    29. Speed riseSpeed; //上升速度
    30. public:
    31. //初始化
    32. Fireworks();
    33. void init();
    34. //更新位置等相关属性
    35. void update();
    36. //根据属性值绘画
    37. void draw(PIMAGE pimg = NULL);
    38. };
    39. #endif // ! FIREWORKS_H_

    灿烂烟花程序的发布

    使用菜单命令“Execute -> Compile”编译之,

    若没有错误,得到可执行程序:燃放烟花.exe

    新建一个文件夹,我这里是“灿烂烟花发布”,将前面得到的可执行程序“燃放烟花.exe”,和资源文件,这里是 “背景音乐.mp3” 和 “背景图片.jpg” 复制到,这个文件夹中。然后复制“灿烂烟花发布”文件夹给好朋友试试吧。

     

    双击“燃放烟花.exe”,运行效果如下:

    OK !

  • 相关阅读:
    main函数的数组参数是干嘛用的
    详解 localStorage、sessionStorage和cookie区别
    java毕业设计—— 基于java+JSP+SSH的婴幼儿产品销售系统设计与实现(毕业论文+程序源码)——婴幼儿产品销售系统
    数据结构之“算法的时间复杂度和空间复杂度”
    当找不到对应版本依赖的时候,点击右上角的maven标志来解决!
    Shell-条件控制语句2
    【面试题】前端面试小知识 <4>
    MySQL:表的约束
    Open3D(C++)欧式聚类分割
    Qt插件系统
  • 原文地址:https://blog.csdn.net/cnds123/article/details/126328433