123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
- import {math} from './math.js';
- import {FBXLoader} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/FBXLoader.js';
- export const world = (() => {
- const START_POS = 100;
- const SEPARATION_DISTANCE = 20;
- class WorldObject {
- constructor(params) {
- this.position = new THREE.Vector3();
- this.quaternion = new THREE.Quaternion();
- this.scale = 1.0;
- this.collider = new THREE.Box3();
- this.params_ = params;
- this.LoadModel_();
- }
- LoadModel_() {
- const texLoader = new THREE.TextureLoader();
- const texture = texLoader.load('./resources/DesertPack/Blend/Textures/Ground.png');
- texture.encoding = THREE.sRGBEncoding;
- const loader = new FBXLoader();
- loader.setPath('./resources/DesertPack/FBX/');
- loader.load('Cactus3.fbx', (fbx) => {
- fbx.scale.setScalar(0.01);
- this.mesh = fbx;
- this.params_.scene.add(this.mesh);
- fbx.traverse(c => {
- if (c.geometry) {
- c.geometry.computeBoundingBox();
- }
- let materials = c.material;
- if (!(c.material instanceof Array)) {
- materials = [c.material];
- }
-
- for (let m of materials) {
- if (m) {
- if (texture) {
- m.map = texture;
- }
- m.specular = new THREE.Color(0x000000);
- }
- }
- c.castShadow = true;
- c.receiveShadow = true;
- });
- });
- }
- UpdateCollider_() {
- this.collider.setFromObject(this.mesh);
- }
- Update(timeElapsed) {
- if (!this.mesh) {
- return;
- }
- this.mesh.position.copy(this.position);
- this.mesh.quaternion.copy(this.quaternion);
- this.mesh.scale.setScalar(this.scale);
- this.UpdateCollider_();
- }
- }
- class WorldManager {
- constructor(params) {
- this.objects_ = [];
- this.unused_ = [];
- this.speed_ = 12;
- this.params_ = params;
- this.score_ = 0.0;
- this.scoreText_ = '00000';
- this.separationDistance_ = SEPARATION_DISTANCE;
- }
- GetColliders() {
- return this.objects_;
- }
- LastObjectPosition_() {
- if (this.objects_.length == 0) {
- return SEPARATION_DISTANCE;
- }
- return this.objects_[this.objects_.length - 1].position.x;
- }
- SpawnObj_(scale, offset) {
- let obj = null;
- if (this.unused_.length > 0) {
- obj = this.unused_.pop();
- obj.mesh.visible = true;
- } else {
- obj = new WorldObject(this.params_);
- }
- obj.quaternion.setFromAxisAngle(
- new THREE.Vector3(0, 1, 0), Math.random() * Math.PI * 2.0);
- obj.position.x = START_POS + offset;
- obj.scale = scale * 0.01;
- this.objects_.push(obj);
- }
- SpawnCluster_() {
- const scaleIndex = math.rand_int(0, 1);
- const scales = [1, 0.5];
- const ranges = [2, 3];
- const scale = scales[scaleIndex];
- const numObjects = math.rand_int(1, ranges[scaleIndex]);
- for (let i = 0; i < numObjects; ++i) {
- const offset = i * 1 * scale;
- this.SpawnObj_(scale, offset);
- }
- }
- MaybeSpawn_() {
- const closest = this.LastObjectPosition_();
- if (Math.abs(START_POS - closest) > this.separationDistance_) {
- this.SpawnCluster_();
- this.separationDistance_ = math.rand_range(SEPARATION_DISTANCE, SEPARATION_DISTANCE * 1.5);
- }
- }
- Update(timeElapsed) {
- this.MaybeSpawn_();
- this.UpdateColliders_(timeElapsed);
- this.UpdateScore_(timeElapsed);
- }
- UpdateScore_(timeElapsed) {
- this.score_ += timeElapsed * 10.0;
- const scoreText = Math.round(this.score_).toLocaleString(
- 'en-US', {minimumIntegerDigits: 5, useGrouping: false});
- if (scoreText == this.scoreText_) {
- return;
- }
- document.getElementById('score-text').innerText = scoreText;
- }
- UpdateColliders_(timeElapsed) {
- const invisible = [];
- const visible = [];
- for (let obj of this.objects_) {
- obj.position.x -= timeElapsed * this.speed_;
- if (obj.position.x < -20) {
- invisible.push(obj);
- obj.mesh.visible = false;
- } else {
- visible.push(obj);
- }
- obj.Update(timeElapsed);
- }
- this.objects_ = visible;
- this.unused_.push(...invisible);
- }
- };
- return {
- WorldManager: WorldManager,
- };
- })();
|