changed game dynamics.
This commit is contained in:
parent
b85d1f5b09
commit
5b7d04bd39
@ -12,10 +12,12 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<link rel="prefetch" href="/background.mp3"/>
|
||||||
|
<link rel="prefetch" href="/8192.webp"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="gameCanvas"></canvas>
|
<canvas id="gameCanvas"></canvas>
|
||||||
<div id="startGame">
|
<div id="mainDiv">
|
||||||
<div id="loadingDiv">Loading...</div>
|
<div id="loadingDiv">Loading...</div>
|
||||||
<button id="startButton">Start Game</button>
|
<button id="startButton">Start Game</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,31 +8,7 @@ body {
|
|||||||
font-family: Roboto, sans-serif;
|
font-family: Roboto, sans-serif;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
}
|
}
|
||||||
#startGame {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
padding: 48px;
|
|
||||||
border-radius: 12px;
|
|
||||||
background-color: #000;
|
|
||||||
color: #fff;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
#music {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
top: 75%;
|
|
||||||
left: 50%;
|
|
||||||
width: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
padding: 48px;
|
|
||||||
border-radius: 12px;
|
|
||||||
background-color: #000;
|
|
||||||
color: #fff;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
#startButton {
|
#startButton {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -41,11 +17,25 @@ body {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: xxx-large;
|
font-size: xxx-large;
|
||||||
display: none;
|
display: none;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
#startButton.ready {
|
#startButton.ready {
|
||||||
display: block;
|
display: block;
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
|
#loadingDiv {
|
||||||
|
z-index: 1000;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#mainDiv {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
#gameCanvas {
|
#gameCanvas {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@ -2,5 +2,6 @@ import {Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
|||||||
|
|
||||||
export class DefaultScene {
|
export class DefaultScene {
|
||||||
public static MainScene: Scene;
|
public static MainScene: Scene;
|
||||||
|
public static DemoScene: Scene;
|
||||||
public static XR: WebXRDefaultExperience;
|
public static XR: WebXRDefaultExperience;
|
||||||
}
|
}
|
||||||
18
src/demo.ts
Normal file
18
src/demo.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import {DefaultScene} from "./defaultScene";
|
||||||
|
import {ArcRotateCamera, MeshBuilder, PointerEventTypes, Vector3} from "@babylonjs/core";
|
||||||
|
import {Main} from "./main";
|
||||||
|
|
||||||
|
export default class Demo {
|
||||||
|
private _main: Main;
|
||||||
|
constructor(main: Main) {
|
||||||
|
this._main = main;
|
||||||
|
this.initialize();
|
||||||
|
}
|
||||||
|
private async initialize() {
|
||||||
|
if (!DefaultScene.DemoScene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const scene = DefaultScene.DemoScene;
|
||||||
|
const camera = new ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2, 5, new Vector3(0, 0, 0), scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/level.ts
Normal file
8
src/level.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import {Observable} from "@babylonjs/core";
|
||||||
|
|
||||||
|
export default interface Level {
|
||||||
|
initialize(): void;
|
||||||
|
dispose(): void;
|
||||||
|
play(): void;
|
||||||
|
getReadyObservable(): Observable<Level>;
|
||||||
|
}
|
||||||
@ -1,35 +1,59 @@
|
|||||||
import {DefaultScene} from "./defaultScene";
|
import {DefaultScene} from "./defaultScene";
|
||||||
import {
|
import {
|
||||||
AbstractMesh,
|
AbstractMesh,
|
||||||
Color3, DistanceConstraint, InstancedMesh, Mesh,
|
Color3, DistanceConstraint, Engine, InstancedMesh, Mesh,
|
||||||
MeshBuilder,
|
MeshBuilder,
|
||||||
Observable,
|
Observable,
|
||||||
ParticleHelper,
|
ParticleHelper,
|
||||||
PhysicsAggregate,
|
PhysicsAggregate,
|
||||||
PhysicsMotionType,
|
PhysicsMotionType,
|
||||||
PhysicsShapeType,
|
PhysicsShapeType, Sound,
|
||||||
StandardMaterial, TransformNode,
|
StandardMaterial, TransformNode,
|
||||||
Vector3
|
Vector3
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {Ship} from "./ship";
|
import {Ship} from "./ship";
|
||||||
import {ScoreEvent} from "./scoreEvent";
|
import {ScoreEvent} from "./scoreEvent";
|
||||||
import {RockFactory} from "./starfield";
|
import {RockFactory} from "./starfield";
|
||||||
|
import Level from "./level";
|
||||||
|
|
||||||
export class Level1 {
|
export class Level1 implements Level {
|
||||||
private _ship: Ship;
|
private _ship: Ship;
|
||||||
|
private _onReadyObservable: Observable<Level> = new Observable<Level>();
|
||||||
private _initialized: boolean = false;
|
private _initialized: boolean = false;
|
||||||
private _startBase: AbstractMesh;
|
private _startBase: AbstractMesh;
|
||||||
private _endBase: AbstractMesh;
|
private _endBase: AbstractMesh;
|
||||||
public onScoreObservable: Observable<ScoreEvent> = new Observable<ScoreEvent>();
|
public onScoreObservable: Observable<ScoreEvent> = new Observable<ScoreEvent>();
|
||||||
|
|
||||||
constructor(ship: Ship) {
|
constructor() {
|
||||||
this._ship = ship;
|
this._ship = new Ship();
|
||||||
|
const xr = DefaultScene.XR;
|
||||||
|
xr.baseExperience.onInitialXRPoseSetObservable.add(() => {
|
||||||
|
xr.baseExperience.camera.parent = this._ship.transformNode;
|
||||||
|
xr.baseExperience.camera.position = new Vector3(0, 0, 0);
|
||||||
|
});
|
||||||
|
xr.input.onControllerAddedObservable.add((controller) => {
|
||||||
|
this._ship.addController(controller);
|
||||||
|
});
|
||||||
this.createStartBase();
|
this.createStartBase();
|
||||||
this.createEndBase();
|
|
||||||
|
this.initialize();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getReadyObservable(): Observable<Level> {
|
||||||
|
return this._onReadyObservable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private scored: Set<string> = new Set<string>();
|
private scored: Set<string> = new Set<string>();
|
||||||
|
public play() {
|
||||||
|
const background = new Sound("background", "/background.mp3", DefaultScene.MainScene, () => {
|
||||||
|
}, {loop: true, autoplay: true, volume: .2});
|
||||||
|
DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
||||||
|
}
|
||||||
|
public dispose() {
|
||||||
|
this._startBase.dispose();
|
||||||
|
this._endBase.dispose();
|
||||||
|
}
|
||||||
public async initialize() {
|
public async initialize() {
|
||||||
if (this._initialized) {
|
if (this._initialized) {
|
||||||
return;
|
return;
|
||||||
@ -37,43 +61,18 @@ export class Level1 {
|
|||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
ParticleHelper.BaseAssetsUrl = window.location.href;
|
ParticleHelper.BaseAssetsUrl = window.location.href;
|
||||||
this._ship.position = new Vector3(0, 1, 0);
|
this._ship.position = new Vector3(0, 1, 0);
|
||||||
|
|
||||||
await RockFactory.init();
|
await RockFactory.init();
|
||||||
const distance = Vector3.Distance(this._startBase.getAbsolutePosition(), this._endBase.getAbsolutePosition());
|
|
||||||
const baseTransform = new TransformNode("baseTransform", DefaultScene.MainScene);
|
const baseTransform = new TransformNode("baseTransform", DefaultScene.MainScene);
|
||||||
baseTransform.position = this._endBase.getAbsolutePosition();
|
baseTransform.position = this._startBase.getAbsolutePosition();
|
||||||
|
|
||||||
for (let i = 0; i < 20; i++) {
|
|
||||||
//const constraintDistance = distance - 20;
|
|
||||||
const dist = (Math.random() * 80) + 20;
|
|
||||||
const startPos = this._endBase.getAbsolutePosition().add(new Vector3(dist,dist,dist));
|
|
||||||
const startTrans = new TransformNode("startTransform", DefaultScene.MainScene);
|
|
||||||
startTrans.position = startPos;
|
|
||||||
startTrans.setParent(baseTransform);
|
|
||||||
baseTransform.rotation = Vector3.Random(0, Math.PI * 2);
|
|
||||||
const rock = await RockFactory.createRock(i, startTrans.getAbsolutePosition(), Vector3.Random(1, 5))
|
|
||||||
startTrans.dispose();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
const dist = (Math.random() * 200) + 190;
|
||||||
|
const rock = await RockFactory.createRock(i, new Vector3(Math.random() * 200 +50 * Math.sign(Math.random() -.5),200,200), Vector3.Random(1, 5))
|
||||||
const constraint = new DistanceConstraint(dist, DefaultScene.MainScene);
|
const constraint = new DistanceConstraint(dist, DefaultScene.MainScene);
|
||||||
rock.physicsBody.addConstraint(this._endBase.physicsBody, constraint);
|
//rock.physicsBody.addConstraint(this._endBase.physicsBody, constraint);
|
||||||
rock.physicsBody.applyImpulse(Vector3.Random(-1, 1).scale(1000), rock.getAbsolutePosition());
|
this._startBase.physicsBody.addConstraint(rock.physicsBody, constraint);
|
||||||
rock.physicsBody.setAngularVelocity(Vector3.Random(-.5, .5));
|
rock.physicsBody.applyForce(Vector3.Random(-1, 1).scale(50000000), rock.getAbsolutePosition());
|
||||||
/* const material = new StandardMaterial("material", DefaultScene.MainScene);
|
//rock.physicsBody.setAngularVelocity(Vector3.Random(-.5, .5));
|
||||||
material.emissiveColor = Color3.Random();
|
|
||||||
const sphere = MeshBuilder.CreateSphere("sphere", {diameter: 1}, DefaultScene.MainScene);
|
|
||||||
sphere.material = material;
|
|
||||||
|
|
||||||
window.setInterval(() => {
|
|
||||||
const track = new InstancedMesh("track", sphere);
|
|
||||||
track.position = rock.physicsBody.transformNode.getAbsolutePosition();
|
|
||||||
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +96,7 @@ export class Level1 {
|
|||||||
height: 1,
|
height: 1,
|
||||||
tessellation: 72
|
tessellation: 72
|
||||||
}, DefaultScene.MainScene);
|
}, DefaultScene.MainScene);
|
||||||
mesh.position = new Vector3(0, 5, 200);
|
mesh.position = new Vector3(0, 5, 500);
|
||||||
const material = new StandardMaterial("material", DefaultScene.MainScene);
|
const material = new StandardMaterial("material", DefaultScene.MainScene);
|
||||||
material.diffuseColor = new Color3(0, 1, 0);
|
material.diffuseColor = new Color3(0, 1, 0);
|
||||||
mesh.material = material;
|
mesh.material = material;
|
||||||
|
|||||||
85
src/main.ts
85
src/main.ts
@ -6,21 +6,42 @@ import {DefaultScene} from "./defaultScene";
|
|||||||
import {Ship} from "./ship";
|
import {Ship} from "./ship";
|
||||||
import {Level1} from "./level1";
|
import {Level1} from "./level1";
|
||||||
import {Scoreboard} from "./scoreboard";
|
import {Scoreboard} from "./scoreboard";
|
||||||
|
import Demo from "./demo";
|
||||||
|
import Level from "./level";
|
||||||
|
|
||||||
const webGpu = false;
|
const webGpu = false;
|
||||||
const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement);
|
const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement);
|
||||||
|
enum GameState {
|
||||||
|
PLAY,
|
||||||
|
DEMO
|
||||||
|
}
|
||||||
export class Main {
|
export class Main {
|
||||||
|
private _loadingDiv: HTMLElement;
|
||||||
|
private _currentLevel: Level;
|
||||||
|
private _gameState: GameState = GameState.DEMO;
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this._loadingDiv = document.querySelector('#loadingDiv');
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
|
||||||
|
|
||||||
|
document.querySelector('#startButton').addEventListener('click', () => {
|
||||||
|
Engine.audioEngine.unlock();
|
||||||
|
this.play();
|
||||||
|
document.querySelector('#mainDiv').remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private _started = false;
|
||||||
|
public play() {
|
||||||
|
this._gameState = GameState.PLAY;
|
||||||
|
this._currentLevel.play();
|
||||||
|
}
|
||||||
|
public demo() {
|
||||||
|
this._gameState = GameState.DEMO;
|
||||||
|
}
|
||||||
private async initialize() {
|
private async initialize() {
|
||||||
|
this._loadingDiv.innerText = "Initializing.";
|
||||||
await this.setupScene();
|
await this.setupScene();
|
||||||
|
|
||||||
const xr = await WebXRDefaultExperience.CreateAsync(DefaultScene.MainScene, {
|
DefaultScene.XR = await WebXRDefaultExperience.CreateAsync(DefaultScene.MainScene, {
|
||||||
disablePointerSelection: true,
|
disablePointerSelection: true,
|
||||||
disableTeleportation: true,
|
disableTeleportation: true,
|
||||||
disableNearInteraction: true,
|
disableNearInteraction: true,
|
||||||
@ -28,29 +49,17 @@ export class Main {
|
|||||||
disableDefaultUI: true,
|
disableDefaultUI: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const ship = new Ship();
|
this.setLoadingMessage("Get Ready!");
|
||||||
const scoreboard = new Scoreboard();
|
this.setLoadingMessage("Initializing Level...");
|
||||||
const level = new Level1(ship);
|
this._currentLevel = new Level1();
|
||||||
|
this._currentLevel.getReadyObservable().add(() => {
|
||||||
|
|
||||||
|
});
|
||||||
const photoDome = new PhotoDome("testdome", '/8192.webp', {}, DefaultScene.MainScene);
|
const photoDome = new PhotoDome("testdome", '/8192.webp', {}, DefaultScene.MainScene);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xr.baseExperience.onInitialXRPoseSetObservable.add(() => {
|
|
||||||
xr.baseExperience.camera.parent = ship.transformNode;
|
|
||||||
xr.baseExperience.camera.position = new Vector3(0, 0, 0);
|
|
||||||
|
|
||||||
level.onScoreObservable.add((score) => {
|
|
||||||
scoreboard.onscoreObservable.notifyObservers(score);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
xr.input.onControllerAddedObservable.add((controller) => {
|
|
||||||
ship.addController(controller);
|
|
||||||
});
|
|
||||||
DefaultScene.XR = xr;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private setLoadingMessage(message: string) {
|
||||||
|
this._loadingDiv.innerText = message;
|
||||||
|
}
|
||||||
private async setupScene() {
|
private async setupScene() {
|
||||||
|
|
||||||
let engine: WebGPUEngine | Engine = null;
|
let engine: WebGPUEngine | Engine = null;
|
||||||
@ -64,30 +73,36 @@ export class Main {
|
|||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
engine.resize();
|
engine.resize();
|
||||||
}
|
}
|
||||||
|
DefaultScene.DemoScene = new Scene(engine);
|
||||||
DefaultScene.MainScene = new Scene(engine);
|
DefaultScene.MainScene = new Scene(engine);
|
||||||
|
|
||||||
|
this.setLoadingMessage("Initializing Physics Engine..");
|
||||||
await this.setupPhysics();
|
await this.setupPhysics();
|
||||||
|
|
||||||
this.setupInspector();
|
this.setupInspector();
|
||||||
|
|
||||||
engine.runRenderLoop(() => {
|
engine.runRenderLoop(() => {
|
||||||
DefaultScene.MainScene.render();
|
if (!this._started) {
|
||||||
|
this._started = true;
|
||||||
|
this._loadingDiv.remove();
|
||||||
|
const start = document.querySelector('#startButton');
|
||||||
|
start.classList.add('ready');
|
||||||
|
}
|
||||||
|
if (this._gameState == GameState.PLAY) {
|
||||||
|
DefaultScene.MainScene.render();
|
||||||
|
} else {
|
||||||
|
DefaultScene.DemoScene.render();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupPhysics() {
|
private async setupPhysics() {
|
||||||
const havok = await HavokPhysics();
|
const havok = await HavokPhysics();
|
||||||
|
|
||||||
const havokPlugin = new HavokPlugin(true, havok);
|
const havokPlugin = new HavokPlugin(true, havok);
|
||||||
DefaultScene.MainScene.enablePhysics(new Vector3(0, 0, 0), havokPlugin);
|
DefaultScene.MainScene.enablePhysics(new Vector3(0, 0, 0), havokPlugin);
|
||||||
|
|
||||||
DefaultScene.MainScene.collisionsEnabled = true;
|
DefaultScene.MainScene.collisionsEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupInspector() {
|
private setupInspector() {
|
||||||
|
this.setLoadingMessage("Initializing Inspector...");
|
||||||
window.addEventListener("keydown", (ev) => {
|
window.addEventListener("keydown", (ev) => {
|
||||||
if (ev.key == 'i') {
|
if (ev.key == 'i') {
|
||||||
import ("@babylonjs/inspector").then((inspector) => {
|
import ("@babylonjs/inspector").then((inspector) => {
|
||||||
@ -102,7 +117,7 @@ export class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const main = new Main();
|
const main = new Main();
|
||||||
|
const demo = new Demo(main);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
147
src/ship.ts
147
src/ship.ts
@ -22,7 +22,7 @@ import {
|
|||||||
WebXRInputSource
|
WebXRInputSource
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {DefaultScene} from "./defaultScene";
|
import {DefaultScene} from "./defaultScene";
|
||||||
import {Radar} from "./radar";
|
|
||||||
import {ShipEngine} from "./shipEngine";
|
import {ShipEngine} from "./shipEngine";
|
||||||
import {Level1} from "./level1";
|
import {Level1} from "./level1";
|
||||||
|
|
||||||
@ -71,6 +71,45 @@ export class Ship {
|
|||||||
private _camera: FreeCamera;
|
private _camera: FreeCamera;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
|
this.setup();
|
||||||
|
this.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private shoot() {
|
||||||
|
this._shot.play();
|
||||||
|
const ammo = MeshBuilder.CreateCapsule("bullet", {radius: .1, height: 2.5}, DefaultScene.MainScene);
|
||||||
|
ammo.parent = this._ship
|
||||||
|
ammo.position.y = 2;
|
||||||
|
ammo.rotation.x = Math.PI / 2;
|
||||||
|
ammo.setParent(null);
|
||||||
|
const ammoAggregate = new PhysicsAggregate(ammo, PhysicsShapeType.CONVEX_HULL, {
|
||||||
|
mass: 1000,
|
||||||
|
restitution: 0
|
||||||
|
}, DefaultScene.MainScene);
|
||||||
|
|
||||||
|
|
||||||
|
ammo.material = this._ammoMaterial;
|
||||||
|
ammoAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||||
|
|
||||||
|
ammoAggregate.body.setLinearVelocity(this._ship.forward.scale(200).add(this._ship.physicsBody.getLinearVelocity()));
|
||||||
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
ammoAggregate.dispose();
|
||||||
|
ammo.dispose()
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
public set position(newPosition: Vector3) {
|
||||||
|
const body = this._ship.physicsBody;
|
||||||
|
body.disablePreStep = false;
|
||||||
|
body.transformNode.position.copyFrom(newPosition);
|
||||||
|
DefaultScene.MainScene.onAfterRenderObservable.addOnce(() => {
|
||||||
|
body.disablePreStep = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
private setup() {
|
||||||
this._ship = new TransformNode("ship", DefaultScene.MainScene);
|
this._ship = new TransformNode("ship", DefaultScene.MainScene);
|
||||||
this._glowLayer = new GlowLayer('bullets', DefaultScene.MainScene);
|
this._glowLayer = new GlowLayer('bullets', DefaultScene.MainScene);
|
||||||
this._glowLayer.intensity = 1;
|
this._glowLayer.intensity = 1;
|
||||||
@ -87,65 +126,12 @@ export class Ship {
|
|||||||
{loop: false, autoplay: false, volume: .5});
|
{loop: false, autoplay: false, volume: .5});
|
||||||
this._ammoMaterial = new StandardMaterial("ammoMaterial", DefaultScene.MainScene);
|
this._ammoMaterial = new StandardMaterial("ammoMaterial", DefaultScene.MainScene);
|
||||||
this._ammoMaterial.emissiveColor = new Color3(1, 1, 0);
|
this._ammoMaterial.emissiveColor = new Color3(1, 1, 0);
|
||||||
this.initialize();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private shoot() {
|
|
||||||
this._shot.play();
|
|
||||||
const ammo = MeshBuilder.CreateCapsule("bullet", {radius: .05, height: 1.5}, DefaultScene.MainScene);
|
|
||||||
ammo.parent = this._ship
|
|
||||||
ammo.position.y = 2;
|
|
||||||
ammo.rotation.x = Math.PI / 2;
|
|
||||||
ammo.setParent(null);
|
|
||||||
const ammoAggregate = new PhysicsAggregate(ammo, PhysicsShapeType.CONVEX_HULL, {
|
|
||||||
mass: 1000,
|
|
||||||
restitution: 0
|
|
||||||
}, DefaultScene.MainScene);
|
|
||||||
|
|
||||||
|
|
||||||
ammo.material = this._ammoMaterial;
|
|
||||||
ammoAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC);
|
|
||||||
|
|
||||||
ammoAggregate.body.setLinearVelocity(this._ship.forward.scale(150).add(this._ship.physicsBody.getLinearVelocity()));
|
|
||||||
|
|
||||||
window.setTimeout(() => {
|
|
||||||
ammoAggregate.dispose();
|
|
||||||
ammo.dispose()
|
|
||||||
}, 5000)
|
|
||||||
}
|
|
||||||
|
|
||||||
public set position(newPosition: Vector3) {
|
|
||||||
const body = this._ship.physicsBody;
|
|
||||||
body.disablePreStep = false;
|
|
||||||
body.transformNode.position.copyFrom(newPosition);
|
|
||||||
DefaultScene.MainScene.onAfterRenderObservable.addOnce(() => {
|
|
||||||
body.disablePreStep = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private async initialize() {
|
|
||||||
const light = new DirectionalLight("light", new Vector3(.1, -1, 0), DefaultScene.MainScene);
|
const light = new DirectionalLight("light", new Vector3(.1, -1, 0), DefaultScene.MainScene);
|
||||||
const ship = this._ship;
|
|
||||||
const landingLight = new SpotLight("landingLight", new Vector3(0, 0, 0), new Vector3(0, -.5, .5), 1.5, .5, DefaultScene.MainScene);
|
|
||||||
landingLight.parent = ship;
|
|
||||||
landingLight.position.z = 5;
|
|
||||||
const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "cockpit3.glb", DefaultScene.MainScene);
|
|
||||||
const shipMesh = importMesh.meshes[0];
|
|
||||||
shipMesh.id = "shipMesh";
|
|
||||||
shipMesh.name = "shipMesh";
|
|
||||||
shipMesh.parent = ship;
|
|
||||||
shipMesh.rotation.y = Math.PI;
|
|
||||||
shipMesh.position.y = 1;
|
|
||||||
shipMesh.position.z = -1;
|
|
||||||
DefaultScene.MainScene.getMaterialById('glass_mat.002').alpha = .7;
|
|
||||||
this._camera = new FreeCamera("Flat Camera",
|
|
||||||
new Vector3(0, .5, 0),
|
|
||||||
DefaultScene.MainScene);
|
|
||||||
this._camera.parent = ship;
|
|
||||||
|
|
||||||
const agg = new PhysicsAggregate(ship, PhysicsShapeType.BOX, {
|
const landingLight = new SpotLight("landingLight", new Vector3(0, 0, 0), new Vector3(0, -.5, .5), 1.5, .5, DefaultScene.MainScene);
|
||||||
|
landingLight.parent = this._ship;
|
||||||
|
landingLight.position.z = 5;
|
||||||
|
const agg = new PhysicsAggregate(this._ship, PhysicsShapeType.BOX, {
|
||||||
mass: 100,
|
mass: 100,
|
||||||
extents: new Vector3(4, 4, 7.4),
|
extents: new Vector3(4, 4, 7.4),
|
||||||
center: new Vector3(0, 1, 1.8)
|
center: new Vector3(0, 1, 1.8)
|
||||||
@ -155,8 +141,7 @@ export class Ship {
|
|||||||
agg.body.setLinearDamping(.1);
|
agg.body.setLinearDamping(.1);
|
||||||
agg.body.setAngularDamping(.2);
|
agg.body.setAngularDamping(.2);
|
||||||
agg.body.setAngularVelocity(new Vector3(0, 0, 0));
|
agg.body.setAngularVelocity(new Vector3(0, 0, 0));
|
||||||
agg.body.setCollisionCallbackEnabled(true)
|
agg.body.setCollisionCallbackEnabled(true);
|
||||||
DefaultScene.MainScene.setActiveCameraByName("Flat Camera");
|
|
||||||
this.setupKeyboard();
|
this.setupKeyboard();
|
||||||
this.setupMouse();
|
this.setupMouse();
|
||||||
this._controllerObservable.add(this.controllerCallback);
|
this._controllerObservable.add(this.controllerCallback);
|
||||||
@ -164,6 +149,13 @@ export class Ship {
|
|||||||
this._rotationNode = new TransformNode("rotation", DefaultScene.MainScene);
|
this._rotationNode = new TransformNode("rotation", DefaultScene.MainScene);
|
||||||
this._forwardNode.parent = this._ship;
|
this._forwardNode.parent = this._ship;
|
||||||
this._rotationNode.parent = this._ship;
|
this._rotationNode.parent = this._ship;
|
||||||
|
this._camera = new FreeCamera("Flat Camera",
|
||||||
|
new Vector3(0, .5, 0),
|
||||||
|
DefaultScene.MainScene);
|
||||||
|
this._camera.parent = this._ship;
|
||||||
|
|
||||||
|
DefaultScene.MainScene.setActiveCameraByName("Flat Camera");
|
||||||
|
|
||||||
//const sightPos = this._forwardNode.position.scale(30);
|
//const sightPos = this._forwardNode.position.scale(30);
|
||||||
const sight = MeshBuilder.CreateSphere("sight", {diameter: 1}, DefaultScene.MainScene);
|
const sight = MeshBuilder.CreateSphere("sight", {diameter: 1}, DefaultScene.MainScene);
|
||||||
sight.parent = this._ship
|
sight.parent = this._ship
|
||||||
@ -171,30 +163,21 @@ export class Ship {
|
|||||||
signtMaterial.emissiveColor = Color3.Yellow();
|
signtMaterial.emissiveColor = Color3.Yellow();
|
||||||
sight.material = signtMaterial;
|
sight.material = signtMaterial;
|
||||||
sight.position = new Vector3(0, 2, 125);
|
sight.position = new Vector3(0, 2, 125);
|
||||||
|
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.applyForce();
|
this.applyForce();
|
||||||
}, 50);
|
}, 50);
|
||||||
this.onReadyObservable.notifyObservers(true);
|
}
|
||||||
//const mirror = new Mirror(this._ship);
|
private async initialize() {
|
||||||
const radar = new Radar(this._ship);
|
const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "cockpit3.glb", DefaultScene.MainScene);
|
||||||
|
const shipMesh = importMesh.meshes[0];
|
||||||
document.querySelector('#loadingDiv').remove();
|
shipMesh.id = "shipMesh";
|
||||||
//const startButton = document.querySelector('#startButton');
|
shipMesh.name = "shipMesh";
|
||||||
//startButton.classList.add('ready');
|
shipMesh.parent = this._ship;
|
||||||
const level = new Level1(this);
|
shipMesh.rotation.y = Math.PI;
|
||||||
const background = new Sound("background", "/background.mp3", DefaultScene.MainScene, () => {
|
shipMesh.position.y = 1;
|
||||||
const startButton = document.querySelector('#startButton');
|
shipMesh.position.z = -1;
|
||||||
startButton.classList.add('ready');
|
DefaultScene.MainScene.getMaterialById('glass_mat.002').alpha = .7;
|
||||||
startButton.addEventListener('click', async () => {
|
|
||||||
if (!Engine.audioEngine.unlocked) {
|
|
||||||
Engine.audioEngine.unlock();
|
|
||||||
}
|
|
||||||
console.log('start background');
|
|
||||||
await DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
|
||||||
await level.initialize();
|
|
||||||
});
|
|
||||||
}, {loop: true, autoplay: true, volume: .2});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +222,7 @@ export class Ship {
|
|||||||
this._thrust.play();
|
this._thrust.play();
|
||||||
}
|
}
|
||||||
this._thrust.setVolume(Math.abs(this._leftStickVector.y));
|
this._thrust.setVolume(Math.abs(this._leftStickVector.y));
|
||||||
this._forwardValue += this._leftStickVector.y * .4;
|
this._forwardValue += this._leftStickVector.y * .8;
|
||||||
} else {
|
} else {
|
||||||
if (this._thrust.isPlaying) {
|
if (this._thrust.isPlaying) {
|
||||||
this._thrust.pause();
|
this._thrust.pause();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user