mini games
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 276 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 362 KiB |
@@ -53,6 +53,9 @@
|
|||||||
|
|
||||||
import { GameEngine } from '@/lib/GameEngine';
|
import { GameEngine } from '@/lib/GameEngine';
|
||||||
import { Hero } from '@/lib/Hero';
|
import { Hero } from '@/lib/Hero';
|
||||||
|
import { Game1 } from '@/lib/mini-games/Game1';
|
||||||
|
import { Game2 } from '@/lib/mini-games/Game2';
|
||||||
|
import { Game4 } from '@/lib/mini-games/Game4';
|
||||||
import { useAppStore } from '@/stores/app';
|
import { useAppStore } from '@/stores/app';
|
||||||
|
|
||||||
const store = useAppStore();
|
const store = useAppStore();
|
||||||
@@ -181,6 +184,18 @@ export default {
|
|||||||
// gameEngine.camera.rotation.copy(l.camera.position)
|
// gameEngine.camera.rotation.copy(l.camera.position)
|
||||||
// gameEngine.camera.scale.copy(l.camera.position)
|
// gameEngine.camera.scale.copy(l.camera.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let testGame1 = new Game1(gameEngine, '/static/textures/game1-test.jpg', 2, 3);
|
||||||
|
// gameEngine.activeObjects.add(testGame1.game);
|
||||||
|
// testGame1.game.position.set(0, 1, -5);
|
||||||
|
|
||||||
|
// let testGame2 = new Game2(gameEngine, '/static/textures/game2-test.jpg', 3, 3);
|
||||||
|
// gameEngine.activeObjects.add(testGame2.game);
|
||||||
|
// testGame2.game.position.set(0, 1, 5);
|
||||||
|
|
||||||
|
// let testGame4 = new Game4(gameEngine, '/static/feathers-game.glb', 3, 4);
|
||||||
|
// gameEngine.activeObjects.add(testGame4.game);
|
||||||
|
// testGame4.game.position.set(0, 1, 5);
|
||||||
},
|
},
|
||||||
async expandScenarioData(scene){
|
async expandScenarioData(scene){
|
||||||
scene.data.$environment = (await this.$api.gameObject.load(scene.data.environment)).data
|
scene.data.$environment = (await this.$api.gameObject.load(scene.data.environment)).data
|
||||||
@@ -192,15 +207,16 @@ export default {
|
|||||||
this.pointerDownTime = performance.now();
|
this.pointerDownTime = performance.now();
|
||||||
},
|
},
|
||||||
targetClick(e){
|
targetClick(e){
|
||||||
if (performance.now() - this.pointerDownTime < 200){
|
// if (performance.now() - this.pointerDownTime < 200){
|
||||||
let intersects = gameEngine.intersect(e, this.$refs.target, gameEngine.activeObjects.children, true);
|
// let intersects = gameEngine.intersect(e, this.$refs.target, gameEngine.activeObjects.children, true);
|
||||||
//console.log(intersects)
|
// //console.log(intersects)
|
||||||
if (intersects.length){
|
// if (intersects.length){
|
||||||
|
|
||||||
}else{
|
// }else{
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
gameEngine.onClick(e, this.$refs.target);
|
||||||
},
|
},
|
||||||
setObjectAttributes(l, data, o, autoScaleFactor = 1){
|
setObjectAttributes(l, data, o, autoScaleFactor = 1){
|
||||||
if (l[data.id]){
|
if (l[data.id]){
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { Raycaster, Vector3 } from "three"
|
||||||
|
|
||||||
|
class Clickable {
|
||||||
|
constructor(defaultDistance) {
|
||||||
|
const objects = [];
|
||||||
|
const raycaster = new Raycaster();
|
||||||
|
let v = new Vector3;
|
||||||
|
|
||||||
|
this.add = function (object, fn, distance) {
|
||||||
|
objects.push(object);
|
||||||
|
object._clickable = { fn, distance: distance || defaultDistance };
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function (object) {
|
||||||
|
objects.splice(objects.indexOf(object), 1);
|
||||||
|
delete object._clickable;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update = function (mouse, camera, event) {
|
||||||
|
raycaster.setFromCamera(mouse, camera);
|
||||||
|
let forExecute = [];
|
||||||
|
objects.forEach(o => {
|
||||||
|
console.log(1)
|
||||||
|
o.getWorldPosition(v);
|
||||||
|
if (camera.position.distanceTo(v) <= o._clickable.distance && o.visible) {
|
||||||
|
console.log(2)
|
||||||
|
const intersects = raycaster.intersectObject(o);
|
||||||
|
// intersects.forEach(i=>{
|
||||||
|
// forExecute.push({o, i})
|
||||||
|
// })
|
||||||
|
if (intersects[0]) forExecute.push({ o, i: intersects[0] });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (forExecute[0]) {
|
||||||
|
let sorted = forExecute.sort((a, b) => a.i.distance - b.i.distance);
|
||||||
|
sorted[0].o._clickable.fn(sorted[0].i);
|
||||||
|
if (this.onclick) {
|
||||||
|
this.onclick(sorted[0].o, sorted[0].i, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {Clickable}
|
||||||
+2
-1
@@ -96,7 +96,8 @@ class Hero{
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(){
|
update(){
|
||||||
return;
|
return
|
||||||
|
if (this.gameEngine.renderer.xr.isPresenting) return;
|
||||||
let { inputVelocity, velocity, euler, quat, v, targetQuaternion, clock } = this;
|
let { inputVelocity, velocity, euler, quat, v, targetQuaternion, clock } = this;
|
||||||
let pc = this.pointerControls;
|
let pc = this.pointerControls;
|
||||||
pc.update();
|
pc.update();
|
||||||
|
|||||||
+11
-2
@@ -14,6 +14,7 @@ import { ARButton } from 'three/addons/webxr/ARButton.js';
|
|||||||
import { XRButton } from 'three/addons/webxr/XRButton.js';
|
import { XRButton } from 'three/addons/webxr/XRButton.js';
|
||||||
import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js';
|
import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js';
|
||||||
import * as CANNON from 'cannon-es';
|
import * as CANNON from 'cannon-es';
|
||||||
|
import { Clickable } from './Clickable.js';
|
||||||
|
|
||||||
class GameEngine {
|
class GameEngine {
|
||||||
async init(domNode, opts = {}) {
|
async init(domNode, opts = {}) {
|
||||||
@@ -68,8 +69,8 @@ class GameEngine {
|
|||||||
const renderer = new THREE.WebGLRenderer({
|
const renderer = new THREE.WebGLRenderer({
|
||||||
antialias: true,
|
antialias: true,
|
||||||
// alpha: true,
|
// alpha: true,
|
||||||
preserveDrawingBuffer: true //this is important for screenshots capturing
|
preserveDrawingBuffer: true, //this is important for screenshots capturing
|
||||||
//powerPreference: "high-performance",
|
powerPreference: "high-performance",
|
||||||
});
|
});
|
||||||
renderer.setPixelRatio(window.devicePixelRatio);
|
renderer.setPixelRatio(window.devicePixelRatio);
|
||||||
// renderer.toneMapping = THREE.CineonToneMapping;
|
// renderer.toneMapping = THREE.CineonToneMapping;
|
||||||
@@ -173,6 +174,8 @@ class GameEngine {
|
|||||||
} : {}));
|
} : {}));
|
||||||
this.initXrControllers();
|
this.initXrControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.clickable = new Clickable(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
initXrControllers() {
|
initXrControllers() {
|
||||||
@@ -466,6 +469,12 @@ class GameEngine {
|
|||||||
return intersects;
|
return intersects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClick(mouseEvent, domElement){
|
||||||
|
let mouse = this.getMouseVector(mouseEvent, domElement);
|
||||||
|
this.raycaster.setFromCamera(mouse, this.camera);
|
||||||
|
this.clickable.update(mouse, this.camera, mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
autoScale(object, mk = 1) {
|
autoScale(object, mk = 1) {
|
||||||
let bb = new THREE.Box3().setFromObject(object);
|
let bb = new THREE.Box3().setFromObject(object);
|
||||||
let k = Math.max(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
|
let k = Math.max(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, sRGBEncoding } from 'three';
|
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
|
||||||
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
||||||
import { MotionEngine } from '../MotionEngine';
|
import { MotionEngine } from '../MotionEngine';
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ class Game1 {
|
|||||||
let material = new MeshBasicMaterial({
|
let material = new MeshBasicMaterial({
|
||||||
map: new TextureLoader().load(image)
|
map: new TextureLoader().load(image)
|
||||||
});
|
});
|
||||||
material.map.encoding = sRGBEncoding;
|
//material.map.encoding = sRGBEncoding;
|
||||||
|
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
let b = bm.clone();
|
let b = bm.clone();
|
||||||
@@ -87,7 +87,7 @@ class Game1 {
|
|||||||
f: i == 0 && this.onfinish
|
f: i == 0 && this.onfinish
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
context.dashboard.addPoints(10);
|
//context.dashboard.addPoints(10);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, sRGBEncoding } from 'three';
|
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
|
||||||
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
||||||
import { MotionEngine } from '../MotionEngine';
|
import { MotionEngine } from '../MotionEngine';
|
||||||
|
|
||||||
class Game2 {
|
class Game2 {
|
||||||
constructor(context, image, w, h) {
|
constructor(context, image, w, h) {
|
||||||
const texture = new TextureLoader().load(image);
|
const texture = new TextureLoader().load(image);
|
||||||
texture.encoding = sRGBEncoding;
|
//texture.encoding = sRGBEncoding;
|
||||||
const material = new MeshBasicMaterial({
|
const material = new MeshBasicMaterial({
|
||||||
map: texture
|
map: texture
|
||||||
});
|
});
|
||||||
@@ -136,7 +136,7 @@ class Game2 {
|
|||||||
f: i == 0 && this.onfinish
|
f: i == 0 && this.onfinish
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
context.dashboard.addPoints(10);
|
//context.dashboard.addPoints(10);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import { Group, RGBAFormat } from 'three';
|
||||||
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
|
import { MotionEngine } from '../MotionEngine';
|
||||||
|
|
||||||
|
var Game4 = function(context, gltf, w, h){
|
||||||
|
this.game = new Group();
|
||||||
|
const aq = new MotionEngine();
|
||||||
|
const pr = [];
|
||||||
|
let d = .51, c = w * h / 2, tc = w * h, m0=1, r0=.2;
|
||||||
|
let lastClicked;
|
||||||
|
|
||||||
|
function setMaterial(m, v){
|
||||||
|
if (v){
|
||||||
|
m.metalness = .5;
|
||||||
|
m.roughness = .383;
|
||||||
|
}else{
|
||||||
|
m.metalness = m0;
|
||||||
|
m.roughness = r0;
|
||||||
|
m.transparent = true;
|
||||||
|
m.format = RGBAFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new GLTFLoader().load(gltf, gltf=>{
|
||||||
|
for (let i = 0; i<c; i++){
|
||||||
|
let o = gltf.scene.getObjectByName('c'+(i+1));
|
||||||
|
let ref = [];
|
||||||
|
for (let j = 0; j<2; j++){
|
||||||
|
let position;
|
||||||
|
do {
|
||||||
|
position = Math.floor(Math.random() * tc);
|
||||||
|
}while (pr[position]);
|
||||||
|
ref[j] = o.clone();
|
||||||
|
ref[j].material = o.material.clone();
|
||||||
|
setMaterial(ref[j].material, 0);
|
||||||
|
pr[position] = ref[j];
|
||||||
|
}
|
||||||
|
ref[0].$ref = ref[1];
|
||||||
|
ref[1].$ref = ref[0];
|
||||||
|
}
|
||||||
|
pr.forEach((c, i)=>{
|
||||||
|
c.position.set((i % w)*d , (~~(i / w))*d);
|
||||||
|
c.rotation.set(0, Math.PI, 0);
|
||||||
|
this.game.add(c);
|
||||||
|
context.clickable.add(c, clickFn);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.game.children[0].onBeforeRender = ()=>{
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var check = ()=>{
|
||||||
|
if (!this.game.children.length) return false;
|
||||||
|
return pr.filter(c=>c.$active === false).length == tc;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clickFn = (i)=>{
|
||||||
|
let clicked = i.object;
|
||||||
|
if (this.done && clicked){
|
||||||
|
aq.add({
|
||||||
|
o: clicked,
|
||||||
|
a: {rotation:{y: Math.PI}},
|
||||||
|
t: 1,
|
||||||
|
m: 'offset'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!clicked || clicked.$active === false || aq.isActive(clicked)) return;
|
||||||
|
setMaterial(clicked.material, 1);
|
||||||
|
let f;
|
||||||
|
if (lastClicked && lastClicked.$ref == clicked){
|
||||||
|
clicked.$active = lastClicked.$active = false;
|
||||||
|
[clicked, lastClicked].forEach(c => {
|
||||||
|
aq.add({
|
||||||
|
o: c,
|
||||||
|
a: {material:{opacity:0}},
|
||||||
|
t: 1,
|
||||||
|
d:1
|
||||||
|
});
|
||||||
|
});
|
||||||
|
lastClicked = null;
|
||||||
|
}else if(!lastClicked){
|
||||||
|
lastClicked = clicked;
|
||||||
|
}else{
|
||||||
|
f = ()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
[clicked, lastClicked].filter(c=>c).forEach(c=>{
|
||||||
|
aq.add({
|
||||||
|
o: c,
|
||||||
|
a: {rotation:{y: Math.PI}, material:{metalness:m0, roughness:r0}},
|
||||||
|
t: 1
|
||||||
|
});
|
||||||
|
});
|
||||||
|
lastClicked = null;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aq.add({
|
||||||
|
o: clicked,
|
||||||
|
a: {rotation:{y: 0}},
|
||||||
|
t: .5,
|
||||||
|
f
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update = ()=>{
|
||||||
|
aq.update();
|
||||||
|
if (!this.done && check()){
|
||||||
|
this.done = true;
|
||||||
|
this.game.children.forEach((c, i)=>{
|
||||||
|
aq.add({
|
||||||
|
o: c,
|
||||||
|
a: {material:{opacity:1}},
|
||||||
|
t: 1,
|
||||||
|
d:1+0.1*i
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.onfinish && this.onfinish();
|
||||||
|
//context.dashboard.addPoints(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Game4 }
|
||||||
Reference in New Issue
Block a user