2018-07-20 09:34:52 +02:00
|
|
|
var utils = require('../utils');
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Load beat data (all the beats and such).
|
|
|
|
|
*/
|
|
|
|
|
AFRAME.registerComponent('beat-loader', {
|
|
|
|
|
schema: {
|
|
|
|
|
challengeId: {type: 'string'},
|
2018-10-01 17:37:11 -07:00
|
|
|
difficulty: {type: 'string'},
|
|
|
|
|
beatSpeed: {default: 4.0},
|
|
|
|
|
beatAnticipationTime: {default: 2.0}
|
2018-07-20 09:34:52 +02:00
|
|
|
},
|
|
|
|
|
|
2018-10-01 17:37:11 -07:00
|
|
|
orientations: [180, 0, 270, 90, 225, 135, 315, 45, 0],
|
|
|
|
|
horizontalPositions: [-0.60, -0.25, 0.25, 0.60],
|
|
|
|
|
verticalPositions: [1.00, 1.35, 1.70],
|
|
|
|
|
|
2018-07-20 09:34:52 +02:00
|
|
|
update: function () {
|
2018-07-21 10:21:30 +02:00
|
|
|
if (!this.data.challengeId || !this.data.difficulty) { return; }
|
2018-10-01 17:37:11 -07:00
|
|
|
this.loadBeats();
|
2018-07-21 10:21:30 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* XHR.
|
|
|
|
|
*/
|
2018-10-01 17:37:11 -07:00
|
|
|
loadBeats: function () {
|
2018-07-20 09:34:52 +02:00
|
|
|
var el = this.el;
|
|
|
|
|
var xhr;
|
|
|
|
|
|
|
|
|
|
// Load beats.
|
2018-07-21 10:21:30 +02:00
|
|
|
let url = utils.getS3FileUrl(this.data.challengeId, `${this.data.difficulty}.json`);
|
2018-07-20 09:34:52 +02:00
|
|
|
xhr = new XMLHttpRequest();
|
|
|
|
|
el.emit('beatloaderstart');
|
2018-07-21 10:21:30 +02:00
|
|
|
console.log(`Fetching ${url}...`);
|
|
|
|
|
xhr.open('GET', url);
|
2018-07-20 09:34:52 +02:00
|
|
|
xhr.addEventListener('load', () => {
|
|
|
|
|
this.handleBeats(JSON.parse(xhr.responseText));
|
|
|
|
|
});
|
|
|
|
|
xhr.send();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
2018-10-01 17:37:11 -07:00
|
|
|
* Load the beat data into the game.
|
2018-07-20 09:34:52 +02:00
|
|
|
*/
|
|
|
|
|
handleBeats: function (beatData) {
|
2018-07-21 10:21:30 +02:00
|
|
|
this.el.sceneEl.emit('beatloaderfinish', beatData, false);
|
2018-10-01 17:37:11 -07:00
|
|
|
var lessThan = function (a, b) {
|
|
|
|
|
return a._time - b._time;
|
|
|
|
|
};
|
|
|
|
|
this.beatData = beatData;
|
|
|
|
|
this.beatData._obstacles.sort(lessThan);
|
|
|
|
|
this.beatData._notes.sort(lessThan);
|
2018-07-20 09:34:52 +02:00
|
|
|
console.log('Finished loading challenge data.');
|
|
|
|
|
},
|
2018-10-01 17:37:11 -07:00
|
|
|
|
|
|
|
|
tick: function (time, delta) {
|
|
|
|
|
var audioEl = this.el.components.song.audio;
|
|
|
|
|
var notes;
|
|
|
|
|
var obstacles;
|
|
|
|
|
var lastTime = this.lastTime || 0;
|
|
|
|
|
var msPerBeat;
|
|
|
|
|
var noteTime;
|
|
|
|
|
|
|
|
|
|
if (!this.data.challengeId || !this.beatData || !audioEl) { return; }
|
|
|
|
|
|
|
|
|
|
notes = this.beatData._notes;
|
|
|
|
|
obstacles = this.beatData._obstacles;
|
|
|
|
|
this.bpm = this.beatData._beatsPerMinute;
|
|
|
|
|
msPerBeat = 1000 * 60 / this.beatData._beatsPerMinute;
|
|
|
|
|
for (i=0; i < notes.length; ++i) {
|
|
|
|
|
noteTime = notes[i]._time * msPerBeat;
|
|
|
|
|
if (noteTime > lastTime && noteTime <= lastTime + delta) {
|
|
|
|
|
notes[i].time = noteTime;
|
|
|
|
|
this.generateBeat(notes[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i=0; i < obstacles.length; ++i) {
|
|
|
|
|
noteTime = obstacles[i]._time * msPerBeat;
|
|
|
|
|
if (noteTime > lastTime && noteTime <= lastTime + delta) {
|
|
|
|
|
// this.generateWall(obstacles[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.lastTime = lastTime + delta;
|
|
|
|
|
|
|
|
|
|
// Sync audio with first element.
|
|
|
|
|
if (this.audioSync || !this.first) { return; }
|
|
|
|
|
if (this.first.el.object3D.position.z < this.el.sceneEl.camera.el.object3D.position.z) { return; }
|
|
|
|
|
this.audioSync = true;
|
|
|
|
|
this.el.components.song.audio.currentTime = this.first.time;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
generateBeat: function (noteInfo) {
|
|
|
|
|
var color;
|
|
|
|
|
var orientation;
|
|
|
|
|
var el;
|
|
|
|
|
var type = noteInfo._cutDirection === 8 ? 'dot' : 'arrow';
|
|
|
|
|
color = noteInfo._type === 0 ? 'red' : 'blue';
|
|
|
|
|
if (noteInfo._type === 3) {
|
|
|
|
|
type = 'mine';
|
|
|
|
|
color = undefined;
|
|
|
|
|
}
|
|
|
|
|
el = this.requestBeat(type, color);
|
|
|
|
|
if (!el) { return; }
|
|
|
|
|
el.setAttribute('beat', {
|
|
|
|
|
color: color,
|
|
|
|
|
type: type,
|
|
|
|
|
speed: this.data.beatSpeed});
|
|
|
|
|
el.object3D.position.set(
|
|
|
|
|
this.horizontalPositions[noteInfo._lineIndex],
|
|
|
|
|
this.verticalPositions[noteInfo._lineLayer],
|
|
|
|
|
-this.data.beatAnticipationTime * this.data.beatSpeed
|
|
|
|
|
);
|
|
|
|
|
el.setAttribute('rotation', {x: 0, y: 0, z: this.orientations[noteInfo._cutDirection]});
|
|
|
|
|
el.play();
|
|
|
|
|
|
|
|
|
|
if (this.first) { return; }
|
|
|
|
|
this.first = {
|
|
|
|
|
el: el,
|
|
|
|
|
time: noteInfo._time
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// generateWall: function (wallInfo) {
|
|
|
|
|
// var el = this.el.sceneEl.components.pool__wall.requestEntity();
|
|
|
|
|
// var speed = this.data.beatSpeed;
|
|
|
|
|
// var durationMs;
|
|
|
|
|
// if (!el) { return; }
|
|
|
|
|
// durationSeconds = 60 * (wallInfo._duration / this.bpm);
|
|
|
|
|
// el.setAttribute('wall', {
|
|
|
|
|
// speed: speed
|
|
|
|
|
// });
|
|
|
|
|
// el.object3D.position.set(
|
|
|
|
|
// this.horizontalPositions[wallInfo._lineIndex],
|
|
|
|
|
// 1.30,
|
|
|
|
|
// -(this.data.beatAnticipationTime * speed)
|
|
|
|
|
// );
|
|
|
|
|
// el.object3D.scale.set(wallInfo._width * 0.30, 2.5, durationSeconds * speed);
|
|
|
|
|
// el.play();
|
|
|
|
|
// if (this.first) { return; }
|
|
|
|
|
// this.first = {
|
|
|
|
|
// el: el,
|
|
|
|
|
// time: wallInfo._time
|
|
|
|
|
// };
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
|
|
requestBeat: function (type, color) {
|
|
|
|
|
var beatPoolName = 'pool__beat-' + type;
|
|
|
|
|
var pool;
|
|
|
|
|
if (color) {beatPoolName += '-' + color; }
|
|
|
|
|
pool = this.el.sceneEl.components[beatPoolName];
|
|
|
|
|
if (!pool) {
|
|
|
|
|
console.warn('Poo ' + beatPoolName + ' unavailable');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return pool.requestEntity();
|
|
|
|
|
}
|
2018-07-20 09:34:52 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function updateQueryParam(uri, key, value) {
|
|
|
|
|
var re = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
|
|
|
|
|
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
|
|
|
|
|
if (uri.match(re)) {
|
|
|
|
|
return uri.replace(re, '$1' + key + '=' + value + '$2');
|
|
|
|
|
} else {
|
|
|
|
|
return uri + separator + key + '=' + value;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-10-01 17:37:11 -07:00
|
|
|
|
|
|
|
|
|