Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
FogNetwork
GitHub Repository: FogNetwork/Tsunami
Path: blob/main/public/games/files/garbage-collector/js/entities/emitter.js
1036 views
1
/*jshint bitwise: false*/
2
/*globals define*/
3
define([
4
'entities/physics-entity',
5
'entities/trash',
6
'geometry/geometry-factory',
7
'config/colors',
8
'config/material',
9
'config/settings',
10
'utils'
11
], function( PhysicsEntity, Trash, GeometryFactory, Colors, Material, Settings, Utils ) {
12
'use strict';
13
14
var defaults = {
15
aspectRatio: 0.1,
16
17
portalRadiusRatio: 0.6,
18
coneRadiusRatio: 1.5,
19
coneLengthRatio: 2,
20
21
speed: 0,
22
23
// Both are in seconds.
24
rate: 0,
25
lifeTime: 0
26
};
27
28
function Emitter( x, y, options ) {
29
PhysicsEntity.call( this, {
30
fixture: {
31
isSensor: true
32
},
33
body: {
34
position: {
35
x: x,
36
y: y
37
}
38
}
39
});
40
41
Utils.defaults( this, options, defaults );
42
43
this.spawnArea = null;
44
this.particle = null;
45
// Any custom particle physics properties go here.
46
this.properties = {};
47
48
this.time = 0;
49
this.firing = false;
50
}
51
52
Emitter.prototype = new PhysicsEntity();
53
Emitter.prototype.constructor = Emitter;
54
55
Emitter.prototype.update = function( dt ) {
56
PhysicsEntity.prototype.update.call( this, dt );
57
58
if ( !this.firing ) {
59
return;
60
}
61
62
this.time += dt;
63
if ( this.time > this.rate ) {
64
this.time = 0;
65
this.fire();
66
}
67
};
68
69
Emitter.prototype.fire = function() {
70
if ( !this.particle || !this.game ) {
71
return;
72
}
73
74
// Initial state of a random point.
75
var state = this.random();
76
77
// Create entities with the properties of the initial state.
78
var entity = new Trash( this.properties, this.lifeTime );
79
80
entity.x = state.x;
81
entity.y = state.y;
82
entity.accelerate( state.vx, state.vy );
83
84
// Add any specified shapes.
85
var particleJSON = JSON.stringify( this.particle );
86
entity.add( GeometryFactory.create( particleJSON ) );
87
88
this.game.add( entity );
89
};
90
91
/**
92
* Get the initial position and acceleration of particle.
93
*/
94
Emitter.prototype.random = function() {
95
var x = this.x,
96
y = this.y;
97
98
var cos = 1,
99
sin = 0;
100
101
if ( this.angle ) {
102
cos = Math.cos( -this.angle );
103
sin = Math.sin( -this.angle );
104
}
105
106
// Spawn inside an area (rect, circle, segment).
107
var point;
108
if ( this.spawnArea ) {
109
point = this.spawnArea.random();
110
point = this.toWorld( point.x, point.y );
111
x = point.x;
112
y = point.y;
113
}
114
115
return {
116
x: x,
117
y: y,
118
vx: cos * this.speed,
119
vy: sin * this.speed
120
};
121
};
122
123
Emitter.prototype.start = function( when ) {
124
when = when || 0;
125
126
setTimeout(function() {
127
this.firing = true;
128
this.time = 0;
129
}.bind( this ), when );
130
};
131
132
Emitter.prototype.stop = function( when ) {
133
when = when || 0;
134
135
setTimeout(function() {
136
this.firing = false;
137
}.bind( this ), when );
138
};
139
140
Emitter.prototype.drawPath = function( ctx ) {
141
var material = this.properties.fixture.filter.categoryBits;
142
143
// The radius of the portal opening.
144
var portalRadius = this.portalRadius;
145
146
var coneRadius = portalRadius * this.coneRadiusRatio,
147
coneLength = portalRadius * this.coneLengthRatio;
148
149
var glowColor = Colors.Glow[ Material.type( material ) ];
150
151
ctx.save();
152
ctx.scale( this.aspectRatio, 1 );
153
ctx.beginPath();
154
155
// Draw warp hole.
156
ctx.arc( 0, 0, portalRadius, 0, 2 * Math.PI );
157
ctx.restore();
158
159
ctx.fillStyle = '#000';
160
ctx.fill();
161
162
// Draw ring.
163
if ( Settings.glow ) {
164
ctx.globalCompositeOperation = 'lighter';
165
}
166
167
if ( glowColor ) {
168
ctx.strokeStyle = glowColor;
169
ctx.lineWidth = 0.3 + Math.random() * 0.2;
170
ctx.stroke();
171
}
172
173
ctx.strokeStyle = '#fff';
174
ctx.lineWidth = 0.1;
175
ctx.stroke();
176
177
if ( Settings.gradients && glowColor ) {
178
var grad = ctx.createLinearGradient( 0, 0, coneLength, 0 );
179
grad.addColorStop( 0, glowColor );
180
grad.addColorStop( 1, 'transparent' );
181
182
ctx.fillStyle = grad;
183
ctx.beginPath();
184
ctx.moveTo( 0, -portalRadius );
185
ctx.lineTo( coneLength, -coneRadius );
186
ctx.lineTo( coneLength, coneRadius );
187
ctx.lineTo( 0, portalRadius );
188
ctx.fill();
189
}
190
191
if ( Settings.glow ) {
192
ctx.globalCompositeOperation = 'source-over';
193
}
194
195
PhysicsEntity.prototype.drawPath.call( this, ctx );
196
};
197
198
Emitter.prototype.aabb = function() {
199
return null;
200
};
201
202
Object.defineProperty( Emitter.prototype, 'portalRadius', {
203
get: function() {
204
return this.spawnArea.height * this.portalRadiusRatio;
205
}
206
});
207
208
return Emitter;
209
});
210
211