draw busses
This commit is contained in:
@@ -19,6 +19,13 @@ export class RouteManager {
|
|||||||
|
|
||||||
this.onRouteChanged = null;
|
this.onRouteChanged = null;
|
||||||
this.gameManager = null;
|
this.gameManager = null;
|
||||||
|
|
||||||
|
this.vehicleSystem = null;
|
||||||
|
this.latestPathPoints = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
setVehicleSystem(vs) {
|
||||||
|
this.vehicleSystem = vs;
|
||||||
}
|
}
|
||||||
|
|
||||||
setGameManager(gm) {
|
setGameManager(gm) {
|
||||||
@@ -127,6 +134,11 @@ export class RouteManager {
|
|||||||
// 2. Pay
|
// 2. Pay
|
||||||
this.gameManager.deductFunds(cost);
|
this.gameManager.deductFunds(cost);
|
||||||
|
|
||||||
|
// Spawn bus
|
||||||
|
if (this.vehicleSystem && this.latestPathPoints.length > 0) {
|
||||||
|
this.vehicleSystem.addBusToRoute(this.latestPathPoints);
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Freeze & Save
|
// 3. Freeze & Save
|
||||||
this.currentPathMesh.material.color.setHex(0x10B981);
|
this.currentPathMesh.material.color.setHex(0x10B981);
|
||||||
|
|
||||||
@@ -222,6 +234,8 @@ export class RouteManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.latestPathPoints = fullPathPoints;
|
||||||
|
|
||||||
// Rebuild Mesh
|
// Rebuild Mesh
|
||||||
if (this.currentPathMesh) {
|
if (this.currentPathMesh) {
|
||||||
this.scene.remove(this.currentPathMesh);
|
this.scene.remove(this.currentPathMesh);
|
||||||
|
|||||||
89
src/VehicleSystem.js
Normal file
89
src/VehicleSystem.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import * as THREE from 'three';
|
||||||
|
|
||||||
|
export class VehicleSystem {
|
||||||
|
constructor(scene) {
|
||||||
|
this.scene = scene;
|
||||||
|
this.buses = []; // { mesh, points, dists, totalLen, currentDist, speed, direction }
|
||||||
|
|
||||||
|
this.busGeom = new THREE.BoxGeometry(3.5, 4.0, 10.0);
|
||||||
|
this.busGeom.translate(0, 3.5, 0);
|
||||||
|
|
||||||
|
this.busMat = new THREE.MeshStandardMaterial({
|
||||||
|
color: 0xF59E0B, // Amber body
|
||||||
|
emissive: 0xB45309, // Slight orange glow so they don't get lost in shadow
|
||||||
|
emissiveIntensity: 0.4,
|
||||||
|
roughness: 0.2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addBusToRoute(routePathPoints) {
|
||||||
|
if (!routePathPoints || routePathPoints.length < 2) return;
|
||||||
|
|
||||||
|
// Clone points to ensure they aren't affected by outside changes
|
||||||
|
const points = routePathPoints.map(p => p.clone());
|
||||||
|
|
||||||
|
const mesh = new THREE.Mesh(this.busGeom, this.busMat);
|
||||||
|
mesh.position.copy(points[0]);
|
||||||
|
mesh.castShadow = true;
|
||||||
|
this.scene.add(mesh);
|
||||||
|
|
||||||
|
// Pre-calculate cumulative distances for smooth interpolation
|
||||||
|
let totalLen = 0;
|
||||||
|
const dists = [0];
|
||||||
|
for (let i = 0; i < points.length - 1; i++) {
|
||||||
|
const d = points[i].distanceTo(points[i + 1]);
|
||||||
|
totalLen += d;
|
||||||
|
dists.push(totalLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buses.push({
|
||||||
|
mesh: mesh,
|
||||||
|
points: points,
|
||||||
|
dists: dists,
|
||||||
|
totalLen: totalLen,
|
||||||
|
currentDist: 0,
|
||||||
|
speed: 40, // Speed in units/sec
|
||||||
|
direction: 1 // 1 = Forward, -1 = Backward
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(deltaTime) {
|
||||||
|
this.buses.forEach(bus => {
|
||||||
|
// 1. Move
|
||||||
|
bus.currentDist += bus.speed * deltaTime * bus.direction;
|
||||||
|
|
||||||
|
// 2. Check Bounds & Reversal
|
||||||
|
if (bus.currentDist >= bus.totalLen) {
|
||||||
|
bus.currentDist = bus.totalLen;
|
||||||
|
bus.direction = -1;
|
||||||
|
} else if (bus.currentDist <= 0) {
|
||||||
|
bus.currentDist = 0;
|
||||||
|
bus.direction = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Find current segment index
|
||||||
|
let i = 0;
|
||||||
|
// Simple linear search (efficient enough for small N points)
|
||||||
|
while (i < bus.dists.length - 2 && bus.currentDist > bus.dists[i + 1]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Interpolate Position
|
||||||
|
const startDist = bus.dists[i];
|
||||||
|
const endDist = bus.dists[i + 1];
|
||||||
|
const segmentLen = endDist - startDist;
|
||||||
|
|
||||||
|
// Avoid divide by zero if 2 points are identical
|
||||||
|
const alpha = segmentLen > 0.0001 ? (bus.currentDist - startDist) / segmentLen : 0;
|
||||||
|
|
||||||
|
const pStart = bus.points[i];
|
||||||
|
const pEnd = bus.points[i + 1];
|
||||||
|
|
||||||
|
bus.mesh.position.lerpVectors(pStart, pEnd, alpha);
|
||||||
|
|
||||||
|
// 5. Rotation (Look at target)
|
||||||
|
const lookTarget = bus.direction === 1 ? pEnd : pStart;
|
||||||
|
bus.mesh.lookAt(lookTarget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/main.js
17
src/main.js
@@ -6,7 +6,7 @@ import { InputManager } from './InputManager.js';
|
|||||||
import { RouteManager } from './RouteManager.js';
|
import { RouteManager } from './RouteManager.js';
|
||||||
import { UIManager } from './UIManager.js';
|
import { UIManager } from './UIManager.js';
|
||||||
import { GameManager } from './GameManager.js';
|
import { GameManager } from './GameManager.js';
|
||||||
|
import { VehicleSystem } from './VehicleSystem.js';
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 1. Configuration
|
// 1. Configuration
|
||||||
@@ -32,7 +32,9 @@ const SETTINGS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let scene, camera, renderer, controls;
|
let scene, camera, renderer, controls;
|
||||||
let inputManager, routeManager, uiManager, gameManager;
|
let inputManager, routeManager, uiManager, gameManager, vehicleSystem;
|
||||||
|
|
||||||
|
const clock = new THREE.Clock(); // Added Clock
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
setupScene();
|
setupScene();
|
||||||
@@ -45,6 +47,11 @@ function init() {
|
|||||||
gameManager = new GameManager(routeManager, uiManager);
|
gameManager = new GameManager(routeManager, uiManager);
|
||||||
routeManager.setGameManager(gameManager); // Dependency Injection
|
routeManager.setGameManager(gameManager); // Dependency Injection
|
||||||
|
|
||||||
|
// Vehicle System
|
||||||
|
vehicleSystem = new VehicleSystem(scene);
|
||||||
|
routeManager.setVehicleSystem(vehicleSystem); // Inject into RouteManager
|
||||||
|
|
||||||
|
|
||||||
gameManager.start(); // Start the loop
|
gameManager.start(); // Start the loop
|
||||||
|
|
||||||
// 3. Input
|
// 3. Input
|
||||||
@@ -268,7 +275,13 @@ function createBuildingLayer(buildings) {
|
|||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
|
const delta = clock.getDelta(); // Get time since last frame
|
||||||
|
|
||||||
controls.update();
|
controls.update();
|
||||||
|
if (vehicleSystem) {
|
||||||
|
vehicleSystem.update(delta);
|
||||||
|
}
|
||||||
|
|
||||||
renderer.render(scene, camera);
|
renderer.render(scene, camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user