import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { Bee } from './Bee.js'; import { Waypoint } from './Waypoint.js'; export class Hive { static collection = []; constructor(scene) { this.scene = scene; this.position = new THREE.Vector3(); this.rotation = new THREE.Vector3(); this.model = null; this.honeyReserve = 0; this.beeSlots = 10; this.queenSlots = 1; this.entranceWaypoint = null; this.billboard = null; this.yWobble = 0; this.swarm; } static loadModel() { return new Promise((resolve, reject) => { var gltfloader = new GLTFLoader(); return gltfloader.load( './beehive/scene.gltf', function (gltf) { resolve(gltf); }, function (xhr) { }, function (error) { reject(error); } ); }); } async load(model) { this.model = model.scene.clone() ?? await Hive.loadModel().scene; this.billboardCanvas = document.createElement('canvas'); this.billboardCanvas.width = 500; this.billboardCanvas.height = 300; this.billboardContext = this.billboardCanvas.getContext('2d'); this.billboardTexture = new THREE.CanvasTexture(this.billboardCanvas); this.billboard = new THREE.Sprite(new THREE.SpriteMaterial({ map: this.billboardTexture })); } init(i) { this.model.scale.set(50, 50, 50); this.model.traverse(function (node) { if (node.isMesh) { node.castShadow = true; node.receiveShadow = true; } }); this.position.x = (70 * i) - 70; this.position.z = Math.abs((20 * i) - 20); this.rotation.y = ((Math.PI / 4)) - ((Math.PI / 4) * i); this.entranceWaypoint = Waypoint.addNewHive(this.scene, this); this.billboard.position.set(this.position.x, this.position.y + 100, this.position.z); this.billboard.scale.set(this.billboardCanvas.width / 10, this.billboardCanvas.height / 10, 1); } addToScene(scene) { scene.add(this.model); } update(delta, timer) { this.model.position.set(this.position.x, this.position.y, this.position.z); this.model.rotation.set(this.rotation.x, this.rotation.y, this.rotation.z); this.yWobble = Math.cos(timer * 0.008) * 4; this.billboardContext.clearRect(0, 0, this.billboardCanvas.width, this.billboardCanvas.height); this.canvasDraw(this.billboardContext); this.billboardTexture.needsUpdate = true; } canvasDraw(context) { context.fillStyle = "#EB9605"; context.beginPath(); context.moveTo(40, this.yWobble + 72); context.bezierCurveTo(40, this.yWobble + 72, 70, this.yWobble + 72, 40, this.yWobble + 20); context.bezierCurveTo(40, this.yWobble + 20, 10, this.yWobble + 72, 40, this.yWobble + 72); context.fill(); context.beginPath(); context.arc(40, this.yWobble + 124, 20, 0, 2 * Math.PI); context.fill(); context.fillStyle = "white"; context.font = "72px Arial"; context.textAlign = "left"; context.fillText(`Honey ${this.honeyReserve}`, 72, 72); context.fillStyle = "white"; context.font = "72px Arial"; context.textAlign = "left"; context.fillText(`Bees ${10 - this.beeSlots}`, 72, 144); } visitFromBee(bee) { this.honeyReserve += bee.carryingHoney; bee.carryingHoney = 0; //let randomFlower = Flower.collection[Math.floor(Flower.collection.length * Math.random())]; //bee.setTarget(randomFlower); bee.setTarget(this.entranceWaypoint); this.spawnBee(); } spawnBee() { if (this.honeyReserve > 15 && this.beeSlots > 0) { this.honeyReserve -= 15; this.beeSlots--; let newBee = new Bee(); newBee.model = Bee.baseModel.clone(); newBee.model.material = newBee.model.material.clone(); newBee.init(); newBee.setSwarm(this.swarm); newBee.setHive(this); newBee.setPosition(this.position.x, this.position.y, this.position.z); newBee.setLastPosition(this.position.x, this.position.y, this.position.z); // newBee.setTarget(Flower.collection[0]); newBee.setTarget(this.entranceWaypoint); newBee.addToScene(this.scene); Bee.collection.push(newBee); } if (this.honeyReserve > 200 && this.queenSlots > 0) { this.honeyReserve -= 200; this.queenSlots--; let newBee = new Bee(); newBee.model = Bee.baseModel.clone(); newBee.model.material = newBee.model.material.clone(); newBee.init(); let claimedHives = Bee.collection.map(bee => bee.homeHive); let nextHive = Hive.collection.filter(hive => !claimedHives.includes(hive))[0]; if (!nextHive) { return; } newBee.setSwarm(this.swarm); newBee.setHive(nextHive); newBee.setPosition(this.position.x, this.position.y, this.position.z); newBee.setLastPosition(nextHive.position.x, nextHive.position.y, nextHive.position.z); newBee.setTarget(nextHive); newBee.addToScene(this.scene); Bee.collection.push(newBee); } } toggleFlower(flower) { if (!this.entranceWaypoint.contains(flower)) { this.entranceWaypoint.addLink(flower); this.entranceWaypoint.addLine(flower); } else { this.entranceWaypoint.removeLink(flower); this.entranceWaypoint.removeLine(flower); } } setSwarm(id) { this.swarm = id; } }