前言
之前看到“粒子消散”的特效组件,于是就产生想法(自己也弄个特效组件应该挺有意思的)。这个烟花特效可以添加到游戏胜利的界面中,可能还有其他应用场景哈哈~。这也算是我做的第一个组件原创demo啦,欢迎各位评论区指导一下O(∩_∩)O
概述
效果图如下
有三种模式可以选择,一种是图案只有五角星,一种是图案只有三角形,还有一种是图案既有五角星又有三角星。颜色有10种,还有背景音乐(自己DIY的烟花音效)!话不多说,开整!
正文
1.创建一个空白的工程
DevEco Studio下载安装成功后,打开DevEco Studio,点击左上角的File,点击New,再选择New Project,选择Empty Ability,然后点击Next,给项目命名Framework,选择设备类型Phone,选择语言类型JS最后点击Finish。
代码删除的部分
在entry>src>main>js>default>pages.index>index.hml 文件里把以下代码删掉
在entry>src>main>js>default>pages.index>index.js 文件里把以下代码删掉
在entry>src>main>js>default>pages.index>index.css 文件里把container部分以下的代码删掉
2.布局设计
index.hml
该组件是画布组件,画布的大小是整个屏幕,而按钮是显示画布上方的,所以要添加个栈组件,依次放入画布组件和按钮组件。代码如下👇,注意这里画布组件添加了触摸事件touchstartfunc,下文会讲解这步。
index.css
给画布组件和按钮组件设置属性,代码如下👇
此时打开模拟器,你就能得到上面效果图左1图,接下来做功能实现部分。
3.绘制图案
五角星
函数 draw_star 传的参数分别是烟花释放的圆心坐标,图案的颜色,图案移动的斜率,图案是否填充颜色。定义的变量中,x和y是图案中心的坐标,根据时间推移(会设定定时器,下文会讲)move_times增加,图案会沿着传进来的斜率方向作直线移动,以达到烟花绽放的效果。变量a-h都是为了便于绘制五角星的图案而设的公式参数值,全局变量r_star是五角星的边长,最后根据公式去绘制单个五角星图案
index.js
先在export default上方定义变量
然后在export default下方添加代码:
三角星
同样, draw_triangle 是绘制单个三角形并沿设定斜率移动的函数,函数的参数类型及作用与五角星的一致。全局变量r_triangle为三角形的边长,代码如下👇
图案的美化
设置了10种颜色的颜色字典,通过绘制图案函数draw中的参数 color 去控制颜色(黑色是作保护作用),颜色可通过单独设置数字1-10来选择,也可以通过随机数(1~10)去随机变化颜色。颜色填充也是如此,1为不填充,2为填充,也可随机产生1或2来随机变化是否填充颜色。
draw函数中,在ctx.lineWidth下方,在ctx.beginPath上方添加代码:
在ctx.stroke下方添加代码
draw开头的函数是绘制单个图案,接下来的Draw函数是绘制8个或10个图案围成圆形向外同速率扩展的图像,run开头的函数是被循环的函数
4.绘制烟花
烟花的布局
绽放的烟花的形状是一个圆形,火花为单个图案。我设计了两种烟花绽放数量,一种是一个圆中有8个图案的,一种是一个圆中有10个图案的,它们的斜率都通过数学公式定义好了(如下的全局变量所示),单个图案沿斜率方向每次移动的距离为全局变量R的数值。
Draw_Star_8(click_x,click_y){
this.draw_Star(click_x,click_y,1,-R,0,Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,2,-R/Math.sqrt(2),-R/Math.sqrt(2),Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,3,0,-R,Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,4,R/Math.sqrt(2),-R/Math.sqrt(2),Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,5,R,0,Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,6,R/Math.sqrt(2),R/Math.sqrt(2),Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,7,0,R,Math.floor(Math.random()*2 + 1));
this.draw_Star(click_x,click_y,8,-R/Math.sqrt(2),R/Math.sqrt(2),Math.floor(Math.random()*2 + 1));
},
Draw_Star_10(click_x,click_y,fill){
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),-R,0,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),-s,-t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),-v,-w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),v,-w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),s,-t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),R,0,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),s,t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),v,w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),-v,w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10 + 1),-s,t,fill);
},
Draw_Triangle_8(click_x,click_y,fill){
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1),-R, 0, fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1),-R/Math.sqrt(2),-R/Math.sqrt(2),fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1), 0, -R, fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1), R/Math.sqrt(2),-R/Math.sqrt(2),fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1), R, 0, fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1), R/Math.sqrt(2),R/Math.sqrt(2), fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1), 0, R, fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10 + 1),-R/Math.sqrt(2),R/Math.sqrt(2), fill);
},
Draw_Triangle_10(click_x,click_y){
this.draw_Triangle(click_x,click_y,1,-R,0, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,2,-s,-t,Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,3,-v,-w,Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,4,v,-w, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,5,s,-t, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,6,R,0, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,7,s,t, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,8,v,w, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,9,-v,w, Math.floor(Math.random()*2 + 1));
this.draw_Triangle(click_x,click_y,10,-s,t,Math.floor(Math.random()*2 + 1));
},
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
火花的移动
上述提过一个movetimes,火花的移动无非就是坐标的变化,通过设置一个定时器,循环绘制图案就能实现移动的效果,先构造一个被循环的函数run_star(举五角星的实例,三角形同理;位置,美化等的参数随意),代码如下
然后添加定时器
点击按钮“五角星”时会释放图案为五角星的烟花
此时,打开模拟器,你会看到图案移动了,但上一个图案没有清除

所以要给被循环的函数添加一个清空操作(为了保护清空函数,要先在清空前加点东西),在this.Draw函数之前添加以下代码:
烟花的结束
按上述步骤下来,会发现烟花的圆形越来越大,最终出界。
为了实现烟花的结束,可以根据movetimes的增加次数来控制烟花绽放范围的大小。通过透明度的递减,最终透明度减为0,图案消失
在draw函数里的开头位置添加以下代码:
烟花的循环绽放
在draw函数里的开头位置添加以下代码:
同理可以设置“三角形”和“混合”的被循环函数
5.点击处绽放烟花
先获取点击处相对于画布组件左上角的坐标,然后作为新烟花绽放的圆心坐标传参,这里的click_b1,click_b2下文会讲解
6.烟花图案的切换
通过设定布尔型变量来控制点击另一个按钮时,清空上一个按钮运行的定时器
7.背景音乐的添加
js模板中添加音频可以去看我之前的文章.
index.hml
index.js
在src/common/下加入音频文件
别忘了生命周期的设置,在应用启动时自动播放音频,在应用隐藏的时候暂停播放音频并清空所有定时器,在应用销毁时清空所有定时器,停止播放音频。
结语
以上就是我这次的小分享啦❀❀!自己的第一个demo开发,略微粗糙,欢迎各位评论区指导一下O(∩_∩)O
本文正在参与51CTO HarmonyOS技术社区创作者激励-星光计划1.0
很有意思的效果,前排支持一波
谢谢支持O(∩_∩)O
支持 学习~
学习了学习了,感觉我学前端的时候也可以直接用DES创建项目,再鸿蒙里面实现。一举两得
烟花特效组件开发,666,是个不错的学习项目。
谢谢支持😄
又一位程序员女神,666,学习一下