我如何从列表中克隆一个随机对象并使用 A-frame.js 使其可见

how do i clone a random object from a list and make it visible using A-frame.js

我正在使用 Javascript 和 A 型框架。我希望能够从块列表中获得一个随机块,并且我希望它向下移动 1。我似乎无法让任何块随机出现在负载电流上。下面是我创建的用于制作我的俄罗斯方块板的代码,但它目前给我一些小问题。

我遇到了错误

  "message": "Uncaught SyntaxError: Unexpected end of input",

我不确定那是什么意思?

var zigZag = document.querySelector("#zigZag");

var fork = document.querySelector("#fork");

var box = document.querySelector("#box");

var line = document.querySelector("#line");

var plane = document.querySelector("#plane");

//timer
// let hour = 0;
// let minute = 0;
// let second = 0;
// let millisecond = 0;

// let cron;

var newBlock, blocks, element, blocksOnPlane, planeBlock;

// Describe this function...

newBlock = [];

blocks = [zigZag, fork, line, box];

blocksOnPlane = [];
document.addEventListener("load", start);

function start() {
  while (true) {
    new Promise((res) => setTimeout(() => res(chooseBlock()), 10));
    console.log(newBlock.length);
    for (var element_index in newBlock) {
      element = newBlock[element_index];
      moveBlock(element);
      plane.detectCollisionsWith(newBlock[element_index], function (
        collidedObject
      ) {
        newBlock = collidedObject;
        newBlock.object3D.position.y = 0;
        blocksOnPlane.unshift(planeBlock);
        newBlock.shift();
      });
      // for (var element_index in blocksOnPlane) {
      //     element = blocksOnPlane[element_index];
      //     newBlock.detectCollisionsWith(planeBlock, function (collidedObject) {
      //         element.setY(element.getY() + 0)
      //         planeBlock = collidedObject;
      //         blocksOnPlane.unshift(planeBlock);
      //         newBlock.shift();

      //     })
      // }
    }
  }
}


document.addEventListener("keydown", function (event) {
  if (event.keyCode === 37) {
    element.object3D.position.x += -1;
  }
  //top
  else if (event.keyCode === 38) {
    element.object3D.position.x += 1;
  }
  //right
  else if (event.keyCode === 39) {
    element.object3D.position.x += 1;
  }
  //bottom
  else if (event.keyCode === 40) {
    element.object3D.position.x += -1;
  }
});

function moveBlock(element) {
  document.createTimer("timer1", 1 * 1000, function () {
    element.object3D.position.y += -1;
  });
}

function listsGetRandomItem(list, remove) {
  var x = Math.floor(Math.random() * list.length);
  if (remove) {
    return list.splice(x, 1)[0];
  } else {
    return list[x];
  }
}

