Started cleaning up audio, rendering artifacts.

This commit is contained in:
Michael Mainguy 2025-02-16 16:44:18 -06:00
parent de108e8a40
commit b85d1f5b09
11 changed files with 298 additions and 242 deletions

Binary file not shown.

BIN
public/shot2.mp3 Normal file

Binary file not shown.

BIN
public/thrust3.mp3 Normal file

Binary file not shown.

BIN
public/thrust4.mp3 Normal file

Binary file not shown.

BIN
public/thrust5.mp3 Normal file

Binary file not shown.

View File

@ -1,143 +1,117 @@
import {DefaultScene} from "./defaultScene"; import {DefaultScene} from "./defaultScene";
import { import {
Color3, AbstractMesh,
HavokPlugin, Color3, DistanceConstraint, InstancedMesh, Mesh,
MeshBuilder, Observable, ParticleHelper, ParticleSystem, ParticleSystemSet, MeshBuilder,
Observable,
ParticleHelper,
PhysicsAggregate, PhysicsAggregate,
PhysicsMotionType, PhysicsMotionType,
PhysicsShapeType, PhysicsShapeType,
StandardMaterial, Texture, 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 {createRock} from "./starfield"; import {RockFactory} from "./starfield";
export class Level1 { export class Level1 {
private _ship: Ship; private _ship: Ship;
private _explosion: ParticleSystemSet private _initialized: boolean = false;
private _startBase: AbstractMesh;
private _endBase: AbstractMesh;
public onScoreObservable: Observable<ScoreEvent> = new Observable<ScoreEvent>(); public onScoreObservable: Observable<ScoreEvent> = new Observable<ScoreEvent>();
constructor(ship: Ship) { constructor(ship: Ship) {
this._ship = ship; this._ship = ship;
this.initialize(); this.createStartBase();
this.createEndBase();
} }
private scored: Set<string> = new Set<string>(); private scored: Set<string> = new Set<string>();
private async initialize() {
const phys = DefaultScene.MainScene.getPhysicsEngine().getPhysicsPlugin() as HavokPlugin; public async initialize() {
if (this._initialized) {
return;
}
this._initialized = true;
ParticleHelper.BaseAssetsUrl = window.location.href; ParticleHelper.BaseAssetsUrl = window.location.href;
this._ship.position = new Vector3(0, 1, 0);
//console.log(window.location.href); await RockFactory.init();
DefaultScene.MainScene.onReadyObservable.addOnce(async () => { const distance = Vector3.Distance(this._startBase.getAbsolutePosition(), this._endBase.getAbsolutePosition());
this._explosion = await ParticleHelper.CreateAsync("explosion", DefaultScene.MainScene); const baseTransform = new TransformNode("baseTransform", DefaultScene.MainScene);
}); baseTransform.position = this._endBase.getAbsolutePosition();
//
/*phys.onTriggerCollisionObservable.add((eventData) => {
if (eventData.collider.transformNode.id.indexOf('star') > -1) {
return;
}
if (this.scored.has(eventData.collidedAgainst.transformNode.id)) {
return;
} else {
this.scored.add(eventData.collidedAgainst.transformNode.id);
//this.onScoreObservable.notifyObservers(1);
}
}); for (let i = 0; i < 20; i++) {
*/ //const constraintDistance = distance - 20;
phys.onCollisionObservable.add( (eventData) => { const dist = (Math.random() * 80) + 20;
this.onScoreObservable.notifyObservers({score: 0, message: eventData?.impulse?.toFixed(2)}); const startPos = this._endBase.getAbsolutePosition().add(new Vector3(dist,dist,dist));
if ((eventData.collidedAgainst.transformNode.id == 'bullet' || const startTrans = new TransformNode("startTransform", DefaultScene.MainScene);
eventData.collider.transformNode.id == 'bullet') && startTrans.position = startPos;
(eventData.collidedAgainst.transformNode.id.indexOf('asteroid') > -1 || startTrans.setParent(baseTransform);
eventData.collider.transformNode.id.indexOf('asteroid') > -1) baseTransform.rotation = Vector3.Random(0, Math.PI * 2);
){ const rock = await RockFactory.createRock(i, startTrans.getAbsolutePosition(), Vector3.Random(1, 5))
const point = eventData.point.clone(); startTrans.dispose();
if (this._explosion) {
/*this._explosion.systems.forEach((system) => {
system.stop();
});*/
this._explosion.emitterNode = point;
this._explosion.start();
}
eventData.collider.transformNode.dispose();
eventData.collidedAgainst.transformNode.dispose()
eventData.collider.dispose();
eventData.collidedAgainst.dispose();
/*const myParticleSystem = new ParticleSystem("particles", 1000, DefaultScene.MainScene);
myParticleSystem.emitter = point;
myParticleSystem.emitRate = 100;
myParticleSystem.minEmitPower = 2;
myParticleSystem.maxEmitPower = 200;
const sphereEmitter = myParticleSystem.createSphereEmitter(10);
myParticleSystem.particleTexture = new Texture("./flare.png");
myParticleSystem.maxLifeTime = 10000;
//const coneEmitter = myParticleSystem.createConeEmitter(0.1, Math.PI / 9);
myParticleSystem.addSizeGradient(0, 2);
myParticleSystem.addSizeGradient(1, 4);
//myParticleSystem.isLocal = true;
myParticleSystem.start(); //S const constraint = new DistanceConstraint(dist, DefaultScene.MainScene);
console.log(eventData);*/ rock.physicsBody.addConstraint(this._endBase.physicsBody, constraint);
} rock.physicsBody.applyImpulse(Vector3.Random(-1, 1).scale(1000), rock.getAbsolutePosition());
rock.physicsBody.setAngularVelocity(Vector3.Random(-.5, .5));
/* const material = new StandardMaterial("material", DefaultScene.MainScene);
material.emissiveColor = Color3.Random();
const sphere = MeshBuilder.CreateSphere("sphere", {diameter: 1}, DefaultScene.MainScene);
sphere.material = material;
}); window.setInterval(() => {
this._ship.onReadyObservable.add(() => { const track = new InstancedMesh("track", sphere);
this._ship.position = new Vector3(0, 1, 0); track.position = rock.physicsBody.transformNode.getAbsolutePosition();
this.createStartBase();
this.createEndBase();
createRock(1, new Vector3(0,0, 70), new Vector3(10,10,10)); }, 200);
createRock(1, new Vector3(0,0, 100), new Vector3(10,10,10));
createRock(1, new Vector3(0,0, 130), new Vector3(10,10,10));
for (let i = 0; i < 100; i++) {
createRock(i , Vector3.Random(-200, 200), Vector3.Random(5,20))
.then((rock) => {
rock.physicsBody.setAngularVelocity(Vector3.Random(-1, 1));
});
} */
}
});
} }
private createStartBase() { private createStartBase() {
const mesh = MeshBuilder.CreateCylinder("startBase", {diameter: 10, height: 1, tessellation: 72}, DefaultScene.MainScene); const mesh = MeshBuilder.CreateCylinder("startBase", {
diameter: 10,
height: 1,
tessellation: 72
}, DefaultScene.MainScene);
const material = new StandardMaterial("material", DefaultScene.MainScene); const material = new StandardMaterial("material", DefaultScene.MainScene);
material.diffuseColor = new Color3(1, 1, 0); material.diffuseColor = new Color3(1, 1, 0);
mesh.material = material; mesh.material = material;
const agg = new PhysicsAggregate(mesh, PhysicsShapeType.CONVEX_HULL, {mass: 0}, DefaultScene.MainScene); const agg = new PhysicsAggregate(mesh, PhysicsShapeType.CONVEX_HULL, {mass: 0}, DefaultScene.MainScene);
agg.body.setMotionType(PhysicsMotionType.ANIMATED); agg.body.setMotionType(PhysicsMotionType.ANIMATED);
this._startBase = mesh;
} }
private createEndBase() { private createEndBase() {
const mesh = MeshBuilder.CreateCylinder("endBase", {diameter: 10, height: 1, tessellation: 72}, DefaultScene.MainScene); const mesh = MeshBuilder.CreateCylinder("endBase", {
diameter: 10,
height: 1,
tessellation: 72
}, DefaultScene.MainScene);
mesh.position = new Vector3(0, 5, 200); mesh.position = new Vector3(0, 5, 200);
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;
const agg = new PhysicsAggregate(mesh, PhysicsShapeType.CONVEX_HULL, {mass: 0}, DefaultScene.MainScene); const agg = new PhysicsAggregate(mesh, PhysicsShapeType.CONVEX_HULL, {mass: 0}, DefaultScene.MainScene);
agg.body.setMotionType(PhysicsMotionType.ANIMATED); agg.body.setMotionType(PhysicsMotionType.ANIMATED);
/*agg.body.setCollisionCallbackEnabled(true); this._endBase = mesh;
const collider = agg.body.getCollisionObservable().add((eventData) => {
if (eventData.collidedAgainst.transformNode.id == 'ship') {
console.log(eventData);
this.onScoreObservable.notifyObservers({score: 0,
message: eventData?.impulse?.toFixed(2)})
}
}); */
} }
private createTarget(i: number) { private createTarget(i: number) {
const target = MeshBuilder.CreateTorus("target" + i, {diameter: 10, tessellation: 72}, DefaultScene.MainScene); const target = MeshBuilder.CreateTorus("target" + i, {diameter: 10, tessellation: 72}, DefaultScene.MainScene);
const targetLOD = MeshBuilder.CreateTorus("target" + i, {
const targetLOD = MeshBuilder.CreateTorus("target" + i, {diameter: 50, tessellation: 10}, DefaultScene.MainScene); diameter: 50,
tessellation: 10
}, DefaultScene.MainScene);
targetLOD.parent = target; targetLOD.parent = target;
target.addLODLevel(300, targetLOD); target.addLODLevel(300, targetLOD);
@ -146,27 +120,17 @@ export class Level1 {
material.alpha = .9; material.alpha = .9;
target.material = material; target.material = material;
target.position = Vector3.Random(-1000, 1000); target.position = Vector3.Random(-1000, 1000);
target.rotation = Vector3.Random(0, Math.PI*2); target.rotation = Vector3.Random(0, Math.PI * 2);
const disc = MeshBuilder.CreateDisc("disc-"+i, {radius: 2, tessellation: 72}, DefaultScene.MainScene); const disc = MeshBuilder.CreateDisc("disc-" + i, {radius: 2, tessellation: 72}, DefaultScene.MainScene);
const discMaterial = new StandardMaterial("material", DefaultScene.MainScene); const discMaterial = new StandardMaterial("material", DefaultScene.MainScene);
discMaterial.ambientColor = new Color3(.1, 1, .1); discMaterial.ambientColor = new Color3(.1, 1, .1);
discMaterial.alpha = .2; discMaterial.alpha = .2;
target.addLODLevel(200, null); target.addLODLevel(200, null);
disc.material = discMaterial; disc.material = discMaterial;
disc.parent = target; disc.parent = target;
disc.rotation.x = -Math.PI/2; disc.rotation.x = -Math.PI / 2;
const agg = new PhysicsAggregate(disc, PhysicsShapeType.MESH, {mass: 0}, DefaultScene.MainScene); const agg = new PhysicsAggregate(disc, PhysicsShapeType.MESH, {mass: 0}, DefaultScene.MainScene);
agg.body.setMotionType(PhysicsMotionType.STATIC); agg.body.setMotionType(PhysicsMotionType.STATIC);
agg.shape.isTrigger = true; agg.shape.isTrigger = true;
//agg.shape.filterCollideMask = 2;
//agg.body.dispose();
//const body = new PhysicsShapeMesh(disc, DefaultScene.MainScene);
//agg.body.setCollisionCallbackEnabled(true);
/*agg.body.getCollisionObservable().add((eventData) => {
target.dispose(false, false);
agg.dispose();
});*/
} }
} }

View File

@ -28,13 +28,11 @@ export class Main {
disableDefaultUI: true, disableDefaultUI: true,
}); });
//const sun = createSun();
const ship = new Ship(); const ship = new Ship();
const scoreboard = new Scoreboard(); const scoreboard = new Scoreboard();
const level = new Level1(ship); const level = new Level1(ship);
const photoDome = new PhotoDome("testdome", '/8192.webp', {}, DefaultScene.MainScene); const photoDome = new PhotoDome("testdome", '/8192.webp', {}, DefaultScene.MainScene);
//starfield(sun);
//starfield(sun);
xr.baseExperience.onInitialXRPoseSetObservable.add(() => { xr.baseExperience.onInitialXRPoseSetObservable.add(() => {
@ -63,7 +61,6 @@ export class Main {
engine = new Engine(canvas, true); engine = new Engine(canvas, true);
} }
engine.setHardwareScalingLevel(1 / window.devicePixelRatio); engine.setHardwareScalingLevel(1 / window.devicePixelRatio);
//Engine.audioEngine.useCustomUnlockedButton = true;
window.onresize = () => { window.onresize = () => {
engine.resize(); engine.resize();
} }

View File

@ -47,9 +47,12 @@ export class Radar {
this._arrowMesh.material = material; this._arrowMesh.material = material;
window.setInterval(() => { window.setInterval(() => {
const point = scene.getMeshById('endBase'); const point = scene.getMeshById('endBase');
point.computeWorldMatrix(true) if (point) {
this._arrowMesh.position = this._radarTransform.absolutePosition; point.computeWorldMatrix(true)
this._arrowMesh.lookAt(point.absolutePosition); this._arrowMesh.position = this._radarTransform.absolutePosition;
this._arrowMesh.lookAt(point.absolutePosition);
}
}, 100); }, 100);
// arrow[0].parent = this._radarTransform; // arrow[0].parent = this._radarTransform;

View File

@ -34,17 +34,13 @@ export class Scoreboard {
const parent = scene.getMeshById('RightUpperDisplay'); const parent = scene.getMeshById('RightUpperDisplay');
const scoreboard = MeshBuilder.CreatePlane("scoreboard", {width: 1, height: 1}, scene); const scoreboard = MeshBuilder.CreatePlane("scoreboard", {width: 1, height: 1}, scene);
scoreboard.parent =parent; scoreboard.parent =parent;
//DefaultScene.MainScene.onBeforeDrawPhaseObservable.add(() => {
//});
//scoreboard.parent = camera;
scoreboard.position.x = -.76; scoreboard.position.x = -.76;
scoreboard.position.y = 4.19; scoreboard.position.y = 4.19;
scoreboard.position.z = .53; scoreboard.position.z = .53;
scoreboard.rotation.x = Angle.FromDegrees(108).radians(); scoreboard.rotation.x = Angle.FromDegrees(104).radians();
scoreboard.rotation.z = Math.PI; scoreboard.rotation.z = Math.PI;
scoreboard.scaling = new Vector3(.5, .5, .5); scoreboard.scaling = new Vector3(.3, .3, .3);
//scoreboard.position = camera.getFrontPosition(1);
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(scoreboard); const advancedTexture = AdvancedDynamicTexture.CreateForMesh(scoreboard);
advancedTexture.background = "black"; advancedTexture.background = "black";
@ -52,6 +48,9 @@ export class Scoreboard {
advancedTexture.addControl(scoreText); advancedTexture.addControl(scoreText);
const fpsText = this.createText(); const fpsText = this.createText();
fpsText.top = '120px'; fpsText.top = '120px';
const hullText = this.createText();
//hullText.top = '240px';
hullText.text = 'Hull: 100%';
const panel = new StackPanel(); const panel = new StackPanel();
panel.isVertical = true; panel.isVertical = true;
advancedTexture.addControl(fpsText); advancedTexture.addControl(fpsText);

View File

@ -1,15 +1,19 @@
import { import {
AbstractMesh, Color3, AbstractMesh,
DirectionalLight, Engine, Color3,
DirectionalLight,
FreeCamera, GlowLayer, Engine,
Matrix, MeshBuilder, FreeCamera,
GlowLayer,
MeshBuilder,
Observable, Observable,
PhysicsAggregate, PhysicsAggregate,
PhysicsMotionType, PhysicsMotionType,
PhysicsShapeType, PhysicsShapeType,
SceneLoader, Sound, SceneLoader,
SpotLight, StandardMaterial, Sound,
SpotLight,
StandardMaterial,
TransformNode, TransformNode,
Vector2, Vector2,
Vector3, Vector3,
@ -20,7 +24,7 @@ import {
import {DefaultScene} from "./defaultScene"; import {DefaultScene} from "./defaultScene";
import {Radar} from "./radar"; import {Radar} from "./radar";
import {ShipEngine} from "./shipEngine"; import {ShipEngine} from "./shipEngine";
import {Mirror} from "./mirror"; import {Level1} from "./level1";
const controllerComponents = [ const controllerComponents = [
'a-button', 'a-button',
@ -54,7 +58,7 @@ export class Ship {
private _controllerObservable: Observable<ControllerEvent> = new Observable<ControllerEvent>(); private _controllerObservable: Observable<ControllerEvent> = new Observable<ControllerEvent>();
public onReadyObservable: Observable<unknown> = new Observable<unknown>(); public onReadyObservable: Observable<unknown> = new Observable<unknown>();
private _engine: ShipEngine; private _engine: ShipEngine;
private _ammoMaterial: StandardMaterial;
private _forwardNode: TransformNode; private _forwardNode: TransformNode;
private _rotationNode: TransformNode; private _rotationNode: TransformNode;
private _onscore: Observable<number>; private _onscore: Observable<number>;
@ -64,32 +68,53 @@ export class Ship {
private _thrust2: Sound; private _thrust2: Sound;
private _shot: Sound; private _shot: Sound;
private _shooting: boolean = false; private _shooting: boolean = false;
private _camera: FreeCamera;
constructor() { constructor() {
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;
this._thrust = new Sound("thrust", "/thrust.mp3", DefaultScene.MainScene, null, {loop: true, autoplay: false}); this._thrust = new Sound("thrust", "/thrust5.mp3", DefaultScene.MainScene, null, {
this._thrust2 = new Sound("thrust2", "/thrust2.mp3", DefaultScene.MainScene, null, {loop: true, autoplay: false}); loop: true,
autoplay: false
});
this._thrust2 = new Sound("thrust2", "/thrust5.mp3", DefaultScene.MainScene, null, {
loop: true,
autoplay: false,
volume: .5
});
this._shot = new Sound("shot", "/shot.mp3", DefaultScene.MainScene, null, this._shot = new Sound("shot", "/shot.mp3", DefaultScene.MainScene, null,
{loop: false, autoplay: false}); {loop: false, autoplay: false, volume: .5});
this._ammoMaterial = new StandardMaterial("ammoMaterial", DefaultScene.MainScene);
this._ammoMaterial.emissiveColor = new Color3(1, 1, 0);
this.initialize(); this.initialize();
} }
private shoot() { private shoot() {
const ammo = MeshBuilder.CreateCapsule("bullet", { radius: .05, height: 1.5}, DefaultScene.MainScene); this._shot.play();
ammo.parent = this._ship const ammo = MeshBuilder.CreateCapsule("bullet", {radius: .05, height: 1.5}, DefaultScene.MainScene);
ammo.position.y =2; ammo.parent = this._ship
ammo.rotation.x = Math.PI / 2; ammo.position.y = 2;
ammo.setParent(null); ammo.rotation.x = Math.PI / 2;
const ammoAggregate = new PhysicsAggregate(ammo, PhysicsShapeType.CONVEX_HULL, {mass: 1}, DefaultScene.MainScene); ammo.setParent(null);
const material = new StandardMaterial("ammoMaterial", DefaultScene.MainScene); const ammoAggregate = new PhysicsAggregate(ammo, PhysicsShapeType.CONVEX_HULL, {
material.emissiveColor = new Color3(1,1,0); mass: 1000,
ammo.material = material; restitution: 0
ammoAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC); }, DefaultScene.MainScene);
ammoAggregate.body.setLinearVelocity(this._ship.forward.scale(100).add(this._ship.physicsBody.getLinearVelocity()));
this._shot.play();
window.setTimeout(() =>{ ammoAggregate.dispose(); ammo.dispose()}, 5000) 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) { public set position(newPosition: Vector3) {
const body = this._ship.physicsBody; const body = this._ship.physicsBody;
body.disablePreStep = false; body.disablePreStep = false;
@ -103,70 +128,35 @@ export class Ship {
private async initialize() { 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 ship = this._ship;
const landingLight = new SpotLight("landingLight", new Vector3(0,0,0), new Vector3(0, -.5, .5),1.5, .5, DefaultScene.MainScene); const landingLight = new SpotLight("landingLight", new Vector3(0, 0, 0), new Vector3(0, -.5, .5), 1.5, .5, DefaultScene.MainScene);
landingLight.parent = ship; landingLight.parent = ship;
landingLight.position.z = 5; landingLight.position.z = 5;
//const lightCode = MeshBuilder.CreateCylinder("lightCode", {diameterBottom: 0, diameterTop: .5, height: 1}, DefaultScene.MainScene);
//lightCode.parent = ship;
//lightCode.position.z = 5;
//this._engine = new ShipEngine(ship);
//ship.position = new Vector3(0, 0, -1000);
//const landingLight = new DirectionalLight("landingLight", new Vector3(0, -1, 0), DefaultScene.MainScene);
//landingLight.parent = ship;
const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "cockpit3.glb", DefaultScene.MainScene); const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "cockpit3.glb", DefaultScene.MainScene);
const shipMesh = importMesh.meshes[0]; const shipMesh = importMesh.meshes[0];
shipMesh.id = "shipMesh"; shipMesh.id = "shipMesh";
shipMesh.name = "shipMesh"; shipMesh.name = "shipMesh";
shipMesh.parent = ship; shipMesh.parent = ship;
shipMesh.rotation.y = Math.PI; shipMesh.rotation.y = Math.PI;
shipMesh.position.y = 1; shipMesh.position.y = 1;
shipMesh.position.z = -1; shipMesh.position.z = -1;
DefaultScene.MainScene.getMaterialById('glass_mat.002').alpha = .7; DefaultScene.MainScene.getMaterialById('glass_mat.002').alpha = .7;
this._camera = new FreeCamera("Flat Camera",
const camera = new FreeCamera("Flat Camera", new Vector3(0, .5, 0),
new Vector3(0, 0, -10),
DefaultScene.MainScene); DefaultScene.MainScene);
camera.parent = ship; this._camera.parent = ship;
camera.position.y = .5;
camera.position.z = 0;
const agg = new PhysicsAggregate(ship, PhysicsShapeType.BOX, {
//right.attachToMesh(rightTransform);
//camera.rotation.x = -Math.PI / 2;
const body = new PhysicsAggregate(ship, PhysicsShapeType.BOX, {
mass: 100, mass: 100,
extents: new Vector3(5, 2, 5) extents: new Vector3(4, 4, 7.4),
center: new Vector3(0, 1, 1.8)
}, DefaultScene.MainScene); }, DefaultScene.MainScene);
body.body.setMotionType(PhysicsMotionType.DYNAMIC); agg.body.setMotionType(PhysicsMotionType.DYNAMIC);
body.body.setLinearDamping(.1); agg.body.setLinearDamping(.1);
body.body.setAngularDamping(.2); agg.body.setAngularDamping(.2);
body.body.setAngularVelocity(new Vector3(0, 0, 0)); agg.body.setAngularVelocity(new Vector3(0, 0, 0));
body.body.setCollisionCallbackEnabled(true) agg.body.setCollisionCallbackEnabled(true)
//body.shape.filterCollideMask = 1;
/*const sight = MeshBuilder.CreateDisc("sight", {
radius: .1,
sideOrientation: Mesh.DOUBLESIDE
}, DefaultScene.MainScene);
const sightMaterial = new StandardMaterial("sightMaterial", DefaultScene.MainScene);
sightMaterial.ambientColor = new Color3(1, 1, 1);
sightMaterial.alpha = .5;
sight.material = sightMaterial;
sight.parent = ship;
sight.rotation.x = Math.PI;
sight.position.z = 10;
const line = MeshBuilder.CreateLines("line", {points: [Vector3.Zero(), new Vector3(0, 0, 10)]}, DefaultScene.MainScene);
line.parent = ship;
line.material = sightMaterial; */
DefaultScene.MainScene.setActiveCameraByName("Flat Camera"); DefaultScene.MainScene.setActiveCameraByName("Flat Camera");
this.setupKeyboard(); this.setupKeyboard();
this.setupMouse(); this.setupMouse();
this._controllerObservable.add(this.controllerCallback); this._controllerObservable.add(this.controllerCallback);
@ -174,8 +164,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;
//const sightPos = this._forwardNode.position.scale(30);
//const radar = new Radar(this._ship); const sight = MeshBuilder.CreateSphere("sight", {diameter: 1}, DefaultScene.MainScene);
sight.parent = this._ship
const signtMaterial = new StandardMaterial("sightMaterial", DefaultScene.MainScene);
signtMaterial.emissiveColor = Color3.Yellow();
sight.material = signtMaterial;
sight.position = new Vector3(0, 2, 125);
window.setInterval(() => { window.setInterval(() => {
this.applyForce(); this.applyForce();
}, 50); }, 50);
@ -184,20 +179,25 @@ export class Ship {
const radar = new Radar(this._ship); const radar = new Radar(this._ship);
document.querySelector('#loadingDiv').remove(); document.querySelector('#loadingDiv').remove();
const startButton = document.querySelector('#startButton'); //const startButton = document.querySelector('#startButton');
startButton.classList.add('ready'); //startButton.classList.add('ready');
const level = new Level1(this);
const background = new Sound("background", "/background.mp3", DefaultScene.MainScene, () => { const background = new Sound("background", "/background.mp3", DefaultScene.MainScene, () => {
const startButton = document.querySelector('#startButton'); const startButton = document.querySelector('#startButton');
startButton.classList.add('ready'); startButton.classList.add('ready');
startButton.addEventListener('click', () => { startButton.addEventListener('click', async () => {
Engine.audioEngine.unlock(); if (!Engine.audioEngine.unlocked) {
background.play(); Engine.audioEngine.unlock();
DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor'); }
console.log('start background');
await DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
await level.initialize();
}); });
}, {loop: true, autoplay: false, volume: .1}); }, {loop: true, autoplay: true, volume: .2});
} }
private _leftStickVector = Vector2.Zero().clone(); private _leftStickVector = Vector2.Zero().clone();
private _rightStickVector = Vector2.Zero().clone(); private _rightStickVector = Vector2.Zero().clone();
private _forwardValue = 0; private _forwardValue = 0;
@ -292,6 +292,7 @@ export class Ship {
body.setLinearVelocity(this._forwardNode.absolutePosition.subtract(this._ship.absolutePosition).scale(-1)); body.setLinearVelocity(this._forwardNode.absolutePosition.subtract(this._ship.absolutePosition).scale(-1));
//this._engine.forwardback(this._forwardValue); //this._engine.forwardback(this._forwardValue);
} }
private controllerCallback = (controllerEvent: ControllerEvent) => { private controllerCallback = (controllerEvent: ControllerEvent) => {
if (controllerEvent.type == 'thumbstick') { if (controllerEvent.type == 'thumbstick') {
if (controllerEvent.hand == 'left') { if (controllerEvent.hand == 'left') {
@ -318,6 +319,7 @@ export class Ship {
} }
} }
} }
private setupMouse() { private setupMouse() {
this._ship.getScene().onPointerDown = (evt) => { this._ship.getScene().onPointerDown = (evt) => {
this._mousePos.x = evt.x; this._mousePos.x = evt.x;
@ -332,48 +334,62 @@ export class Ship {
}; };
this._ship.getScene().onPointerMove = (ev) => { this._ship.getScene().onPointerMove = (ev) => {
if (!this._mouseDown) {return}; if (!this._mouseDown) {
const xInc = this._rightStickVector.x = (ev.x - this._mousePos.x) / 100; return
const yInc = this._rightStickVector.y = (ev.y - this._mousePos.y) / 100; }
if (Math.abs(xInc) <= 1) { ;
this._rightStickVector.x = xInc; const xInc = this._rightStickVector.x = (ev.x - this._mousePos.x) / 100;
} else { const yInc = this._rightStickVector.y = (ev.y - this._mousePos.y) / 100;
this._rightStickVector.x = Math.sign(xInc); if (Math.abs(xInc) <= 1) {
} this._rightStickVector.x = xInc;
if (Math.abs(yInc) <= 1) { } else {
this._rightStickVector.y = yInc; this._rightStickVector.x = Math.sign(xInc);
} else { }
this._rightStickVector.y = Math.sign(yInc); if (Math.abs(yInc) <= 1) {
} this._rightStickVector.y = yInc;
} else {
this._rightStickVector.y = Math.sign(yInc);
}
}; };
} }
private setupKeyboard() { private setupKeyboard() {
document.onkeyup = () => {
this._leftStickVector.y = 0;
this._leftStickVector.x = 0;
this._rightStickVector.y = 0;
this._rightStickVector.x = 0;
}
document.onkeydown = (ev) => { document.onkeydown = (ev) => {
switch (ev.key) { switch (ev.key) {
case '1':
this._camera.position.x = 15;
this._camera.rotation.y = -Math.PI / 2;
console.log(1);
break;
case ' ': case ' ':
this.shoot(); this.shoot();
break; break;
case 'e': case 'e':
break; break;
case 'w': case 'w':
this._leftStickVector.y =-1; this._leftStickVector.y = -1;
break; break;
case 's': case 's':
this._leftStickVector.y =1; this._leftStickVector.y = 1;
break; break;
case 'a': case 'a':
this._leftStickVector.x =-1; this._leftStickVector.x = -1;
break; break;
case 'd': case 'd':
this._leftStickVector.x =1; this._leftStickVector.x = 1;
break; break;
case 'ArrowUp': case 'ArrowUp':
this._rightStickVector.y = -1;
break; break;
case 'ArrowDown': case 'ArrowDown':
this._rightStickVector.y = 1;
break; break;
} }

View File

@ -1,30 +1,107 @@
import { import {
AbstractMesh, AbstractMesh, Color3, ISceneLoaderAsyncResult, MeshBuilder, ParticleHelper, ParticleSystem, ParticleSystemSet,
PhysicsAggregate, PhysicsAggregate,
PhysicsMotionType, PhysicsMotionType,
PhysicsShapeType, PhysicsShapeType,
SceneLoader, SceneLoader, StandardMaterial,
Vector3 Vector3
} from "@babylonjs/core"; } from "@babylonjs/core";
import {DefaultScene} from "./defaultScene"; import {DefaultScene} from "./defaultScene";
let _particleData: any = null;
export async function createRock(i: number, position: Vector3, size: Vector3): Promise<AbstractMesh> {
const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "asteroid.glb", DefaultScene.MainScene);
const rock = importMesh.meshes[1];
rock.scaling = size; export class RockFactory {
rock.position = position; private static _rockMesh: AbstractMesh;
rock.setParent(null); private static _rockMaterial: StandardMaterial;
importMesh.meshes[0].dispose();
rock.name = "asteroid-" + i; public static async init() {
rock.id = "asteroid-" + i; if (!this._rockMesh) {
const agg = new PhysicsAggregate(rock, PhysicsShapeType.CONVEX_HULL, {mass: 10000}, DefaultScene.MainScene); console.log('loading mesh');
const body =agg.body; const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "asteroid.glb", DefaultScene.MainScene);
body.setLinearDamping(.001); this._rockMesh = importMesh.meshes[1].clone("asteroid", null, true);
body.setAngularDamping(.00001); this._rockMesh.setParent(null);
body.setMotionType(PhysicsMotionType.DYNAMIC); this._rockMesh.setEnabled(false);
body.setCollisionCallbackEnabled(true);
//body.setAngularVelocity(new Vector3(Math.random(), Math.random(), Math.random())); //importMesh.meshes[1].dispose();
// body.setLinearVelocity(Vector3.Random(-10, 10)); console.log(importMesh.meshes);
return rock; if (!this._rockMaterial) {
this._rockMaterial = this._rockMesh.material.clone("asteroid") as StandardMaterial;
this._rockMaterial.name = 'asteroid-material';
this._rockMaterial.id = 'asteroid-material';
importMesh.meshes[1].dispose(false, true);
importMesh.meshes[0].dispose();
}
}
}
public static async createRock(i: number, position: Vector3, size: Vector3): Promise<AbstractMesh> {
const explosion = await ParticleHelper.CreateAsync("explosion", DefaultScene.MainScene);
const rock = this._rockMesh.clone("asteroid-" + i, null, true);
//rock.material.dispose();
//rock.material = rockMaterial;
rock.scaling = size;
rock.position = position;
//rock.setParent(null);
rock.name = "asteroid-" + i;
rock.id = "asteroid-" + i;
rock.metadata = {type: 'asteroid'};
rock.setEnabled(true);
const agg = new PhysicsAggregate(rock, PhysicsShapeType.CONVEX_HULL, {mass: 10000, restitution: .0001}, DefaultScene.MainScene);
const body =agg.body;
body.setLinearDamping(.001);
//body.setAngularDamping(.00001);
body.setMotionType(PhysicsMotionType.DYNAMIC);
body.setCollisionCallbackEnabled(true);
//rock.renderOutline = true;
//rock.outlineColor = Color3.Red();
//rock.outlineWidth = .02;
//rock.showBoundingBox = true;
//rock.renderOverlay = true;
body.getCollisionObservable().add((eventData) => {
if (eventData.type == 'COLLISION_STARTED') {
if ( eventData.collidedAgainst.transformNode.id == 'bullet') {
const position = eventData.point;
// _explosion.emitterNode = position;
eventData.collider.shape.dispose();
eventData.collider.transformNode.dispose();
eventData.collider.dispose();
eventData.collidedAgainst.shape.dispose();
eventData.collidedAgainst.transformNode.dispose();
eventData.collidedAgainst.dispose();
const ball = MeshBuilder.CreateBox("ball", {size: .01}, DefaultScene.MainScene);
ball.scaling = new Vector3(.1, .1, .1);
ball.position = position;
const material = new StandardMaterial("ball-material", DefaultScene.MainScene);
material.emissiveColor = Color3.Yellow();
ball.material = material;
explosion.start(ball);
setTimeout(() => {
explosion.systems.forEach((system: ParticleSystem) => {
system.stop();
system.dispose(true, true, true);
});
explosion.dispose();
if (ball && !ball.isDisposed()) {
ball.dispose(false, true);
}
//ball.dispose();
}, 2000);
}
}
});
//body.setAngularVelocity(new Vector3(Math.random(), Math.random(), Math.random()));
// body.setLinearVelocity(Vector3.Random(-10, 10));
return rock;
}
} }