<script src="https://rawgit.com/ngokevin/aframe-layout-component/master/dist/aframe-layout-component.min.js"></script>
<script src="https://rawgit.com/ngokevin/aframe-template-component/master/dist/aframe-template-component.min.js"></script>

<script>
// spawner component to generate an entity on an event.
AFRAME.registerComponent('spawner', {
  schema: {
    on: { default: 'click' },
    mixin: { default: '' }
  },

  /**
   * Add event listener.
   */
  update: function (oldData) {
    this.el.addEventListener(this.data.on, this.spawn.bind(this));
  },

  /**
   * Spawn new entity at entity's current position.
   */
  spawn: function () {
    var el = this.el;
    var entity = document.createElement('a-entity');
    var matrixWorld = el.object3D.matrixWorld;
    var position = new THREE.Vector3();
    var rotation = el.getAttribute('rotation');
    var entityRotation;

    position.setFromMatrixPosition(matrixWorld);
    entity.setAttribute('position', position);

    // Have the spawned entity face the same direction as the entity.
    // Allow the entity to further modify the inherited rotation.
    position.setFromMatrixPosition(matrixWorld);
    entity.setAttribute('position', position);
    entity.setAttribute('mixin', this.data.mixin);
    entity.addEventListener('loaded', function () {
      entityRotation = entity.getComputedAttribute('rotation');
      entity.setAttribute('rotation', {
        x: entityRotation.x + rotation.x,
        y: entityRotation.y + rotation.y,
        z: entityRotation.z + rotation.z
      });
    });
    el.sceneEl.appendChild(entity);
  }
});

// click-listener component to pass window clicks to an entity.
AFRAME.registerComponent('click-listener', {
  init: function () {
    var el = this.el;
    window.addEventListener('click', function () {
      el.emit('click', null, false);
    });
  }
});
</script>

<a-scene>
  <a-assets>
    <img id="enemy-sprite" crossorigin="" src="https://ucarecdn.com/f11bb3e6-ceb4-427c-bcaa-351cabac37d5/">

    <script id="enemies" type="text/x-nunjucks-template">
      <a-entity layout="type: circle; radius: 5" position="0 0.5 0">
        <a-animation attribute="rotation" dur="30000" easing="linear" repeat="indefinite" to="0 360 0"></a-animation>

        {% for x in range(num) %}
        <a-image look-at="#player" src="#enemy-sprite" transparent="true"></a-image>
        {% endfor %}
      </a-entity>
    </script>
    
    <!-- Laser. -->
    <a-mixin id="laser"
             geometry="primitive: cylinder; radius: 0.05; translate: 0 -2 0"
             material="color: green; metalness: 0.2; opacity: 0.4; roughness: 0.3"
             rotation="90 0 0"></a-mixin>
  </a-assets>

  <a-entity template="src: #enemies" data-num="10"></a-entity>

  <!-- Add spawner and click-listener to player. -->
  <a-camera id="player" position="0 1.8 0" spawner="mixin: laser; on: click" click-listener></a-camera>

  <a-sky color="#252243"></a-sky>
</a-scene>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.