粒子效果[4] - 多烟花效果

用到的图片:

stardotringhexhex_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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
function times(num, fn) {
for (let i = 0; i < num; i++) {
fn()
}
}
function random(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
function createColorArr(num) {
let arr = []
for (let n = 0; n < num; n++) {
arr.push(PIXI.utils.rgb2hex([
Math.random() * 1,
Math.random() * 1,
Math.random() * 1,
]))
}
return arr
}
let game = new PIXI.Application({
width: 1334,
height: 750,
backgroundColor: 0x000020
})
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 inter = 20;
// 每一批 用1-5个颜色
let tints = createColorArr(Math.floor(Math.random() * 4 + 1))
// 一种贴图一个容器
let team = imgs.map(img => {
let box = new PIXI.Container(count);
container.addChild(box);
return { box, img }
})
// 发射元素 60次/s
emitter = () => {
totalFrame++
// 每 120 帧 增加一次元素
if (totalFrame % inter === 0) {
// 随机下一次间隔
inter = Math.floor(Math.random() * 200) + 200
// 随机下一次颜色
tints = createColorArr(Math.floor(Math.random() * 4 + 1))
times(45, () => {
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.3 + 0.7) * v;
ele.yv = Math.cos(angle) * (Math.random() * 0.7 + 0.1) * v;
ele.ya = 0.007
ele.alpha = 1
ele.tint = random(tints)
}
// 爆炸过程
if (ele.frame > boomFrame) {
if (ele.xv !== 0) ele.xv *= 0.995 // 速度 逐渐减慢
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 * Math.cos(ele.frame / 120)
ele.scale.set(Math.cos(ele.frame / 120) / 2) // 透明度 从 1/2 逐渐趋近 0
}
ele.frame++
})
})
}
PIXI.Ticker.shared.add(emitter)
return container
// return [container,tl]
}
// 近景
let c1 = fire([ 'hex', 'ring', 'hex_ring', 'star'], 300)
c1.position.set(1334 / 2, 750)
game.stage.addChild(c1)
// 中景
let c2 = fire(['dot', 'hex', 'ring', 'hex_ring'], 300)
c2.position.set(1334 / 3, 750)
c2.scale.set(0.5)
let b2 = new PIXI.filters.BlurFilter();
b2.blur = 0.3
c2.filters = [b2]
game.stage.addChild(c2)
// 远景
let c3 = fire(['dot', 'hex', 'ring'], 300)
c3.position.set(1334 / 4 * 3, 750)
c3.scale.set(0.3)
let b3 = new PIXI.filters.BlurFilter();
b3.blur = 1
c3.filters = [b3]
game.stage.addChild(c3)
})