diff --git a/public/asteroid4.glb b/public/asteroid4.glb new file mode 100644 index 0000000..2155570 Binary files /dev/null and b/public/asteroid4.glb differ diff --git a/public/base.glb b/public/base.glb index 5d2d2df..a3df2df 100644 Binary files a/public/base.glb and b/public/base.glb differ diff --git a/src/level1.ts b/src/level1.ts index 1ce2e7b..8901360 100644 --- a/src/level1.ts +++ b/src/level1.ts @@ -1,20 +1,18 @@ import {DefaultScene} from "./defaultScene"; +import type {AudioEngineV2} from "@babylonjs/core"; import { AbstractMesh, - Color3, DistanceConstraint, Engine, InstancedMesh, LinesMesh, Mesh, + Color3, + DistanceConstraint, MeshBuilder, Observable, - ParticleHelper, PhysicsAggregate, PhysicsMotionType, - PhysicsShapeType, PointsCloudSystem, - StandardMaterial, TransformNode, + PhysicsShapeType, + StandardMaterial, Vector3 } from "@babylonjs/core"; -import type {AudioEngineV2} from "@babylonjs/core"; import {Ship} from "./ship"; - -import {RockFactory} from "./rockFactory"; import Level from "./level"; import {Scoreboard} from "./scoreboard"; import setLoadingMessage from "./setLoadingMessage"; @@ -55,12 +53,7 @@ export class Level1 implements Level { this._ship.addController(controller); }); }); - - - //console.log('Controller observable registered, observer:', !!observer); - this.initialize(); - } getReadyObservable(): Observable { @@ -94,6 +87,7 @@ export class Level1 implements Level { }); }, 2000); } + public dispose() { this._startBase.dispose(); this._endBase.dispose(); @@ -101,6 +95,7 @@ export class Level1 implements Level { this._backgroundStars.dispose(); } } + public async initialize() { debugLog('Initializing level from config:', this._levelConfig.difficulty); if (this._initialized) { @@ -133,6 +128,7 @@ export class Level1 implements Level { // Calculate distance from start base const dist = Vector3.Distance(asteroidMesh.position, this._startBase.position); const constraint = new DistanceConstraint(dist, DefaultScene.MainScene); + // constraint.isCollisionsEnabled = true; this._startBase.physicsBody.addConstraint(asteroidMesh.physicsBody, constraint); } } @@ -155,6 +151,7 @@ export class Level1 implements Level { } }); + this._initialized = true; // Notify that initialization is complete diff --git a/src/levelDeserializer.ts b/src/levelDeserializer.ts index d3b3d73..172c601 100644 --- a/src/levelDeserializer.ts +++ b/src/levelDeserializer.ts @@ -1,6 +1,6 @@ import { AbstractMesh, - Color3, + Color3, DirectionalLight, GlowLayer, MeshBuilder, Observable, @@ -66,6 +66,10 @@ export class LevelDeserializer { const planets = this.createPlanets(); const asteroids = await this.createAsteroids(scoreObservable); + const dir = new Vector3(-1,-2,-1) + const light = new DirectionalLight("dirLight", dir, DefaultScene.MainScene); + const light2 = new DirectionalLight("dirLight2", dir.negate(), DefaultScene.MainScene); + light2.intensity = .5; return { startBase, sun, diff --git a/src/levelGenerator.ts b/src/levelGenerator.ts index a6bf065..8138dc3 100644 --- a/src/levelGenerator.ts +++ b/src/levelGenerator.ts @@ -214,29 +214,29 @@ export class LevelGenerator { case 'recruit': return { rockCount: 5, - forceMultiplier: .5, + forceMultiplier: .8, rockSizeMin: 10, rockSizeMax: 15, - distanceMin: 80, - distanceMax: 100 + distanceMin: 220, + distanceMax: 250 }; case 'pilot': return { rockCount: 10, forceMultiplier: 1, rockSizeMin: 8, - rockSizeMax: 12, - distanceMin: 80, - distanceMax: 150 + rockSizeMax: 20, + distanceMin: 225, + distanceMax: 300 }; case 'captain': return { rockCount: 20, forceMultiplier: 1.2, - rockSizeMin: 2, - rockSizeMax: 7, - distanceMin: 100, - distanceMax: 250 + rockSizeMin: 5, + rockSizeMax: 40, + distanceMin: 230, + distanceMax: 450 }; case 'commander': return { diff --git a/src/main.ts b/src/main.ts index 80860ae..4c228a3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { CreateAudioEngineAsync, DirectionalLight, Engine, - HavokPlugin, + HavokPlugin, HemisphericLight, ParticleHelper, Scene, ScenePerformancePriority, @@ -255,7 +255,12 @@ export class Main { const havok = await HavokPhysics(); const havokPlugin = new HavokPlugin(true, havok); //DefaultScene.MainScene.ambientColor = new Color3(.1, .1, .1); - const light = new DirectionalLight("dirLight", new Vector3(-1, -2, -1), DefaultScene.MainScene); + + //const light = new HemisphericLight("mainlight", new Vector3(-1, -1, 0), DefaultScene.MainScene); + //light.diffuse = new Color3(.4, .4, .3); + //light.groundColor = new Color3(.2, .2, .1); + //light.intensity = .5; + //light.specular = new Color3(0,0,0); DefaultScene.MainScene.enablePhysics(new Vector3(0, 0, 0), havokPlugin); DefaultScene.MainScene.getPhysicsEngine().setTimeStep(1/60); DefaultScene.MainScene.getPhysicsEngine().setSubTimeStep(5); diff --git a/src/rockFactory.ts b/src/rockFactory.ts index 0697438..10d2eea 100644 --- a/src/rockFactory.ts +++ b/src/rockFactory.ts @@ -52,7 +52,7 @@ export class RockFactory { } private static async loadMesh() { debugLog('loading mesh'); - const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "asteroid3.glb", DefaultScene.MainScene); + const importMesh = await SceneLoader.ImportMeshAsync(null, "./", "asteroid4.glb", DefaultScene.MainScene); this._rockMesh = importMesh.meshes[1].clone("asteroid", null, false); this._rockMesh.setParent(null); this._rockMesh.setEnabled(false); @@ -62,16 +62,17 @@ export class RockFactory { if (!this._rockMaterial) { // Clone the original material from GLB to preserve all textures this._originalMaterial = this._rockMesh.material.clone("asteroid-original") as PBRMaterial; + this._rockMaterial = this._rockMesh.material.clone("asteroid-original") as PBRMaterial; debugLog('Cloned original material from GLB:', this._originalMaterial); // Create material using GameConfig texture level - const config = GameConfig.getInstance(); + /*const config = GameConfig.getInstance(); this._rockMaterial = MaterialFactory.createAsteroidMaterial( 'asteroid-material', config.asteroidTextureLevel, DefaultScene.MainScene, this._originalMaterial - ) as PBRMaterial; + ) as PBRMaterial;*/ this._rockMaterial.freeze(); this._rockMesh.material = this._rockMaterial; @@ -113,12 +114,13 @@ export class RockFactory { body.setLinearDamping(0) body.setMotionType(PhysicsMotionType.DYNAMIC); body.setCollisionCallbackEnabled(true); + body.getCollisionObservable().add((eventData) => { if (eventData.type == 'COLLISION_STARTED') { - debugLog('[RockFactory] Collision detected:', { + /*debugLog('[RockFactory] Collision detected:', { collidedWith: eventData.collidedAgainst.transformNode.id, asteroidName: eventData.collider.transformNode.name - }); + });*/ if ( eventData.collidedAgainst.transformNode.id == 'ammo') { debugLog('[RockFactory] ASTEROID HIT! Triggering explosion...'); @@ -147,8 +149,15 @@ export class RockFactory { eventData.collidedAgainst.dispose(); debugLog('[RockFactory] Disposal complete'); } + } else { + /*debugLog('[RockFactory] Collision ended between:', { + collider: eventData.collider.transformNode.id, + collidedWith: eventData.collidedAgainst.transformNode.id + });*/ } + }); + //body.setAngularVelocity(new Vector3(Math.random(), Math.random(), Math.random())); // body.setLinearVelocity(Vector3.Random(-10, 10)); } diff --git a/src/scoreboard.ts b/src/scoreboard.ts index b91c373..506def4 100644 --- a/src/scoreboard.ts +++ b/src/scoreboard.ts @@ -82,8 +82,8 @@ export class Scoreboard { scoreText.text = `Score: ${this.calculateScore()}`; remainingText.text = `Remaining: ${this._remaining}`; const elapsed = Date.now() - this._startTime; - if (this._active && i++%40 == 0) { - timeRemainingText.text = `Time: ${Math.floor(elapsed/60).toString().padStart(2,"0")}:${(elapsed%60).toString().padStart(2,"0")}`; + if (this._active && i++%30 == 0) { + timeRemainingText.text = `Time: ${Math.floor(elapsed/60000).toString().padStart(2,"0")}:${(Math.floor(elapsed/1000)%60).toString().padStart(2,"0")}`; fpsText.text = `FPS: ${Math.floor(scene.getEngine().getFps())}`; } }); diff --git a/src/ship.ts b/src/ship.ts index 64d6a5c..89be482 100644 --- a/src/ship.ts +++ b/src/ship.ts @@ -231,16 +231,16 @@ export class Ship { //shipMesh.position.y = 1; shipMesh.position.z = -1; // shipMesh.renderingGroupId = 3; - const light = new PointLight("ship.light", new Vector3(0, .5, .1), DefaultScene.MainScene); - light.intensity = 4; - light.includedOnlyMeshes = [shipMesh]; + //const light = new PointLight("ship.light", new Vector3(0, .5, .1), DefaultScene.MainScene); + //light.intensity = 4; + /*light.includedOnlyMeshes = [shipMesh]; for (const mesh of shipMesh.getChildMeshes()) { // mesh.renderingGroupId = 3; if (mesh.material.id.indexOf('glass') === -1) { light.includedOnlyMeshes.push(mesh); } } - light.parent = this._ship; + light.parent = this._ship;*/ //DefaultScene.MainScene.getMaterialById('glass_mat.002').alpha = .4; } diff --git a/src/starBase.ts b/src/starBase.ts index 92c934a..5c5172e 100644 --- a/src/starBase.ts +++ b/src/starBase.ts @@ -1,14 +1,12 @@ import { - AbstractMesh, + AbstractMesh, LoadAssetContainerAsync, Mesh, PhysicsAggregate, PhysicsMotionType, - PhysicsShapeType, - SceneLoader, + PhysicsShapeType, Scene, Vector3 } from "@babylonjs/core"; import {DefaultScene} from "./defaultScene"; import {GameConfig} from "./gameConfig"; -import {debug} from "openai/core"; import debugLog from "./debug"; /** @@ -20,21 +18,33 @@ export default async function buildStarBase(position: Vector3): Promise { + debugLog('collidedBody', collidedBody); + }) } - - return baseMesh; + importMesh.rootNodes[0].dispose(); + return starBase; } \ No newline at end of file