inertialrush-game-test
Version:
This package enables the integration of the Inertial Rush game into any React application, making it easy to showcase the game.
564 lines (501 loc) • 17.9 kB
JavaScript
/*
* HexGL
* @author Thibaut 'BKcore' Despoulain <http://bkcore.com>
* @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/.
*/
var bkcore = bkcore || {};
bkcore.hexgl = bkcore.hexgl || {};
bkcore.hexgl.tracks = bkcore.hexgl.tracks || {};
bkcore.hexgl.connectionToSocket = connectToSocket()
bkcore.hexgl.tracks.Cityscape = {
lib: null,
materials: {},
name: "Cityscape",
checkpoints: {
list: [1,2],
start: 1,
last: 2
},
spawn: {
x: 489,
y: 400,
z: 1400
},
spawnRotation: {
x: 0,
y: 0,
z: 0
},
analyser: null,
pixelRatio: 2048.0 / 6000.0,
load: function(opts, quality, idShipModel)
{
this.lib = new bkcore.threejs.Loader(opts);
// desktop + quality low
// OR
// mobile + quality low or mid
if(quality < 2) // LOW
{
this.lib.load({
textures: {
'hex' : "textures/hud/hex.jpg",
'spark' : "textures/particles/spark.png",
'cloud' : "textures/particles/cloud.png",
'booster.sprite' : "textures/boostersprite.jpg",
},
texturesCube: {
'skybox' : "textures/skybox/%1.jpg"
},
objects: {
'city' : "objects/city.glb",
'ship' : `objects/ships/ship${idShipModel}.glb`,
'shipBot' : "objects/ships/ship2.glb",
'booster' : "objects/ships/booster.glb",
'firstAidKit.base' : "objects/first-aid-kit/base.glb",
'firstAidKit.plus' : "objects/first-aid-kit/plus.glb",
},
analysers: {
'track.cityscape.collision' : "textures/tracks-analysers/collision.png",
'track.cityscape.height' : "textures/tracks-analysers/height.png"
},
images: {
'hud.bg' : "textures/hud/hud-bg.png",
'hud.speed' : "textures/hud/hud-fg-speed.png",
'hud.shield' : "textures/hud/hud-fg-shield.png"
},
sounds: {
bg: {
src: 'audio/bg.mp3',
loop: true,
usePanner: false
},
crash: {
src: 'audio/crash.ogg',
loop: false,
usePanner: true
},
destroyed: {
src: 'audio/destroyed.ogg',
loop: false,
usePanner: false
},
boost: {
src: 'audio/boost.ogg',
loop: false,
usePanner: true
},
wind: {
src: 'audio/wind.ogg',
loop: true,
usePanner: true
}
}
});
}
// desktop + quality mid or high
// OR
// mobile + quality high
else // HIGH
{console.log('HIGH');
this.lib.load({
textures: {
'hex' : "textures.full/hud/hex.jpg",
'spark' : "textures.full/particles/spark.png",
'cloud' : "textures.full/particles/cloud.png",
'booster.sprite' : "textures.full/boostersprite.jpg",
},
texturesCube: {
'skybox' : "textures.full/skybox/%1.jpg"
},
objects: {
'city' : "objects/city.glb",
'ship' : `objects/ships/ship${idShipModel}.glb`,
'shipBot' : "objects/ships/ship2.glb",
'booster' : "objects/ships/booster.glb",
'firstAidKit.base' : "objects/first-aid-kit/base.glb",
'firstAidKit.plus' : "objects/first-aid-kit/plus.glb",
},
analysers: {
'track.cityscape.collision' : "textures.full/tracks-analysers/collision.png",
'track.cityscape.height' : "textures.full/tracks-analysers/height.png"
},
images: {
'hud.bg' : "textures.full/hud/hud-bg.png",
'hud.speed' : "textures.full/hud/hud-fg-speed.png",
'hud.shield' : "textures.full/hud/hud-fg-shield.png"
},
sounds: {
bg: {
src: 'audio/bg.mp3',
loop: true
},
crash: {
src: 'audio/crash.ogg',
loop: false
},
destroyed: {
src: 'audio/destroyed.ogg',
loop: false
},
boost: {
src: 'audio/boost.ogg',
loop: false
},
wind: {
src: 'audio/wind.ogg',
loop: true
}
}
});
}
},
buildMaterials: function(quality)
{
// desktop + quality low
// OR
// mobile + quality low or mid
if(quality < 2) // LOW
{
/*this.materials.bonusBase = new THREE.MeshBasicMaterial({
map: this.lib.get("textures", "bonus.base.diffuse"),
});
this.materials.bonusSpeed = new THREE.MeshBasicMaterial({
color: 0x0096ff
});*/
}
// desktop + quality mid or high
// OR
// mobile + quality high
else // HIGH
{
/*this.materials.bonusBase = new THREE.MeshPhongMaterial( {
map: this.lib.get("textures", "bonus.base.diffuse"),
specularMap: this.lib.get("textures", "bonus.base.specular"),
normalMap: this.lib.get("textures", "bonus.base.normal"),
shininess: 42,
} );
this.materials.bonusSpeed = new THREE.MeshBasicMaterial({
color: 0x0096ff
});*/
}
},
buildScenes: function(ctx, quality, sounds, width)
{
//save map
/*const collision = this.lib.get("analysers", "track.cityscape.height").pixels.data;
const normalArrayCollision = Array.from(collision);
const link = document.createElement("a");
const content = JSON.stringify(normalArrayCollision);
const file = new Blob([content], { type: 'text/plain' });
link.href = URL.createObjectURL(file);
link.download = "sample.txt";
link.click();
URL.revokeObjectURL(link.href);*/
ctx.components.ships = {}
ctx.components.shipsEffects = {}
bkcore.hexgl.connectionToSocket.on('initClient', (message) => {
const parsedMessage = message.split(',')
ctx.components.shipControls.name = parsedMessage[6];
const kit1Data = {
x: parsedMessage[0],
y: parsedMessage[1],
z: parsedMessage[2],
}
const kit2Data = {
x: parsedMessage[3],
y: parsedMessage[4],
z: parsedMessage[5],
}
this.updateKitposition(kit1Data, kit2Data)
});
bkcore.hexgl.connectionToSocket.on('g', () => {
ctx.components.shipControls.inGarage()
})
bkcore.hexgl.connectionToSocket.on('u', (message) => {
const parsedMessage = message.split(',')
const kit1Data = {
x: parsedMessage[0],
y: parsedMessage[1],
z: parsedMessage[2],
}
const kit2Data = {
x: parsedMessage[3],
y: parsedMessage[4],
z: parsedMessage[5],
}
this.updateKitposition(kit1Data, kit2Data)
const ships = []
let j = 6
for (let i = 0; i < ((parsedMessage.length - 6) / 10); i++) {
ships[i] = {
name: parsedMessage[j + 0],
rollAmount: +parsedMessage[j + 1] || 0,
shield: parsedMessage[j + 2] || 0,
dummyX: parsedMessage[j + 3] || 0,
dummyY: +parsedMessage[j + 4] || 0,
dummyZ: +parsedMessage[j + 5] || 0,
quaternionX: parsedMessage[j + 6] || 0,
quaternionY: parsedMessage[j + 7] || 0,
quaternionZ: parsedMessage[j + 8] || 0,
quaternionW: parsedMessage[j + 9] || 0,
}
j += 10;
}
ships.forEach((el) => {
if (ctx.components.shipControls.name === el.name) {
ctx.components.shipControls.update(el)
} else {
if (!ctx.components.ships[el.name]) {
this.createShip(el)
} else {
ctx.components.ships[el.name].update(el, true)
ctx.components.shipsEffects[el.name].update(el, camera)
}
}
})
for (ship in ctx.components.ships) {
if (!ships.find((el) => el.name === ship)) {
this.removeShip(ship)
}
}
})
this.removeShip = function(name) {
// scene.remove(ctx.components.ships[name].mesh)
delete ctx.components.ships[name]
delete ctx.components.shipsEffects[name]
}
this.createShip = function(el) {
const mesh = ctx.addObject(scene, this.lib.get("objects", "shipBot").clone(), el.dummyX, el.dummyY, el.dummyZ);
const geometrySprite = new THREE.PlaneGeometry( 10, 10 );
const materialSprite = new THREE.MeshBasicMaterial({
map: this.lib.get("textures", "booster.sprite"),
blending: THREE.AdditiveBlending,
transparent: true,
});
var boosterSprite = ctx.createMesh(mesh, geometrySprite , 0, 0, -4, materialSprite);
const booster = ctx.addObject(mesh, this.lib.get("objects", "booster").clone(), 0, 0, -4);
booster.depthWrite = false;
var boosterLight = new THREE.PointLight(0x00a2ff, 4.0, 60);
boosterLight.position.set(0, 0.665, -4);
if(quality > 0)
mesh.add(boosterLight);
const ship = new bkcore.hexgl.ShipControls(ctx);
ship.collisionMap = this.lib.get("analysers", "track.cityscape.collision");
ship.collisionPixelRatio = 2048.0 / 6000.0;
ship.collisionDetection = true;
ship.heightMap = this.lib.get("analysers", "track.cityscape.height");
ship.heightPixelRatio = 2048.0 / 6000.0;
ship.heightBias = 4.0;
ship.heightScale = 10.0;
ship.control(mesh);
ship.name = el.name;
mesh.name = el.name;
const dummy = {
x: el.dummyX,
y: el.dummyY,
z: el.dummyZ,
}
ship.reset(dummy)
ctx.components.ships[el.name] = ship;
var fxParams = {
scene: scene,
shipControls: ship,
booster: booster,
boosterSprite: boosterSprite,
boosterLight: boosterLight,
useParticles: false
};
fxParams.textureCloud = this.lib.get("textures", "cloud");
fxParams.textureSpark = this.lib.get("textures", "spark");
fxParams.useParticles = true;
ctx.components.shipsEffects[el.name] = new bkcore.hexgl.ShipEffects(fxParams);
}
this.updateKitposition = function(kit1Data, kit2Data) {
ctx.components.firstAidKitPlusControl1.update(kit1Data)
ctx.components.firstAidKitPlusControl2.update(kit2Data)
// firstAidKitPlus1.scale.set(0.02, 0.02, 0.02);
// firstAidKitPlus2.scale.set(0.02, 0.02, 0.02);
firstAidKitBase1.position.set(kit1Data.x, kit1Data.y, kit1Data.z)
firstAidKitBase2.position.set(kit2Data.x, kit2Data.y, kit2Data.z)
// firstAidKitBase1.scale.set(0.2, 0.2, 0.2);
// firstAidKitBase2.scale.set(0.2, 0.2, 0.2);
}
// IMPORTANT
this.analyser = this.lib.get("analysers", "track.cityscape.collision");
// SKYBOX
var sceneCube = new THREE.Scene();
/*sceneCube.background = this.lib.get("texturesCube", "skybox");*/
var cameraCube = new THREE.PerspectiveCamera( 70, ctx.width / ctx.height, 1, 6000 );
sceneCube.add( cameraCube );
/*var skyshader = THREE.ShaderLib[ "cube" ];
skyshader.uniforms[ "tCube" ].value = this.lib.get("texturesCube", "skybox");
var skymaterial = new THREE.ShaderMaterial(
{
fragmentShader: skyshader.fragmentShader,
vertexShader: skyshader.vertexShader,
uniforms: skyshader.uniforms,
depthWrite: false
});
var mesh = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100 ), skymaterial );
skymaterial.side = THREE.BackSide;
sceneCube.add(mesh);*/
ctx.manager.add("sky", sceneCube, cameraCube);
var ambient = 0xbbbbbb, diffuse = 0xffffff, specular = 0xffffff, shininess = 42, scale = 23;
// MAIN SCENE
var camera = new THREE.PerspectiveCamera( 70, ctx.width / ctx.height, 1, 60000 );
var ambientLight = new THREE.AmbientLight(ambient);
ambientLight.intensity = 1.5;
var scene = new THREE.Scene();
scene.background = this.lib.get("texturesCube", "skybox");
scene.add( camera );
scene.add( ambientLight );
// SUN
var sun = new THREE.DirectionalLight( diffuse, 1.5 );
sun.position.set( -4000, 1200, 1800 );
sun.lookAt(new THREE.Vector3());
// desktop + quality mid or high
if(quality >= 2)
{
sun.castShadow = true;
sun.shadow.camera.near = 50;
sun.shadow.camera.far = camera.far*2;
sun.shadow.camera.right = 3000;
sun.shadow.camera.left = -3000;
sun.shadow.camera.top = 3000;
sun.shadow.camera.bottom = -3000;
//sun.shadowCameraVisible = true;
sun.shadow.bias = 0.0001;
sun.shadow.mapSize.width = 2048;
sun.shadow.mapSize.height = 2048;
}
scene.add( sun );
// CUBE
/*const geometry = new THREE.BoxGeometry( 10, 10, 10 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = ctx.createMesh(scene, geometry , -2250, 386.9000244140625, -837.77, material);*/
// SHIP
var ship = ctx.addObject(scene, this.lib.get("objects", "ship"), 0, 0, 0);
var booster = ctx.addObject(ship, this.lib.get("objects", "booster"), 0, 0, -4);
booster.depthWrite = false;
var boosterSprite = new THREE.Sprite(new THREE.SpriteMaterial({
map: this.lib.get("textures", "booster.sprite"),
blending: THREE.AdditiveBlending,
color: 0xffffff,
depthTest: false
}));
boosterSprite.scale.set(10, 10, 1.0);
booster.add(boosterSprite);
var boosterLight = new THREE.PointLight(0x00a2ff, 4.0, 60);
boosterLight.position.set(0, 0.665, -4);
// desktop + quality low, mid or high
// OR
// mobile + quality mid or high
// NB booster is now enabled on desktop + low quality,
// when it wasn't before; this is because this booster setting
// is the only difference between mobile + mid quality
// and desktop + low quality, so I merged them for convenience
if(quality > 0)
ship.add(boosterLight);
// SHIP CONTROLS
var shipControls = new bkcore.hexgl.ShipControls(ctx);
shipControls.collisionMap = this.lib.get("analysers", "track.cityscape.collision");
// console.log(shipControls.collisionMap.pixels.data.join(','))
shipControls.collisionPixelRatio = 2048.0 / 6000.0;
shipControls.collisionDetection = true;
shipControls.heightMap = this.lib.get("analysers", "track.cityscape.height");
// console.log(shipControls.heightMap.pixels.data.join(','))
shipControls.heightPixelRatio = 2048.0 / 6000.0;
shipControls.heightBias = 4.0;
shipControls.heightScale = 10.0;
shipControls.control(ship);
shipControls.sounds = sounds;
ctx.components.shipControls = shipControls;
// ctx.tweakShipControls();
// SHIP EFFECTS AND PARTICLES
var fxParams = {
scene: scene,
shipControls: shipControls,
booster: booster,
boosterSprite: boosterSprite,
boosterLight: boosterLight,
useParticles: false
};
// desktop + quality mid or high
if(quality > 2)
{
fxParams.textureCloud = this.lib.get("textures", "cloud");
fxParams.textureSpark = this.lib.get("textures", "spark");
fxParams.useParticles = true;
}
ctx.components.shipEffects = new bkcore.hexgl.ShipEffects(fxParams);
var city = ctx.addObject(scene, this.lib.get("objects", "city"),0,0,0);
let firstAidKitBase1 = ctx.addObject(scene, this.lib.get("objects", "firstAidKit.base"), 0, 0, 0);
let firstAidKitPlus1 = ctx.addObject(scene, this.lib.get("objects", "firstAidKit.plus"), 0, 0, 0);
firstAidKitBase1.scale.set(0.2, 0.2, 0.2);
firstAidKitPlus1.scale.set(0.2, 0.2, 0.2);
var firstAidKitPlusControl1 = new bkcore.hexgl.FirstAidKitPlusControl(ctx);
firstAidKitPlusControl1.control(firstAidKitPlus1);
ctx.components.firstAidKitPlusControl1 = firstAidKitPlusControl1;
let firstAidKitBase2 = ctx.addObject(scene, this.lib.get("objects", "firstAidKit.base").clone(), 0, 0, 0);
let firstAidKitPlus2 = ctx.addObject(scene, this.lib.get("objects", "firstAidKit.plus").clone(), 0, 0, 0);
firstAidKitBase2.scale.set(0.2, 0.2, 0.2);
firstAidKitPlus2.scale.set(0.2, 0.2, 0.2);
var firstAidKitPlusControl2 = new bkcore.hexgl.FirstAidKitPlusControl(ctx);
firstAidKitPlusControl2.control(firstAidKitPlus2);
ctx.components.firstAidKitPlusControl2 = firstAidKitPlusControl2;
// CAMERA
ctx.components.cameraChase = new bkcore.hexgl.CameraChase({
ctx: ctx,
target: ship,
camera: camera,
cameraCube: ctx.manager.get("sky").camera,
lerp: 0.5,
yoffset: 8.0,
zoffset: 10.0,
viewOffset: 10.0
});
/*var size = new THREE.Box3().setFromObject( track ).getSize( new THREE.Vector3() );
console.log(size);*/
ctx.manager.add("game", scene, camera, function(delta, renderer)
{
if(delta > 25 && this.objects.lowFPS < 1000) this.objects.lowFPS++;
var dt = delta/16.6;
if(this.objects.hud.time !== ""){
this.objects.components.shipControls.requestUpdate(dt);
}
this.objects.components.shipEffects.update(dt, camera);
this.objects.components.cameraChase.update(dt, this.objects.components.shipControls.getSpeedRatio());
/*this.objects.time += 0.002;
var c = this.objects.components.cameraChase.camera;
c.position.set(
Math.cos(this.objects.time)*15+this.objects.components.shipControls.dummy.position.x,
10+this.objects.components.shipControls.dummy.position.y,
Math.sin(this.objects.time)*15+this.objects.components.shipControls.dummy.position.z
);
c.lookAt(this.objects.components.shipControls.dummy.position);
this.objects.components.cameraChase.cameraCube.rotation.copy(c.rotation);*/
this.objects.composers.game.render(dt);
if(this.objects.hud) this.objects.hud.update(
this.objects.components.shipControls.getRealSpeed(100),
this.objects.components.shipControls.getRealSpeedRatio(),
this.objects.components.shipControls.getShield(100),
this.objects.components.shipControls.getShieldRatio(),
this.objects.components.shipControls.dummy
);
if(this.objects.components.shipControls.getShieldRatio() < 0.2)
this.objects.extras.vignetteColor.setHex(0x992020);
else
this.objects.extras.vignetteColor.setHex(0x458ab1);
},
{
components: ctx.components,
composers: ctx.composers,
extras: ctx.extras,
quality: quality,
hud: ctx.hud,
time: 0.0,
lowFPS: 0
});
},
}