// Describe this function...
function chooseBlock() {
  var tetrisBlock = document.clone(listsGetRandomItem(blocks, false));
  tetrisBlock.visible = true;
  tetrisBlock.object3D.position.x = 0;
  tetrisBlock.object3D.position.y = 7.5;
  tetrisBlock.object3D.position.z = -14;
  newBlock.unshift(tetrisBlock);
}
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<!DOCTYPE html>

    <button type="button" name="start">start</button>
    <button type="button" name="pause">pause</button>
    <button type="button" name="reset">reset</button>
    <a-scene>
      <a-entity
        id="zigZag"
        collide-with-player=""
        hatch-type-shape=""
        data-hatch-type="hatch-type-empty"
        data-icon-type="rectangle"
        physics-scale-fix=""
        hatch-physics=""
        shadow="cast: false; receive: false"
        hatch-cursor-event-detection="enableCursorDetection: true"
        position="-4.0825353394644335 5.15966087923683 -17.160361366799766"
        color="#d5b949"
        class="clickable"
        <!--
        visible="true"
        --
      >
        ><a-box
          id="line6"
          collide-with-player=""
          hatch-type-shape=""
          geometry="primitive: box"
          data-hatch-type="hatch-type-shape"
          data-icon-type="box"
          physics-scale-fix=""
          hatch-physics=""
          shadow=""
          hatch-cursor-event-detection="enableCursorDetection: true"
          position="5.039535339464433 3.3480091207631695 3.1603613667997656"
          color="#f1eaa3"
          material="color: #f1eaa3"
          class="clickable"
          scale="2 1 1"
          rotation="0 0 89.99999999999999"
          child-test="true"
        ></a-box
        ><a-box
          id="line5"
          collide-with-player=""
          hatch-type-shape=""
          geometry="primitive: box"
          data-hatch-type="hatch-type-shape"
          data-icon-type="box"
          physics-scale-fix=""
          hatch-physics=""
          shadow=""
          hatch-cursor-event-detection="enableCursorDetection: true"
          position="4.137505339464433 4.44454912076317 3.1603613667997656"
          color="#f1eaa3"
          material="color: #f1eaa3"
          class="clickable"
          scale="2 1 1"
          rotation="0 0 89.99999999999999"
          child-test="true"
        ></a-box
        ><a-box
          id="line4"
          collide-with-player=""
          hatch-type-shape=""
          geometry="primitive: box"
          data-hatch-type="hatch-type-shape"
          data-icon-type="box"
          physics-scale-fix=""
          hatch-physics=""
          shadow=""
          hatch-cursor-event-detection="enableCursorDetection: true"
          position="4.636015339464434 3.91959912076317 3.1603613667997656"
          color="#f1eaa3"
          material="color: #f1eaa3"
          class="clickable"
          scale="2 1 1"
          rotation="0 0 0"
          child-test="true"
        ></a-box
      ></a-entity>
      <a-entity
        id="fork"
        collide-with-player=""
        hatch-type-shape=""
        data-hatch-type="hatch-type-empty"
        data-icon-type="rectangle"
        physics-scale-fix=""
        hatch-physics=""
        shadow="cast: false; receive: false"
        hatch-cursor-event-detection="enableCursorDetection: true"
        position="1.158747821160648 5.997102835551197 -14.335538215901849"
        color="#617ec2"
        class="clickable"
        rotation="0 0 0"
        scale="1 1 1"
        visible="true"
        ><a-box
          id="line3"
          collide-with-player=""
          hatch-type-shape=""
          geometry="primitive: box"
          data-hatch-type="hatch-type-shape"
          data-icon-type="box"
          physics-scale-fix=""
          hatch-physics=""
          shadow=""
          hatch-cursor-event-detection="enableCursorDetection: true"
          position="-1.158747821160648 1.502897164448803 0.33553821590184896"
          color="#a3eaf1"
          material="color: #a3eaf1"
          class="clickable"
          scale="3 1.0000000000000002 1"
          rotation="0 0 89.99999999999999"
          child-test="true"
        ></a-box
        ><a-box
          id="line2"
          collide-with-player=""
          hatch-type-shape=""
          geometry="primitive: box"
          data-hatch-type="hatch-type-shape"
          data-icon-type="box"
          physics-scale-fix=""
          hatch-physics=""
          shadow=""
          hatch-cursor-event-detection="enableCursorDetection: true"
          position="-0.60527 1.44434 0.33554"
          color="#a3edf1"
          material="color: #a3edf1"
          class="clickable"
          scale="2 1 1"
          rotation="0 0 0"
          child-test="true"
        ></a-box
      ></a-entity>
      <a-box
        hatch-type-shape=""
        data-icon-type="box"
        id="box"
        shadow=""
        displayname="Box"
        position="0 9.09 -14"
        rotation="0 0 0"
        color="#4CC3D9"
        side="front"
        hatch-physics=""
        data-hatch-type="hatch-type-shape"
        material="color: #4CC3D9; side: front"
        geometry="primitive: box"
        physics-scale-fix=""
        hatch-cursor-event-detection="enableCursorDetection: true"
        collide-with-player=""
        class="clickable"
        scale="2 2 1"
        child-test="true"
        visible="true"
      ></a-box>
      <a-box
        id="line"
        collide-with-player=""
        hatch-type-shape=""
        geometry="primitive: box"
        data-hatch-type="hatch-type-shape"
        data-icon-type="box"
        physics-scale-fix=""
        hatch-physics=""
        shadow=""
        hatch-cursor-event-detection="enableCursorDetection: true"
        position="0 7.5 -14"
        color="#a3f1af"
        material="color: #a3f1af"
        class="clickable"
        scale="4 1 1"
        visible="true"
      ></a-box>
      <a-entity
        id="Ground"
        ground="dressing: none; groundSize: 100; ground: flat; groundTexture: none; grid: 1x1; groundColor: #333343; flatShading: true; gridColor: #B5B5B5"
        data-hatch-type="hatch-type-ground"
        data-is-droppable="false"
        data-icon-type="terrain"
        data-is-expandable="false"
        position="0 0 0"
        color="#62E9F7"
        visible="true"
        ><a-entity
          class="environment"
          position=""
          visible=""
          light=""
          data-not-selectable="true"
          data-hide-model="true"
          data-icon-type="light-hemisphere"
        ></a-entity
        ><a-entity
          class="environment"
          position=""
          light=""
          data-hide-model="true"
          visible="true"
          data-icon-type="light-directional"
        ></a-entity
        ><a-entity
          rotation=""
          visible=""
          data-not-selectable="true"
          class="environmentGround environment"
          scale=""
          shadow=""
        ></a-entity
        ><a-entity
          data-not-selectable="true"
          visible=""
          class="environmentDressing environment"
        ></a-entity
      ></a-entity>
      <a-plane
        id="plane"
        collide-with-player=""
        hatch-type-shape=""
        geometry="primitive: plane"
        data-hatch-type="hatch-type-shape"
        data-icon-type="plane"
        physics-scale-fix=""
        hatch-physics=""
        shadow=""
        hatch-cursor-event-detection=""
        position="-0.38406 0 -16.5359"
        color="#975c26"
        material="color: #975c26; shader: flat; side: back"
        rotation="90 0 0"
        scale="17.9 12.9 1"
        visible="true"
      ></a-plane>
    </a-scene>

