game scenarios

This commit is contained in:
2025-03-14 19:13:52 +02:00
parent 96869a62e4
commit 6aad752ce3
13 changed files with 396 additions and 127 deletions
+111
View File
@@ -0,0 +1,111 @@
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { OrbitControls } from 'three/examples/jsm/Addons.js';
import { MapControls } from 'three/addons/controls/MapControls.js';
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js';
class GameEngine {
async init(domNode) {
const width = 1200, height = 800;
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10000);
camera.position.set(1, 0, 1);
const scene = new THREE.Scene();
// this.light = new THREE.AmbientLight( 0x404040, 0 ); // soft white light
// scene.add( this.light );
function animate(time) {
let delta = clock.getDelta();
mixer.update(delta);
renderer.render(scene, camera);
controls.update();
}
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
preserveDrawingBuffer: true
});
renderer.setPixelRatio( window.devicePixelRatio );
// renderer.toneMapping = THREE.CineonToneMapping;
// renderer.toneMappingExposure = 1.2;
// renderer.shadowMap.enabled = true;
// renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
renderer.outputEncoding = THREE.sRGBEncoding;
const controls = new OrbitControls( camera, renderer.domElement );
//controls.enableZoom = true;
//const controls = new MapControls( camera, renderer.domElement );
this.transformControls = new TransformControls( camera, renderer.domElement );
this.transformControls.addEventListener( 'dragging-changed', function ( event ) {
controls.enabled = ! event.value;
} );
// controls.enableDamping = true;
// controls.screenSpacePanning = true;
renderer.setSize(width, height);
renderer.setAnimationLoop(animate);
const mixer = new THREE.AnimationMixer(this.scene);
const clock = new THREE.Clock();
this.clock = clock;
this.renderer = renderer;
this.scene = scene;
this.loader = new GLTFLoader();
this.camera = camera;
this.controls = controls;
this.mixer = mixer;
domNode.appendChild(renderer.domElement);
let texture = await this.loadTexture('/static/textures/bck.webp');
let bck = await this.loadTexture('/static/textures/bck.webp');
bck.premultiplyAlpha = true;
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = bck; //new THREE.Color(0.7,0.7,0.7);
scene.environment = texture;
console.log('GameEngine started')
renderer.domElement.addEventListener('wheel', (event)=>{
camera.zoom -= event.deltaY / 1000;
camera.zoom = Math.max(camera.zoom, .4);
controls.rotateSpeed = 1 / camera.zoom;
camera.updateProjectionMatrix();
})
}
$ = THREE;
async load(url, progress){
return new Promise((resolve, reject)=>{
this.loader.load(url, resolve, progress, reject)
})
}
async loadTexture(url, progress){
return new Promise((resolve, reject)=>{
new THREE.TextureLoader().load(url, texture=>{
//texture.encoding = THREE.sRGBEncoding;
texture.colorSpace = THREE.SRGBColorSpace;
resolve(texture)
}, progress, reject)
})
}
async captureScreenshot(type = 'image/webp', quality = 80){
return new Promise((resolve, reject)=>{
this.renderer.domElement.toBlob(resolve, type, quality)
})
}
playAnimation(object, clip, play = true){
let action = this.mixer.clipAction(clip, object);
if (play) action.play();
else action.stop();
}
stop(){
this.renderer.setAnimationLoop(null);
}
}
export {GameEngine}
+57
View File
@@ -0,0 +1,57 @@
const epsilon = 0.1;
export default {
blobToBase64: blob => {
const reader = new FileReader();
reader.readAsDataURL(blob);
return new Promise(resolve => {
reader.onloadend = () => {
resolve(reader.result);
};
});
},
adjustMinMax(r){
return {
x1: Math.min(r.x1, r.x2), x2: Math.max(r.x1, r.x2),
y1: Math.min(r.y1, r.y2), y2: Math.max(r.y1, r.y2)
}
},
intersectPointRect(p, r){
//r = this.adjustMinMax(r);
return p[0] >= r.x1 && p[0] <= r.x2 && p[1] >= r.y1 && p[1] <= r.y2;
},
intersectPointLine(p, l){
//l = this.adjustMinMax(l);
let dx = l.x2 - l.x1, dy = l.y2 - l.y1;
let c = dy / dx;
return this.intersectPointRect(p, l) && c * p[0] - p[1] <= epsilon
},
intersectLineRect(l, r){
return this.intersectPointRect([l.x1, l.y1], r) ||
this.intersectPointRect([l.x2, l.y2], r);
},
intersectRectRect(r1, r2){
return this.intersectPointRect([r1.x1, r1.y1], r2) ||
this.intersectPointRect([r1.x1, r1.y2], r2) ||
this.intersectPointRect([r1.x2, r1.y1], r2) ||
this.intersectPointRect([r1.x2, r1.y2], r2);
},
round(n, p = 2){
let pp = Math.pow(10, p);
return Math.round(n*pp)/pp;
},
deg2rad(deg){
return deg * (Math.PI / 180);
},
rad2deg(rad){
return rad * 180 / Math.PI;
}
}