FireComponent.ts
6.46 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
const { ccclass, property } = cc._decorator;
@ccclass
export default class FireComponent extends cc.Component {
@property
isWidget: boolean = false;
@property(cc.Node)
_widgetTarget: cc.Node = null;
// @property(cc.Node)
/** 烟火数量 */
private fire_count = 35;// 原始100个
/** 烟火衰减速度 */
private gap_alpha = 0.02;// 原始0.005
public get widgetTarget() {
return this._widgetTarget;
}
public set widgetTarget(value) {
this._widgetTarget = value;
this.isWidget = !!this._widgetTarget;
if (!CC_EDITOR) {
this.initWidgit();
}
}
private gfx: cc.Graphics = null;
private particles: any[] = [];
onLoad() {
this.gfx = this.node.getComponent(cc.Graphics) || this.node.addComponent(cc.Graphics);
// widgit
this.initWidgit();
// touch
// this.initTouch();
this.InitTouch();
}
private initWidgit() {
// 全屏适配
if (!this.isWidget) return;
let canvas = cc.find("Canvas");
let widget = this.node.addComponent(cc.Widget);
widget.target = this.widgetTarget || canvas;
widget.isAlignTop = true;
widget.isAlignLeft = true;
widget.isAlignRight = true;
widget.isAlignBottom = true;
widget.left = 0;
widget.right = 0;
widget.top = 0;
widget.bottom = 0;
widget.alignMode = cc.Widget.AlignMode.ON_WINDOW_RESIZE;
}
private initTouch() {
// 点击事件
// this.node.on(cc.Node.EventType.TOUCH_END, (event: cc.Event.EventTouch) => {
// let wpos = event.getLocation();
// let npos = this.node.convertToNodeSpaceAR(wpos);
// this.fire(npos.x, npos.y);
// })
}
private ClickCall(event) {
let wpos = event.getLocation();
let npos = this.node.convertToNodeSpaceAR(wpos);
this.fire(npos.x, npos.y);
}
private fire(x, y) {
// 生成烟花
this.gfx.clear();
this.createFireworks(x, y);
}
private tick() {
this.gfx.fillColor = cc.color(255, 255, 255, 0);//0, 0, 0, 26
this.gfx.fillRect(-this.node.width / 2, -this.node.height / 2, this.node.width, this.node.height);
this.drawFireworks();
}
private createFireworks(sx, sy) {
this.particles = [];
var hue = Math.floor(Math.random() * 51) + 150;
var hueVariance = 60;// 30
for (var i = 0; i < this.fire_count; i++) {
var angle = Math.floor(Math.random() * 360);
var p = {
radians: angle * Math.PI / 180,
x: sx,
y: sy,
speed: (Math.random() * 5) + .4,
radius: 0,
size: Math.floor(Math.random() * 3) + 1,
hue: Math.floor(Math.random() * 2 * hueVariance) + (hue - hueVariance),
brightness: Math.floor(Math.random() * 31) + 50,
alpha: (Math.floor(Math.random() * 61) + 40) / 100
};
p.radius = p.speed;
this.particles.push(p);
}
}
private drawFireworks() {
// this.gfx.clear();
let isDraw = false;
for (var i = 0; i < this.particles.length; i++) {
var p = this.particles[i];
var vx = Math.cos(p.radians) * p.radius;
var vy = Math.sin(p.radians) * p.radius + 0.4;
p.x -= vx;
p.y -= vy;
p.radius *= 1 - p.speed / 100;
p.alpha -= this.gap_alpha;// 0.005
if (p.alpha > 0) {
isDraw = true;
this.gfx.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
this.gfx.fillColor = this.hsla2rgba('hsla(' + p.hue + ', 100%, ' + p.brightness + '%)', p.alpha);
this.gfx.fill();
}
}
if (!isDraw) {
this.gfx.clear();
}
}
private hsla2rgba(str, alpha): cc.Color {
const colorArr = str.match(/\d+/g);
let [h, s, l] = colorArr;
h = parseFloat(h) / 360;
s = parseFloat(s) / 100;
l = parseFloat(l) / 100;
if (s === 0) {
l = Math.round(l * 255);
return cc.color(l, l, l, Math.round(alpha * 255));
}
const getRGB = num => {
let q = l >= 0.5 ? l + s - l * s : l * (1 + s); // 注意是数字1加上s,不是字母l
let p = 2 * l - q;
if (num < 0) {
num += 1;
}
if (num > 1) {
num -= 1;
}
switch (true) {
case num > 2 / 3:
num = p;
break;
case num >= 1 / 2:
num = p + (q - p) * 6 * (2 / 3 - num);
break;
case num >= 1 / 6:
num = q;
break;
default:
num = p + (q - p) * 6 * num;
break;
}
return Math.round(num * 255);
};
let r = getRGB(h + 1 / 3);
let g = getRGB(h);
let b = getRGB(h - 1 / 3);
return cc.color(r, g, b, Math.round(alpha * 255));
}
update() {
this.tick();
}
///////////////// 自定义触摸监听 /////////////////
private _eventManager = cc["internal"]["eventManager"];
private _touchListener: any;
private InitTouch() {
const EventListener = cc["EventListener"];
this._touchListener = EventListener.create({
event: EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: false,//是否吞噬touch事件
owner: this.node,
mask: null,
onTouchBegan: this.onTouchStart.bind(this),
onTouchMoved: null,
onTouchEnded: this.onTouchEnded.bind(this),
onTouchCancelled: null,
});
this._eventManager.addListener(this._touchListener, this.node);
}
private onTouchStart(touch: cc.Touch, event: cc.Event.EventTouch): boolean {
// cc.log("touch start");
//此处必须返回true(表示接触到了节点),否则TOUCH_MOVE,TOUCH_END,TOUCH_CANCEL不触发。
return true;
}
private onTouchEnded(touch: cc.Touch, event: cc.Event.EventTouch): void {
// cc.log("touch end");
this.ClickCall(touch);
}
protected onDestroy(): void {
// super.onDestroy();
this._eventManager.removeListener(this._touchListener, this.node);
}
}