不确定您从哪里得到 document.clone(element) 作为 document 对象 doesn't seem to have a cloning utility

有一个element.cloneNode() method which works fine - we can use it within a custom component,它也将处理实体生命周期:

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  // register new component
  AFRAME.registerComponent("foo", {
    // on init
    init: function() {
      // grab the button, and the entity
      const btn = document.querySelector("button")
      const tmplate = document.getElementById("template")

      // when clicked
      btn.addEventListener("click", evt => {
        // clone the node
        const new_element = tmplate.cloneNode(true);
        // make it smaller, and move it a bit
        new_element.setAttribute("scale", "0.2 0.2 0.2")
        new_element.setAttribute("position", {
          x: Math.random() * 6 - 3,
          y: 0.5,
          z: -1
        })
        // append it to the scene
        this.el.appendChild(new_element)
      })
    }
  })
</script>
<button style="z-index: 9999; position: fixed;">COPY</button>
<a-scene foo>
  <a-entity id="template">
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
    <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
  </a-entity>
  <a-sky color="#ECECEC"></a-sky>
</a-scene>


您可以使用 interval timeouts, or a tick / throttledTick handler. This could be done within a system 将其向下移动,这将管理创建的实体(向下移动、碰撞)。

一个简单的“向下移动”版本可能如下所示:

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  //register system
  AFRAME.registerSystem("foo", {
    init: function() {
      // array of all registered elements
      this.elements = [];
      // set up the throttled version
      this.tick = AFRAME.utils.throttleTick(this.tick, 250, this);
    },
    register: function(el) {
      // push new element to the registered array
      this.elements.push(el)
    },
    tick: function() {
      // loop through all of the elements, and move them down
      for (el of this.elements) {
        const pos = el.object3D.position // this is more efficient than getAttribute("position")
        pos.y = (pos.y < 0) ? 2 : pos.y - 0.1; // use setAttribute() if you want getAttribute() to work
      }
    }
  })

  // register new component
  AFRAME.registerComponent("foo", {
    // on init
    init: function() {
      //  move it a bit, and make it visible
      this.el.setAttribute("position", {
        x: Math.random() * 6 - 3,
        y: 0.5,
        z: -2
      })
      this.el.setAttribute("visible", "true")

      // register the element in the system
      this.system.register(this.el)
    }
  })

  AFRAME.registerComponent("inserter", {
    init: function() {
      // grab the button, and the entity
      const btn = document.querySelector("button")
      const tmplate = document.getElementById("template")

      // when clicked
      btn.addEventListener("click", evt => {
        // clone the node
        const new_element = tmplate.cloneNode(true);
        new_element.setAttribute("foo", "")
        // append it to the scene
        this.el.appendChild(new_element)
      })
    }
  })
</script>
<button style="z-index: 9999; position: fixed;">NEW</button>
<a-scene inserter>
  <a-entity id="template" visible="false" scale="0.2 0.2 0.2">
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
    <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
  </a-entity>
  <a-sky color="#ECECEC"></a-sky>
</a-scene>


迟早你可能会 运行 遇到性能问题(一旦有多个节点),最好深入研究 mesh instancing (or at least check the performance guidelines)