Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
FogNetwork
GitHub Repository: FogNetwork/Tsunami
Path: blob/main/public/games/files/garbage-collector/js/entities/laser.js
1036 views
1
/*jshint bitwise: false*/
2
/*globals define*/
3
define([
4
'box2d',
5
'entities/explosion',
6
'entities/physics-entity',
7
'entities/player',
8
'config/colors',
9
'config/material',
10
'config/settings',
11
'utils',
12
'world'
13
], function( Box2D, Explosion, PhysicsEntity, Player, Colors, Material, Settings, Utils, world ) {
14
'use strict';
15
16
var PI2 = Utils.PI2;
17
18
var Vec2 = Box2D.Common.Math.b2Vec2;
19
20
function Laser( x, y, material ) {
21
PhysicsEntity.call( this, {
22
fixture: {
23
isSensor: true,
24
filter: {
25
categoryBits: material
26
}
27
},
28
body: {
29
position: {
30
x: x,
31
y: y
32
}
33
}
34
});
35
36
this.target = null;
37
this.endpoint = null;
38
this.normal = null;
39
this.fraction = Number.POSITIVE_INFINITY;
40
}
41
42
Laser.prototype = new PhysicsEntity();
43
Laser.prototype.constructor = Laser;
44
45
Laser.prototype.update = function( dt ) {
46
PhysicsEntity.prototype.update.call( this, dt );
47
48
var cos = 1,
49
sin = 0;
50
51
if ( this.angle ) {
52
cos = Math.cos( -this.angle );
53
sin = Math.sin( -this.angle );
54
}
55
56
this.target = null;
57
this.endpoint = null;
58
this.fraction = Number.POSITIVE_INFINITY;
59
60
world.RayCast(
61
function( fixture, point, normal, fraction ) {
62
var target = fixture.GetBody().GetUserData();
63
if ( !( target.material & this.material ) ) {
64
return -1;
65
}
66
67
if ( fraction < this.fraction ) {
68
this.target = target;
69
this.normal = normal;
70
this.endpoint = point;
71
this.fraction = fraction;
72
}
73
74
return fraction;
75
}.bind( this ),
76
new Vec2( this.x + cos, this.y + sin ),
77
new Vec2( this.x + 1e4 * cos, this.y + 1e4 * sin )
78
);
79
80
if ( !this.target ) {
81
return;
82
}
83
84
// Delete target.
85
var target = this.target;
86
if ( target !== this &&
87
target.material !== Material.BIMATTER &&
88
!( target instanceof Player ) &&
89
target.game ) {
90
this.game.removed.push( target );
91
92
if ( Settings.explosions ) {
93
var explosion, fill;
94
fill = Colors.Explosion[ Material.type( target.material ) ];
95
96
if ( fill ) {
97
explosion = new Explosion( target.x, target.y );
98
explosion.fill.set( fill );
99
this.game.add( explosion );
100
}
101
}
102
}
103
};
104
105
Laser.prototype.drawPath = function( ctx ) {
106
// Draw laser source.
107
ctx.beginPath();
108
109
// The laser starts at a radius of 1.
110
ctx.rect( -1, -0.5, 2, 1 );
111
ctx.fillStyle = '#000';
112
ctx.fill();
113
114
PhysicsEntity.prototype.drawPath.call( this, ctx );
115
};
116
117
Laser.prototype.draw = function( ctx ) {
118
PhysicsEntity.prototype.draw.call( this, ctx );
119
120
// Only render beam if there is no endpoint and target,
121
// or if the target has not been removed from the game.
122
if ( !this.endpoint || !this.target ||
123
( this.target && !this.target.game ) ) {
124
return;
125
}
126
127
if ( Settings.glow ) {
128
ctx.globalCompositeOperation = 'lighter';
129
}
130
131
var cos = Math.cos( -this.angle ),
132
sin = Math.sin( -this.angle );
133
134
var x0 = this.x + cos,
135
y0 = this.y + sin,
136
x1 = this.endpoint.x,
137
y1 = this.endpoint.y;
138
139
ctx.beginPath();
140
ctx.moveTo( x0, y0 );
141
ctx.lineTo( x1, y1 );
142
143
var outerWidth = 0.4 + Math.random() * 0.2,
144
innerWidth = 0.1 + Math.random() * 0.1;
145
146
// Draw beam.
147
var glowColor = Colors.Glow[ Material.type( this.material ) ];
148
149
if ( glowColor ) {
150
ctx.lineWidth = outerWidth;
151
ctx.strokeStyle = glowColor;
152
ctx.stroke();
153
}
154
155
ctx.lineWidth = innerWidth;
156
ctx.strokeStyle = '#fff';
157
ctx.stroke();
158
159
// Draw endpoint glows.
160
ctx.beginPath();
161
ctx.arc( x0, y0, innerWidth * 2, 0, PI2 );
162
ctx.moveTo( x1, y1 );
163
ctx.arc( x1, y1, innerWidth * 2, 0, PI2 );
164
165
if ( glowColor ) {
166
ctx.lineWidth = outerWidth;
167
ctx.strokeStyle = glowColor;
168
ctx.stroke();
169
}
170
171
ctx.fillStyle = '#fff';
172
ctx.fill();
173
174
if ( Settings.glow ) {
175
ctx.globalCompositeOperation = 'source-over';
176
}
177
};
178
179
Laser.prototype.drawNormals = function( ctx ) {
180
if ( !this.endpoint || !this.normal ) {
181
return;
182
}
183
184
ctx.save();
185
186
// Counteract transofmrs in draw.
187
ctx.rotate( this.angle );
188
ctx.translate( -this.x, -this.y );
189
190
ctx.beginPath();
191
ctx.moveTo( this.endpoint.x, this.endpoint.y );
192
ctx.lineTo( this.endpoint.x + this.normal.x, this.endpoint.y + this.normal.y );
193
ctx.lineWidth = 0.2;
194
ctx.strokeStyle = '#fff';
195
ctx.stroke();
196
197
ctx.restore();
198
};
199
200
Laser.prototype.aabb = function() {
201
var aabb;
202
if ( !this.endpoint ) {
203
aabb = PhysicsEntity.prototype.aabb();
204
return Utils.expandAABB( aabb, 1, 1 );
205
}
206
207
var x0 = this.x,
208
y0 = this.y;
209
210
var x1 = this.endpoint.x,
211
y1 = this.endpoint.y;
212
213
aabb = {
214
xmin: Math.min( x0, x1 ),
215
ymin: Math.min( y0, y1 ),
216
xmax: Math.max( x0, x1 ),
217
ymax: Math.max( y0, y1 )
218
};
219
220
// 1 is the pointer radius. 0.6 is the maximum glow radius.
221
var radius = 1.6;
222
return Utils.relativeExpandAABB( aabb, radius, radius );
223
};
224
225
return Laser;
226
});
227
228