粒子特效[3] - 爆炸烟花

用到的图片:

star dot ring hex hex_ring

废话不多说 shou you my code

1
2
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/6.0.2/browser/pixi.js"></script>
<div id="preview-box" style="text-align:center"></div>
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
function times(num, fn) {
for (let i = 0; i < num; i++) {
fn()
}
}
let game = new PIXI.Application({
width: 1334,
height: 750,
backgroundColor: 0x000000
})
document.getElementById('preview-box').appendChild(game.view)
game.view.style.width = "100%"
let config = {crossOrigin:true}
PIXI.Assets.add('dot', '../images/dot.png',config);
PIXI.Assets.add('hex', '../images/hex.png',config)
PIXI.Assets.add('ring', '../images/ring.png',config)
PIXI.Assets.add('hex_ring', '../images/hex_ring.png',config)
PIXI.Assets.add('star', '../images/star.png',config)
PIXI.Assets.load(['dot', 'hex', 'ring', 'hex_ring', 'star']).then((textures) => {
// 第26帧到达顶点
let topFrame = 26;
// 再60帧后爆炸
let boomFrame = topFrame + 60;
function fire(imgs, count) {
let totalFrame = 0
let container = new PIXI.Container()
container.pause = false
let team = imgs.map(img => {
let box = new PIXI.Container(count);
container.addChild(box);
return { box, img }
})
// 发射元素 60次/s
emitter = () => {
totalFrame++
// 每 120 帧 增加一次元素
if (totalFrame % 120 === 0) {
times(30, () => {
team.forEach(d => {
let { box, img } = d;
if (box.children.length >= count) box.children[0].destroy()
let ele = new PIXI.Sprite(textures[img])
ele.frame = 0
ele.alpha = 0.65 * Math.random()
// 锚点不在正中,旋转的时候就有抖动效果
ele.anchor.set(0.3)
// 初始角度不同,避免旋转的时候,同时向一个方向抖动
ele.angle = Math.random() * 360
ele.scale.set(0.1)
// 初始速度往上
ele.xv = 0
ele.xa = 0
ele.yv = -6
ele.ya = 0.1
box.addChild(ele)
})
})
}
// 每帧 渲染一次
team.forEach(d => {
let { box } = d;
box.children.forEach((ele, index) => {
let t = ele.frame / 4
// 曲折上升
if (ele.frame < topFrame) {
ele.y = ele.y + (ele.yv * t + ele.ya * t * t)
ele.alpha = 1 - ele.frame / (topFrame - 1)
}
// 爆炸初始速度
if (ele.frame === boomFrame) {
// 假设爆炸的初速度是一样的,只是角度不同,就得根据随机角度计算x和y方向的速度
let angle = Math.random() * Math.PI * 2
let v = 0.38
ele.y -= 200
ele.xv = Math.sin(angle) * (Math.random() * 0.7 + 0.1) * v;
ele.yv = Math.cos(angle) * (Math.random() * 0.7 + 0.1) * v;
ele.ya = 0.01
ele.alpha = 1
ele.tint = PIXI.utils.rgb2hex([
Math.random() * 1,
Math.random() * .1,
Math.random() * 0.3,
])
}
// 爆炸过程
if (ele.frame > boomFrame) {
ele.x = ele.x + (ele.xv * t)
ele.y = ele.y + (ele.yv * t + ele.ya * t * t)
ele.angle += 1
// 闪烁效果 至于为什么加上index ,自己试一下就明白了
ele.alpha = (t + index) % 2
ele.scale.set(36 / ele.frame)
}
ele.frame++
})
})
}
PIXI.Ticker.shared.add(emitter)
return container
// return [container,tl]
}
let c1 = fire(['dot', 'hex', 'ring', 'hex_ring', 'star'], 600)
c1.position.set(1334 / 2, 750)
game.stage.addChild(c1)
})