├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── dist
├── aframe-super-shooter-kit.js
└── aframe-super-shooter-kit.min.js
├── examples
├── basic
│ └── index.html
└── supercraft
│ ├── components
│ └── enemy.js
│ ├── index.html
│ └── sounds
│ ├── enemy1a.ogg
│ ├── enemy1b.ogg
│ ├── enemy1c.ogg
│ ├── enemy2.ogg
│ ├── enemy3.ogg
│ ├── explosion.ogg
│ ├── shoot.ogg
│ └── song.ogg
├── index.html
├── index.js
├── package-lock.json
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | *.sw[pomn]
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | addons:
3 | firefox: 'latest'
4 | node_js:
5 | - '6.9'
6 |
7 | install:
8 | - npm install
9 | - ./node_modules/.bin/mozilla-download ./firefox/ --product firefox --branch mozilla-aurora
10 | - export FIREFOX_NIGHTLY_BIN="./firefox/firefox/firefox-bin"
11 |
12 | before_script:
13 | - export DISPLAY=:99.0
14 | - sh -e /etc/init.d/xvfb start
15 |
16 | script:
17 | - $CI_ACTION
18 |
19 | env:
20 | global:
21 | - TEST_SUITE=unit
22 | matrix:
23 | - CI_ACTION="npm run test"
24 | - CI_ACTION="npm run dist"
25 | # - CI_ACTION="npm run lint"
26 |
27 | branches:
28 | only:
29 | - master
30 |
31 | cache:
32 | directories:
33 | - node_modules
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Diego F. Goberna <diego@feiss.be>
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # aframe-super-shooter-kit
2 |
3 | [A-Frame](https://aframe.io) kit of components for making a simple WebVR
4 | shooter minigame. From the creators of A-Frame, Supermedium, and Supercraft.
5 |
6 | 
7 |
8 | **[PLAY](https://supermedium.github.io/aframe-super-shooter-kit/examples/supercraft/)**
9 |
10 | The kit is set of simple and easy to use components to provide a way of
11 | building simple shooting experiences, where a "shooter" shoots "bullets" that
12 | can hit "targets". A large chunk of the game can be handled at just the
13 | declarative A-Frame layer in HTML.
14 |
15 | 1. One `bullet` entity acts as a template for the instances of shot bullets.
16 | 2. Entity with `shooter` component attached (e.g., a gun) spawns bullets on
17 | `shoot` event from its position.
18 | 3. Collisions among bullet's and `target`'s bounding boxes are checked.
19 | 4. Health and life of targets are calculated (`hit` and `die` events).
20 |
21 | So we define which entities are bullets, shooters, and targets, and then wire
22 | up the game using controls and progress the game with events.
23 |
24 | 
25 |
26 | [Video of Supercraft + Super Shooter Kit workflow](https://www.youtube.com/watch?v=RW3enib2X94)
27 |
28 | ## API
29 |
30 | ### `shooter` component
31 |
32 | The `shooter` component should be attached to a controller for gun. But it can
33 | also be attached to the camera to support 2D / desktop or normal smartphone if
34 | wired to mouse or touch.
35 |
36 | | Property | Description | Default Value |
37 | | -------- | ----------- | ------------- |
38 | | activeBulletType | Name of current active bullet the shooter is firing. | 'normal' |
39 | | bulletTypes | Array of possible bullet names. | ['normal'] |
40 | | cycle | A flag to tell when swapping to the `next` or `prev` bullet type, cycle to the first or last type when reaching the last or first type respectively. | false |
41 |
42 | #### Events
43 |
44 | These events can be triggered with `entity.emit(eventName)`.
45 |
46 | | Event Name | Effect |
47 | |----------------|-------------------------------------------------------------|
48 | | shoot | Shoot a bullet. |
49 | | changebullet | Swap bullet type (either `prev`, `next`, or name of bullet. |
50 |
51 | ### `bullet` component
52 |
53 | | Property | Description | Default Value |
54 | |--------------|---------------------------------------------------------------------------|---------------|
55 | | damagePoints | How many health points to remove from target when hitting target. | 1.0 |
56 | | maxTime | Life time of bullet in seconds. When elapsed, the bullet will be removed. | 1.0 |
57 | | name | Name of the bullet type. | normal |
58 | | poolSize | How many copies of this bullet can be on screen at once. | 10 |
59 | | speed | Speed of bullet in meters per second. | 1.0 |
60 |
61 | ### `target` component
62 |
63 | | Property | Description | Default Value |
64 | |--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
65 | | active | Whether this target is included in collision tests. | true |
66 | | healthPoints | Number of hit or health points of the target. When a bullet hits this target, its health points will decrease by the bullet's damage points. When the target reaches 0 health points, then the event 'die' is emitted on the target. | 1 |
67 | | static | Whether this object does not ever move or change shape. If set to false, then the bounding box is recalculated continuously. | true |
68 |
69 | #### Members
70 |
71 | Component members can be accessed by like `entity.components.target.lastBulletHit`:
72 |
73 | | Member | Description |
74 | |---------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
75 | | lastBulletHit | Reference object to the last bullet object3D that hit the target. Useful for attaining the position of where the bullet contacted the target. |
76 |
77 | #### Events
78 |
79 | Events emitted on the target that we can listen to, to perhaps show an
80 | explosion effect on target hit or die.
81 |
82 | | Event Name | Description |
83 | |------------|--------------------------------------------------------|
84 | | hit | Target was hit by a bullet. |
85 | | die | Target ran out of healthPoints and has been destroyed. |
86 |
87 | ## With Supercraft Assets
88 |
89 | [Supercraft](https://supermedium.com/supercraft) is an A-Frame WebVR
90 | application that lets you build low-poly VR assets inside of VR with your
91 | hands, and export them to Web or JSON! With the shooter kit providing dead-easy
92 | components, A-Frame letting you do things in just HTML, and ability to create
93 | good assets without modeling experience, WebVR development is made simple.
94 |
95 | The advantage of the Supercraft JSON exports alongside
96 | [aframe-supercraft-loader](https://www.npmjs.com/package/aframe-supercraft-loader)
97 | and [aframe-supercraft-thing](https://www.npmjs.com/package/aframe-supercraft-thing)
98 | is that they are tailored for A-Frame resulting in extremely small file sizes
99 | and performant through geometry merging.
100 |
101 | All 3D assets in this scene are delivered within a single 190KB JSON file:
102 | [Supercraft Shooter](https://supermedium.github.io/supercraft-shooter). All
103 | the assets in the game were done using Supercraft in **45 minutes**, and the
104 | code is just dozens of lines of Javascript and HTML. Game created in an
105 | afternoon.
106 |
107 | An extremely cool workflow is using the `supercraft-loader` to "live-reload"
108 | assets. The Supercraft JSON is hosted on the Web via name; we just need to do
109 | `supercraft-loader="name: my-supercraft-site"`, and whenever we publish an update
110 | to `my-supercraft-site` within Supercraft, the scene will automatically have
111 | access to the fresh new assets.
112 |
113 | And `supercraft-thing-loader` can be used to pick individual objects out of a
114 | Supercraft scene of objects. You can create all your assets in one scene, make
115 | sure they have good scale relative to one another, tweak them all at once!
116 |
117 | **[VIDEO](https://www.youtube.com/watch?v=RW3enib2X94)**
118 |
119 | ## Installation
120 |
121 | ### Browser
122 |
123 | See the [Supercraft Shooter example source
124 | code](https://github.com/supermedium/aframe-super-shooter-kit/tree/master/examples/supercraft).
125 |
126 | Install and use by directly including the [browser files](dist):
127 |
128 | ```html
129 |
130 | A-Frame Super Shooter Kit - Basic
131 |
132 |
133 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | ```
182 |
183 | ### npm
184 |
185 | Install via npm:
186 |
187 | ```bash
188 | npm install aframe-super-shooter-kit
189 | ```
190 |
191 | Then require and use.
192 |
193 | ```js
194 | require('aframe');
195 | require('aframe-super-shooter-kit');
196 | ```
197 |
--------------------------------------------------------------------------------
/dist/aframe-super-shooter-kit.js:
--------------------------------------------------------------------------------
1 | !function(e){var t={};function i(n){if(t[n])return t[n].exports;var l=t[n]={i:n,l:!1,exports:{}};return e[n].call(l.exports,l,l.exports,i),l.l=!0,l.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)i.d(n,l,function(t){return e[t]}.bind(null,l));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t){if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");AFRAME.registerComponent("shooter",{schema:{activeBulletType:{type:"string",default:"normal"},bulletTypes:{type:"array",default:["normal"]},cycle:{default:!1}},init:function(){this.el.addEventListener("shoot",this.onShoot.bind(this)),this.el.addEventListener("changebullet",this.onChangeBullet.bind(this)),this.bulletSystem=this.el.sceneEl.systems.bullet},onShoot:function(){this.bulletSystem.shoot(this.data.activeBulletType,this.el.object3D)},onChangeBullet:function(e){var t,i=this.data,n=this.el;if("next"===e.detail){if(-1===(t=i.bulletTypes.indexOf(i.activeBulletType)))return;return t=i.cycle?(t+1)%i.bulletTypes.length:Math.min(i.bulletTypes.length-1,t+1),i.activeBulletType=i.bulletTypes[t],void n.setAttribute("shooter","activeBulletType",i.bulletTypes[t])}if("prev"===e.detail){if(-1===(t=i.bulletTypes.indexOf(i.activeBulletType)))return;return t=i.cycle?(t-1)%i.bulletTypes.length:Math.max(0,t-1),i.activeBulletType=i.bulletTypes[t],void n.setAttribute("shooter","activeBulletType",i.bulletTypes[t])}n.setAttribute("shooter","activeBulletType",e.detail)}}),AFRAME.registerComponent("bullet",{dependencies:["material"],schema:{damagePoints:{default:1,type:"float"},maxTime:{default:4,type:"float"},name:{default:"normal",type:"string"},poolSize:{default:10,type:"int",min:0},speed:{default:8,type:"float"}},init:function(){var e=this.el;e.object3D.visible=!1,e.addEventListener("object3dset",t=>{e.sceneEl.systems.bullet.registerBullet(this)})}}),AFRAME.registerSystem("bullet",{init:function(){var e;(e=document.createElement("a-entity")).id="superShooterBulletContainer",this.el.sceneEl.appendChild(e),this.container=e.object3D,this.pool={},this.targets=[]},registerBullet:function(e){var t,i,n,l;if(l=e.el.object3D)for(i=e.data,this.pool[i.name]=[],n=0;nl&&(n=i,l=o[i].time)}return this.shootBullet(o[n],t)},shootBullet:function(e,t){return e.visible=!0,e.time=0,t.getWorldPosition(e.position),t.getWorldDirection(e.direction),e.direction.multiplyScalar(-e.speed),this.container.add(e),e},tick:function(){var e=new THREE.Box3,t=new THREE.Vector3,i=new THREE.Box3;return function(n,l){var o,r,s,a,u;for(r=0;r=o.maxTime)this.killBullet(o);else for(t.copy(o.direction).multiplyScalar(l/850),o.position.add(t),e.setFromObject(o),u=0;u{e.sceneEl.systems.bullet.registerTarget(this,this.data.static)})},update:function(e){this.healthPoints=this.data.healthPoints},onBulletHit:function(e){this.data.active&&(this.lastBulletHit=e,this.healthPoints-=e.damagePoints,this.healthPoints<=0&&this.el.emit("die"))}})}]);
--------------------------------------------------------------------------------
/dist/aframe-super-shooter-kit.min.js:
--------------------------------------------------------------------------------
1 | !function(e){var t={};function i(n){if(t[n])return t[n].exports;var l=t[n]={i:n,l:!1,exports:{}};return e[n].call(l.exports,l,l.exports,i),l.l=!0,l.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)i.d(n,l,function(t){return e[t]}.bind(null,l));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t){if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");AFRAME.registerComponent("shooter",{schema:{activeBulletType:{type:"string",default:"normal"},bulletTypes:{type:"array",default:["normal"]},cycle:{default:!1}},init:function(){this.el.addEventListener("shoot",this.onShoot.bind(this)),this.el.addEventListener("changebullet",this.onChangeBullet.bind(this)),this.bulletSystem=this.el.sceneEl.systems.bullet},onShoot:function(){this.bulletSystem.shoot(this.data.activeBulletType,this.el.object3D)},onChangeBullet:function(e){var t,i=this.data,n=this.el;if("next"===e.detail){if(-1===(t=i.bulletTypes.indexOf(i.activeBulletType)))return;return t=i.cycle?(t+1)%i.bulletTypes.length:Math.min(i.bulletTypes.length-1,t+1),i.activeBulletType=i.bulletTypes[t],void n.setAttribute("shooter","activeBulletType",i.bulletTypes[t])}if("prev"===e.detail){if(-1===(t=i.bulletTypes.indexOf(i.activeBulletType)))return;return t=i.cycle?(t-1)%i.bulletTypes.length:Math.max(0,t-1),i.activeBulletType=i.bulletTypes[t],void n.setAttribute("shooter","activeBulletType",i.bulletTypes[t])}n.setAttribute("shooter","activeBulletType",e.detail)}}),AFRAME.registerComponent("bullet",{dependencies:["material"],schema:{damagePoints:{default:1,type:"float"},maxTime:{default:4,type:"float"},name:{default:"normal",type:"string"},poolSize:{default:10,type:"int",min:0},speed:{default:8,type:"float"}},init:function(){var e=this.el;e.object3D.visible=!1,e.addEventListener("object3dset",t=>{e.sceneEl.systems.bullet.registerBullet(this)})}}),AFRAME.registerSystem("bullet",{init:function(){var e;(e=document.createElement("a-entity")).id="superShooterBulletContainer",this.el.sceneEl.appendChild(e),this.container=e.object3D,this.pool={},this.targets=[]},registerBullet:function(e){var t,i,n,l;if(l=e.el.object3D)for(i=e.data,this.pool[i.name]=[],n=0;nl&&(n=i,l=o[i].time)}return this.shootBullet(o[n],t)},shootBullet:function(e,t){return e.visible=!0,e.time=0,t.getWorldPosition(e.position),t.getWorldDirection(e.direction),e.direction.multiplyScalar(-e.speed),this.container.add(e),e},tick:function(){var e=new THREE.Box3,t=new THREE.Vector3,i=new THREE.Box3;return function(n,l){var o,r,s,a,u;for(r=0;r=o.maxTime)this.killBullet(o);else for(t.copy(o.direction).multiplyScalar(l/850),o.position.add(t),e.setFromObject(o),u=0;u{e.sceneEl.systems.bullet.registerTarget(this,this.data.static)})},update:function(e){this.healthPoints=this.data.healthPoints},onBulletHit:function(e){this.data.active&&(this.lastBulletHit=e,this.healthPoints-=e.damagePoints,this.healthPoints<=0&&this.el.emit("die"))}})}]);
2 |
--------------------------------------------------------------------------------
/examples/basic/index.html:
--------------------------------------------------------------------------------
1 |
2 | A-Frame Super Shooter Kit - Basic
3 |
4 |
5 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/examples/supercraft/components/enemy.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Enemy component.
3 | * Handle enemy animation and dying behavior.
4 | * Favor using threejs `object3D` property of entities rather than `setAttribute()`
5 | * for optimization.
6 | */
7 | AFRAME.registerComponent('enemy', {
8 | schema: {
9 | // 1: behind bushes
10 | // 2: behind trees
11 | // 3: behind clouds
12 | type: {default: 1}
13 | },
14 |
15 | /**
16 | * Initialize listeners and component variables.
17 | * Find and link with the explosion object associated.
18 | */
19 | init: function () {
20 | var el = this.el;
21 | var explosionScale;
22 |
23 | this.hidingPos = 0; // Save rest y position when enemy is hidden.
24 | this.timeout = null; // Timeout for waiting for the next appearance.
25 | this.tweenAppear = null; // Tween for appearing animation.
26 | this.tweenDisappear = null; // Tween for hiding animation.
27 | this.vulnerable = false; // Cannot be shoot when it's hiding.
28 |
29 | // Link with explosion object.
30 | // Hide explosion object and set scale depending on type of enemy (further == bigger).
31 | this.explosion = document.getElementById(`${this.el.id}expl`).object3D;
32 | this.explosion.visible = false;
33 | explosionScale = this.data.type * 2.2;
34 | this.explosion.scale.set(explosionScale, explosionScale, explosionScale);
35 |
36 | el.addEventListener('run', this.run.bind(this));
37 | el.addEventListener('stop', this.stop.bind(this));
38 | el.addEventListener('hit', this.die.bind(this));
39 | },
40 |
41 | /**
42 | * Game start. When start message is shot.
43 | */
44 | run: function () {
45 | var lift;
46 |
47 | // Create tweens if not created yet.
48 | if (this.tweenAppear === null) {
49 | // Save hidingPos (default position on the Supercraft site).
50 | this.hidingPos = this.el.object3D.position.y;
51 |
52 | // Depending the type of enemy, the further it is, the higher it has to rise.
53 | lift = this.data.type * 1.2;
54 | this.tweenAppear = new TWEEN.Tween(this.el.object3D.position)
55 | .to({y: this.hidingPos + lift}, 500)
56 | .easing(TWEEN.Easing.Elastic.Out)
57 | .onComplete(this.endAppear.bind(this));
58 |
59 | this.tweenDisappear = new TWEEN.Tween(this.el.object3D.position)
60 | .to({y: this.hidingPos}, 200)
61 | .delay(1000)
62 | .easing(TWEEN.Easing.Cubic.Out)
63 | .onComplete(this.endDisappear.bind(this));
64 | }
65 |
66 | // Hide start message.
67 | document.getElementById('startMessage').object3D.visible = false;
68 | this.appear();
69 | },
70 |
71 | /**
72 | * Animate and move in.
73 | */
74 | appear: function () {
75 | this.tweenAppear.start();
76 | this.el.querySelector('[sound]').components.sound.playSound();
77 | },
78 |
79 | /**
80 | * Handle appearance animation finished.
81 | */
82 | endAppear: function () {
83 | this.vulnerable = true;
84 | // We can start the disappear tween right away because it has a delay and it will hold a
85 | // sec.
86 | this.tweenDisappear.start();
87 | },
88 |
89 | /**
90 | * Handle hiding animation is finished.
91 | */
92 | endDisappear: function () {
93 | this.vulnerable = false;
94 | // Set next appearance to a random value of seconds between 1 and 4.
95 | this.timeout = setTimeout(this.appear.bind(this),
96 | 1000 + Math.floor(Math.random() * 3000));
97 | },
98 |
99 | /**
100 | * Stop tweens and timeouts.
101 | */
102 | stop: function () {
103 | this.tweenAppear.stop();
104 | this.tweenDisappear.stop();
105 | clearTimeout(this.timeout);
106 | this.vulnerable = false;
107 | },
108 |
109 | /**
110 | * Enemy was killed (this is called via `die` event thrown by the bullets when collide).
111 | */
112 | die: function (evt) {
113 | var el = this.el;
114 |
115 | if (!this.vulnerable) { return; } // I'm hidden!
116 |
117 | this.stop();
118 |
119 | // Hide enemy, return it to hiding position.
120 | el.object3D.visible = false;
121 | el.object3D.position.y = this.hidingPos;
122 |
123 | // Play explosion sound.
124 | document.getElementById('commonExplosion').components.sound.playSound();
125 |
126 | // Show explosion on the hit position and make it look to center of stage.
127 | this.explosion.position.copy(this.el.components.target.lastBulletHit.position);
128 | this.explosion.lookAt(0, 1.6, 0);
129 | this.explosion.visible = true;
130 |
131 | // Wait 300 ms to hide explosion.
132 | setTimeout(() => {
133 | this.explosion.visible = false;
134 | this.el.object3D.visible = true;
135 | // After a random number of secs (2-5), appear again.
136 | setTimeout(this.appear.bind(this),
137 | 2000 + Math.floor(Math.random() * 3000));
138 | }, 300);
139 | }
140 | });
141 |
--------------------------------------------------------------------------------
/examples/supercraft/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Supercraft Shooter
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
119 |
120 |
121 |
126 |
127 |
131 |
140 |
141 |
142 |
143 |
144 |
145 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
170 |
171 |
173 |
174 |
--------------------------------------------------------------------------------
/examples/supercraft/sounds/enemy1a.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/enemy1a.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/enemy1b.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/enemy1b.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/enemy1c.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/enemy1c.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/enemy2.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/enemy2.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/enemy3.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/enemy3.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/explosion.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/shoot.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/shoot.ogg
--------------------------------------------------------------------------------
/examples/supercraft/sounds/song.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/supermedium/aframe-super-shooter-kit/7b1da1b59e1adc4b182b591167456bd4a6f8caff/examples/supercraft/sounds/song.ogg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | A-Frame Super Shooter Kit
6 |
7 |
48 |
49 |
50 |
A-Frame super-shooter kit
51 |
52 |
53 |
54 |
55 |
Supercraft Shooter
56 |
Full example of using aframe-super-shooter-kit with assets made in VR with Supercraft.