Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mamayaya1
GitHub Repository: mamayaya1/game
Path: blob/main/projects/HexGL/bkcore/hexgl/HexGL.js
4627 views
1
/*
2
* HexGL
3
* @author Thibaut 'BKcore' Despoulain <http://bkcore.com>
4
* @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License.
5
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/.
6
*/
7
8
'use strict';
9
'v1.0.1';
10
11
var bkcore = bkcore || {};
12
bkcore.hexgl = bkcore.hexgl || {};
13
14
bkcore.hexgl.HexGL = function(opts)
15
{
16
var self = this;
17
18
this.document = opts.document || document;
19
20
this.a = window.location.href;
21
22
this.active = true;
23
this.displayHUD = opts.hud == undefined ? true : opts.hud;
24
this.width = opts.width == undefined ? window.innerWidth : opts.width;
25
this.height = opts.height == undefined ? window.innerHeight : opts.height;
26
27
this.difficulty = opts.difficulty == undefined ? 0 : opts.difficulty;
28
this.player = opts.player == undefined ? "Anonym" : opts.player;
29
30
this.track = bkcore.hexgl.tracks[ opts.track == undefined ? 'Cityscape' : opts.track ];
31
32
this.mode = opts.mode == undefined ? 'timeattack' : opts.mode;
33
34
this.controlType = opts.controlType == undefined ? 1 : opts.controlType;
35
36
// 0 == low, 1 == mid, 2 == high, 3 == very high
37
// the old platform+quality combinations map to these new quality values
38
// as follows:
39
// mobile + low quality => 0 (LOW)
40
// mobile + mid quality OR desktop + low quality => 1 (MID)
41
// mobile + high quality => 2 (HIGH)
42
// desktop + mid or high quality => 3 (VERY HIGH)
43
this.quality = opts.quality == undefined ? 3 : opts.quality;
44
45
if(this.quality === 0)
46
{
47
this.width /= 2;
48
this.height /=2;
49
}
50
51
this.settings = null;
52
this.renderer = null;
53
this.manager = null;
54
this.lib = null;
55
this.materials = {};
56
this.components = {};
57
this.extras = {
58
vignetteColor: new THREE.Color(0x458ab1),
59
bloom: null,
60
fxaa: null
61
};
62
63
this.containers = {};
64
this.containers.main = opts.container == undefined ? document.body : opts.container;
65
this.containers.overlay = opts.overlay == undefined ? document.body : opts.overlay;
66
67
this.gameover = opts.gameover == undefined ? null : opts.gameover;
68
69
this.godmode = opts.godmode == undefined ? false : opts.godmode;
70
71
this.hud = null;
72
73
this.gameplay = null;
74
75
this.composers = {
76
game: null
77
};
78
79
this.initRenderer();
80
81
function onKeyPress(event)
82
{
83
if(event.keyCode == 27/*escape*/)
84
{
85
self.reset();
86
}
87
}
88
89
this.document.addEventListener('keydown', onKeyPress, false);
90
}
91
92
bkcore.hexgl.HexGL.prototype.start = function()
93
{
94
95
this.manager.setCurrent("game");
96
97
var self = this;
98
99
function raf()
100
{
101
if(self && self.active) requestAnimationFrame( raf );
102
self.update();
103
}
104
105
//if(this.a[15] == "o")
106
raf();
107
108
this.initGameplay();
109
}
110
111
bkcore.hexgl.HexGL.prototype.reset = function()
112
{
113
this.manager.get('game').objects.lowFPS = 0;
114
this.gameplay.start();
115
116
bkcore.Audio.stop('bg');
117
bkcore.Audio.stop('wind');
118
bkcore.Audio.volume('wind', 0.35);
119
bkcore.Audio.play('bg');
120
bkcore.Audio.play('wind');
121
}
122
123
bkcore.hexgl.HexGL.prototype.restart = function()
124
{
125
try{ this.document.getElementById('finish').style.display = 'none'; }
126
catch(e){};
127
this.reset();
128
}
129
130
bkcore.hexgl.HexGL.prototype.update = function()
131
{
132
if(!this.active) return;
133
134
if(this.gameplay != null)
135
this.gameplay.update();
136
137
this.manager.renderCurrent();
138
}
139
140
bkcore.hexgl.HexGL.prototype.init = function()
141
{
142
this.initHUD();
143
144
this.track.buildMaterials(this.quality);
145
146
this.track.buildScenes(this, this.quality);
147
148
this.initGameComposer();
149
}
150
151
bkcore.hexgl.HexGL.prototype.load = function(opts)
152
{
153
this.track.load(opts, this.quality);
154
}
155
156
bkcore.hexgl.HexGL.prototype.initGameplay = function()
157
{
158
var self = this;
159
160
this.gameplay = new bkcore.hexgl.Gameplay({
161
mode: this.mode,
162
hud: this.hud,
163
shipControls: this.components.shipControls,
164
cameraControls: this.components.cameraChase,
165
analyser: this.track.analyser,
166
pixelRatio: this.track.pixelRatio,
167
track: this.track,
168
onFinish: function() {
169
self.components.shipControls.terminate();
170
self.displayScore(this.finishTime, this.lapTimes);
171
}
172
});
173
174
this.gameplay.start();
175
176
bkcore.Audio.play('bg');
177
bkcore.Audio.play('wind');
178
bkcore.Audio.volume('wind', 0.35);
179
}
180
181
bkcore.hexgl.HexGL.prototype.displayScore = function(f, l)
182
{
183
this.active = false;
184
185
var tf = bkcore.Timer.msToTimeString(f);
186
var tl = [
187
bkcore.Timer.msToTimeString(l[0]),
188
bkcore.Timer.msToTimeString(l[1]),
189
bkcore.Timer.msToTimeString(l[2])
190
];
191
192
if(this.gameover !== null)
193
{
194
this.gameover.style.display = "block";
195
this.gameover.children[0].innerHTML = tf.m + "'" + tf.s + "''" + tf.ms;
196
this.containers.main.parentElement.style.display = "none";
197
return;
198
}
199
200
var t = this.track;
201
var dc = this.document.getElementById("finish");
202
var ds = this.document.getElementById("finish-state");
203
var dh = this.document.getElementById("finish-hallmsg");
204
var dr = this.document.getElementById("finish-msg");
205
var dt = this.document.getElementById("finish-result");
206
var dl1 = this.document.getElementById("finish-lap1");
207
var dl2 = this.document.getElementById("finish-lap2");
208
var dl3 = this.document.getElementById("finish-lap3");
209
var dd = this.document.getElementById("finish-diff")
210
var st = this.document.getElementById("finish-twitter");
211
var sf = this.document.getElementById("finish-fb");
212
var sl = this.document.getElementById("lowfps-msg");
213
var d = this.difficulty == 0 ? 'casual' : 'hard';
214
var ts = this.hud.timeSeparators;
215
216
if(this.gameplay.result == this.gameplay.results.FINISH)
217
{
218
ds != undefined && (ds.innerHTML = "Finished!");
219
// local record
220
if(typeof(Storage)!=="undefined")
221
{
222
if(localStorage['score-'+t+'-'+d] == undefined || localStorage['score-'+t+'-'+d] > f)
223
{
224
dr != undefined && (dr.innerHTML = "New local record!");
225
localStorage['score-'+t+'-'+d] = f;
226
227
// Export race data
228
localStorage['race-'+t+'-replay'] = JSON.Stringify(this.gameplay.raceData.export());
229
}
230
else
231
{
232
dr != undefined && (dr.innerHTML = "Well done!");
233
}
234
}
235
// ladder record
236
var p = bkcore.hexgl.Ladder.global[t][d][bkcore.hexgl.Ladder.global[t][d].length-2];
237
if(p != undefined && p['score'] > f)
238
{
239
dh != undefined && (dh.innerHTML = "You made it to the HOF!");
240
}
241
else
242
{
243
dh != undefined && (dh.innerHTML = "Hall Of Fame");
244
}
245
246
dt != undefined && (dt.innerHTML = tf.m + ts[1] + tf.s + ts[2] + tf.ms);
247
dl1 != undefined && (dl1.innerHTML = tl[0]["m"] != undefined ? tl[0].m + ts[1] + tl[0].s + ts[2] + tl[0].ms : "-");
248
dl2 != undefined && (dl2.innerHTML = tl[1]["m"] != undefined ? tl[1].m + ts[1] + tl[1].s + ts[2] + tl[1].ms : "-");
249
dl3 != undefined && (dl3.innerHTML = tl[2]["m"] != undefined ? tl[2].m + ts[1] + tl[2].s + ts[2] + tl[2].ms : "-");
250
251
// Ladder save
252
// Undisclosed
253
}
254
else
255
{
256
ds != undefined && (ds.innerHTML = "Destroyed!");
257
dr != undefined && (dr.innerHTML = "Maybe next time!");
258
dh != undefined && (dh.innerHTML = "Hall Of Fame");
259
dt != undefined && (dt.innerHTML = "None");
260
dl1 != undefined && (dl1.innerHTML = "None");
261
dl2 != undefined && (dl2.innerHTML = "None");
262
dl3 != undefined && (dl3.innerHTML = "None");
263
}
264
265
dd != undefined && (dd.innerHTML = d);
266
st != undefined && (st.href='http://twitter.com/share?text='+encodeURIComponent('I just scored '+dt.innerHTML+' in '+'Cityscape ('+d+') on #HexGL! Come try it and beat my record on '));
267
sf != undefined && (sf.href='http://www.facebook.com/sharer.php?s=100'
268
+'&p[title]='+encodeURIComponent('I just scored '+dt.innerHTML+' in '+'Cityscape ('+d+') on HexGL!')
269
+'&p[summary]='+encodeURIComponent('HexGL is a futuristic racing game built by Thibaut Despoulain (BKcore) using HTML5, Javascript and WebGL. Come challenge your friends on this fast-paced 3D game!')
270
+'&p[url]='+encodeURIComponent('http://hexgl.bkcore.com')
271
+'&p[images][0]='+encodeURIComponent('http://hexgl.bkcore.com/image.png'));
272
273
bkcore.hexgl.Ladder.displayLadder('finish-ladder', t, d, 8);
274
275
if(this.manager.get('game').objects.lowFPS >= 999)
276
sl != undefined && (sl.innerHTML = 'Note: Your framerate was pretty low, you should try a lesser graphic setting!');
277
else
278
sl != undefined && (sl.innerHTML = '');
279
280
dc.style.display = 'block';
281
}
282
283
bkcore.hexgl.HexGL.prototype.initRenderer = function()
284
{
285
var renderer = new THREE.WebGLRenderer({
286
antialias: false,
287
clearColor: 0x000000
288
});
289
290
// desktop + quality mid or high
291
if(this.quality > 2)
292
{
293
renderer.physicallyBasedShading = true;
294
renderer.gammaInput = true;
295
renderer.gammaOutput = true;
296
renderer.shadowMapEnabled = true;
297
renderer.shadowMapSoft = true;
298
}
299
300
renderer.autoClear = false;
301
renderer.sortObjects = false;
302
renderer.setSize( this.width, this.height );
303
renderer.domElement.style.position = "relative";
304
305
this.containers.main.appendChild( renderer.domElement );
306
this.canvas = renderer.domElement;
307
this.renderer = renderer;
308
this.manager = new bkcore.threejs.RenderManager(renderer);
309
}
310
311
bkcore.hexgl.HexGL.prototype.initHUD = function()
312
{
313
if(!this.displayHUD) return;
314
this.hud = new bkcore.hexgl.HUD({
315
width: this.width,
316
height: this.height,
317
font: "BebasNeueRegular",
318
bg: this.track.lib.get("images", "hud.bg"),
319
speed: this.track.lib.get("images", "hud.speed"),
320
shield: this.track.lib.get("images", "hud.shield")
321
});
322
this.containers.overlay.appendChild(this.hud.canvas);
323
}
324
325
bkcore.hexgl.HexGL.prototype.initGameComposer = function()
326
{
327
var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
328
var renderTarget = new THREE.WebGLRenderTarget( this.width, this.height, renderTargetParameters );
329
330
// GAME COMPOSER
331
var renderSky = new THREE.RenderPass( this.manager.get("sky").scene, this.manager.get("sky").camera );
332
333
var renderModel = new THREE.RenderPass( this.manager.get("game").scene, this.manager.get("game").camera );
334
renderModel.clear = false;
335
336
this.composers.game = new THREE.EffectComposer( this.renderer, renderTarget );
337
338
var effectScreen = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] );
339
effectScreen.renderToScreen = true;
340
var effectVignette = new THREE.ShaderPass( THREE.ShaderExtras[ "vignette" ] );
341
342
var effectHex = new THREE.ShaderPass( bkcore.threejs.Shaders[ "hexvignette" ] );
343
effectHex.uniforms[ 'size' ].value = 512.0 * (this.width/1633);
344
effectHex.uniforms[ 'rx' ].value = this.width;
345
effectHex.uniforms[ 'ry' ].value = this.height;
346
effectHex.uniforms[ 'tHex' ].texture = this.track.lib.get("textures", "hex");
347
effectHex.uniforms[ 'color' ].value = this.extras.vignetteColor;
348
349
effectHex.renderToScreen = true;
350
351
this.composers.game.addPass( renderSky );
352
this.composers.game.addPass( renderModel );
353
354
// if(this.quality > 0 && !this.mobile)
355
// {
356
// var effectFXAA = new THREE.ShaderPass( THREE.ShaderExtras[ "fxaa" ] );
357
// effectFXAA.uniforms[ 'resolution' ].value.set( 1 / this.width, 1 / this.height );
358
359
// this.composers.game.addPass( effectFXAA );
360
361
// this.extras.fxaa = effectFXAA;
362
363
// }
364
365
// desktop + quality mid or high
366
if(this.quality > 2)
367
{
368
var effectBloom = new THREE.BloomPass( 0.8, 25, 4 , 256);
369
370
this.composers.game.addPass( effectBloom );
371
372
this.extras.bloom = effectBloom;
373
}
374
375
// desktop + quality low, mid or high
376
// OR
377
// mobile + quality mid or high
378
if(this.quality > 0)
379
this.composers.game.addPass( effectHex );
380
else
381
this.composers.game.addPass( effectScreen );
382
}
383
384
bkcore.hexgl.HexGL.prototype.createMesh = function(parent, geometry, x, y, z, mat)
385
{
386
geometry.computeTangents();
387
388
var mesh = new THREE.Mesh( geometry, mat );
389
mesh.position.set( x, y, z );
390
parent.add(mesh);
391
392
// desktop + quality mid or high
393
if(this.quality > 2)
394
{
395
mesh.castShadow = true;
396
mesh.receiveShadow = true;
397
}
398
399
return mesh;
400
}
401
402
bkcore.hexgl.HexGL.prototype.tweakShipControls = function()
403
{
404
var c = this.components.shipControls;
405
if(this.difficulty == 1)
406
{
407
c.airResist = 0.035;
408
c.airDrift = 0.07;
409
c.thrust = 0.035;
410
c.airBrake = 0.04;
411
c.maxSpeed = 9.6;
412
c.boosterSpeed = c.maxSpeed * 0.35;
413
c.boosterDecay = 0.007;
414
c.angularSpeed = 0.0140;
415
c.airAngularSpeed = 0.0165;
416
c.rollAngle = 0.6;
417
c.shieldDamage = 0.03;
418
c.collisionSpeedDecrease = 0.8;
419
c.collisionSpeedDecreaseCoef = 0.5;
420
c.rollLerp = 0.1;
421
c.driftLerp = 0.4;
422
c.angularLerp = 0.4;
423
}
424
else if(this.difficulty == 0)
425
{
426
c.airResist = 0.02;
427
c.airDrift = 0.06;
428
c.thrust = 0.02;
429
c.airBrake = 0.025;
430
c.maxSpeed = 7.0;
431
c.boosterSpeed = c.maxSpeed * 0.5;
432
c.boosterDecay = 0.007;
433
c.angularSpeed = 0.0125;
434
c.airAngularSpeed = 0.0135;
435
c.rollAngle = 0.6;
436
c.shieldDamage = 0.06;
437
c.collisionSpeedDecrease = 0.8;
438
c.collisionSpeedDecreaseCoef = 0.5;
439
c.rollLerp = 0.07;
440
c.driftLerp = 0.3;
441
c.angularLerp = 0.4;
442
}
443
444
if(this.godmode)
445
c.shieldDamage = 0.0;
446
}
447
448