From 80841054613f5c7eead2cba40b9d69fc99edf327 Mon Sep 17 00:00:00 2001 From: Fabien Benetou Date: Mon, 13 May 2024 08:48:10 +0200 Subject: [PATCH] Saved state on physics-construct (but challenging syntax) --- index.html | 82 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 8d79c69..3ee32c0 100644 --- a/index.html +++ b/index.html @@ -127,6 +127,9 @@ function showOnlyThisGame(name){ + + todo + test getVoxelPoses() to hash equivalent, in order to be able to share builds */ AFRAME.registerComponent('physics-construct', { init: function(){ @@ -138,7 +141,8 @@ AFRAME.registerComponent('physics-construct', { sphereEl.setAttribute('target', '') sphereEl.setAttribute('position', '0 1 -.5') sphereEl.setAttribute("onpicked", "window.pfb = selectedElements.at(-1).element.getAttribute('position').clone();") - sphereEl.setAttribute("onreleased", "twoPosToBox(window.pfb, selectedElements.at(-1).element.getAttribute('position'),'"+generatorName+"');") + sphereEl.setAttribute("onreleased", "document.querySelector('["+generatorName+"]').components['"+generatorName+"'].twoPosToBox(window.pfb, selectedElements.at(-1).element.getAttribute('position'), '"+generatorName+"');") + // really verbose... consider rebinding or more helpers in such events, facilitating access to this.el and component overall AFRAME.scenes[0].appendChild(sphereEl) let ballEl = document.createElement('a-sphere') @@ -156,6 +160,24 @@ AFRAME.registerComponent('physics-construct', { //let script = document.createElement("script") //script.setAttribute("src", "https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.2.2/dist/aframe-physics-system.min.js") //document.head.appendChild(script) // does not work, check older tricks + + if (window.location.hash) { + let poses = JSON.parse(decodeURI(window.location.hash.replace("#",'')))[generatorName] + // prefixed by generatorName in order to support saving/sharing of the state of other games + poses?.map( p => { + let newEl = document.createElement('a-box') + newEl.setAttribute("scale", p.scale) + newEl.setAttribute("position", p.position) + newEl.setAttribute("rotation", p.rotation) + newEl.setAttribute("target","true") + newEl.setAttribute('static-body', '') + newEl.setAttribute("onreleased", "document.querySelector('["+generatorName+"]').emit('getVoxelPoses')") + newEl.classList.add( "voxel_" + generatorName ) + newEl.classList.add( "voxel" ) + newEl.classList.add( generatorName ) + AFRAME.scenes[0].appendChild(newEl) + }) + } }, events: { reset: function (evt) { @@ -165,26 +187,53 @@ AFRAME.registerComponent('physics-construct', { }, check: function (evt) { }, + getVoxelPoses: function (evt){ + console.log('generating poses') + let generatorName = this.attrName + let poses = [] + // to clarify querySelectorAll here is done on the element and thus should no interfer with other components using the same mechanism + // Array.from( this.el.querySelectorAll(".voxel") ).map( el => { + Array.from( AFRAME.scenes[0].querySelectorAll(".voxel_" + generatorName ) ).map( el => { + poses.push( { + position: this.shortenVector3( el.getAttribute("position") ), + rotation: this.shortenVector3( el.getAttribute("rotation") ), + scale: this.shortenVector3( el.getAttribute("scale") ), + } ) + }) + let data = {} + data[generatorName] = poses + window.location.hash = JSON.stringify(data) + console.log('generated poses:', poses.length) + // prefixed by generatorName in order to support saving/sharing of the state of other games + }, }, -}) - -// should be in the component instead -function twoPosToBox(A, B, generatorName){ + shortenVector3: function ( v ){ + let o = new THREE.Vector3() + o.x = v.x.toFixed(3) + o.y = v.y.toFixed(3) + o.z = v.z.toFixed(3) + return o + }, + twoPosToBox(A, B, generatorName){ let center = A.clone() center.add(B) center.divideScalar(2) let lengthes = A.clone() lengthes.sub(B) - let el = document.createElement("a-box") - el.setAttribute("position", center ) - el.setAttribute('target', '') - el.setAttribute('static-body', '') - //el.setAttribute("onpicked", 'e.detail.element.removeAttribute("dynamic-body")') // untested - //el.setAttribute("onreleased", 'e.detail.element.setAttribute("dynamic-body","")') - el.classList.add( generatorName ) - el.setAttribute("scale", lengthes.toArray().map( i => Math.abs(i) ).join(" ") ) - AFRAME.scenes[0].appendChild(el) -} + let newEl = document.createElement("a-box") + newEl.setAttribute("position", center ) + newEl.setAttribute('target', '') + newEl.setAttribute('static-body', '') + newEl.classList.add( "voxel" ) + newEl.classList.add( generatorName ) + newEl.classList.add( "voxel_" + generatorName ) + newEl.setAttribute("scale", lengthes.toArray().map( i => Math.abs(i) ).join(" ") ) + newEl.setAttribute("onreleased", "document.querySelector('["+generatorName+"]').emit('getVoxelPoses')") + AFRAME.scenes[0].appendChild(newEl) + // should parent to the component element instead... + return newEl + } +}) //___________________________________________________________________________________________________________________________________ AFRAME.registerComponent('voxelpaint', { @@ -561,6 +610,8 @@ AFRAME.registerComponent('fishinbowl', { //___________________________________________________________________________________________________________________________________ let correctlyPlacedLetters = 0 +// should show the target or a box around the letter otherwise can be tricky to grab for some letters without a top left corner + // e.g B is easy, J is hard AFRAME.registerComponent('letterstoword', { init: function(){ correctlyPlacedLetters = 0 @@ -954,6 +1005,7 @@ AFRAME.registerComponent('idleafterload', { +