game scenarios
This commit is contained in:
@@ -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}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user