Move beat positioning logic to beat component. Clean up

This commit is contained in:
Diego Marcos
2018-10-31 17:53:32 -07:00
parent 119979fce4
commit 5c7758a25e
2 changed files with 104 additions and 57 deletions

View File

@@ -1,3 +1,4 @@
import {BEAT_WARMUP_OFFSET, BEAT_WARMUP_SPEED, BEAT_WARMUP_TIME} from '../constants/beat';
import utils from '../utils';
/**
@@ -8,26 +9,40 @@ AFRAME.registerComponent('beat-loader', {
schema: {
beatAnticipationTime: {default: 2.0},
beatSpeed: {default: 4.0},
beatWarmupTime: {default: BEAT_WARMUP_TIME / 1000},
beatWarmupSpeed: {default: BEAT_WARMUP_SPEED},
challengeId: {type: 'string'}, // If clicked play.
difficulty: {type: 'string'},
isPlaying: {default: false},
menuSelectedChallengeId: {type: 'string'} // If menu selected.
},
orientations: [180, 0, 270, 90, 225, 135, 315, 45, 0],
orientationsHumanized: {
0: 'down',
45: 'downright',
90: 'right',
135: 'upright',
180: 'up',
225: 'upleft',
270: 'left',
315: 'downleft'
0: 'up',
1: 'down',
2: 'left',
3: 'right',
4: 'upleft',
5: 'upright',
6: 'downleft',
7: 'downright'
},
horizontalPositions: [-0.60, -0.25, 0.25, 0.60],
verticalPositions: [1.00, 1.35, 1.70],
horizontalPositions: [-0.60, -0.25, 0.25, 0.60],
horizontalPositionsHumanized: {
0: 'left',
1: 'middleleft',
2: 'middleright',
3: 'right'
},
verticalPositionsHumanized: {
0: 'bottom',
1: 'middle',
2: 'top'
},
init: function () {
this.audioAnalyserEl = document.getElementById('audioanalyser');
this.beatData = null;
@@ -39,7 +54,6 @@ AFRAME.registerComponent('beat-loader', {
this.songCurrentTime = undefined;
this.onKeyDown = this.onKeyDown.bind(this);
this.xhr = null;
this.stageColors = this.el.components['stage-colors'];
this.twister = document.getElementById('twister');
this.leftStageLasers = document.getElementById('leftStageLasers');
@@ -107,7 +121,7 @@ AFRAME.registerComponent('beat-loader', {
processBeats: function () {
// Reset variables used during playback.
// Beats spawn ahead of the song and get to the user in sync with the music.
this.beatsTimeOffset = this.data.beatAnticipationTime * 1000;
this.beatsTimeOffset = (this.data.beatAnticipationTime + this.data.beatWarmupTime) * 1000;
this.beatsTime = 0;
this.beatData._events.sort(lessThan);
this.beatData._obstacles.sort(lessThan);
@@ -130,54 +144,45 @@ AFRAME.registerComponent('beat-loader', {
* Generate beats and stuff according to timestamp.
*/
tick: function (time, delta) {
var bpm;
var i;
var notes;
var obstacles;
var beatsTime = this.beatsTime;
var msPerBeat;
var noteTime;
if (!this.data.isPlaying || !this.data.challengeId || !this.beatData) { return; }
// Re-sync song with beats playback.
const songComponent = this.el.components.song;
const currentTime = songComponent.getCurrentTime();
if (songComponent.songStartTime && this.beatsTimeOffset !== undefined &&
this.songCurrentTime !== currentTime) {
this.songCurrentTime = currentTime;
this.beatsTime = (this.songCurrentTime + this.data.beatAnticipationTime) * 1000;
if (this.beatsTimeOffset !== undefined && this.songCurrentTime !== this.el.components.song.context.currentTime) {
this.songCurrentTime = this.el.components.song.context.currentTime;
this.beatsTime = (this.songCurrentTime + this.data.beatAnticipationTime + this.data.beatWarmupTime) * 1000;
}
const beatsTime = this.beatsTime;
const bpm = this.beatData._beatsPerMinute;
const msPerBeat = 1000 * 60 / this.beatData._beatsPerMinute;
const notes = this.beatData._notes;
notes = this.beatData._notes;
obstacles = this.beatData._obstacles;
bpm = this.beatData._beatsPerMinute;
msPerBeat = 1000 * 60 / this.beatData._beatsPerMinute;
for (i = 0; i < notes.length; ++i) {
noteTime = notes[i]._time * msPerBeat;
if (noteTime > beatsTime &&
noteTime <= (beatsTime + delta)) {
if (noteTime > beatsTime && noteTime <= beatsTime + delta) {
notes[i].time = noteTime;
this.generateBeat(notes[i]);
}
}
const obstacles = this.beatData._obstacles;
for (i = 0; i < obstacles.length; ++i) {
for (i=0; i < obstacles.length; ++i) {
noteTime = obstacles[i]._time * msPerBeat;
if (noteTime > beatsTime && noteTime <= beatsTime + delta) {
this.generateWall(obstacles[i]);
}
}
const events = this.beatData._events;
for (i=0; i < events.length; ++i) {
noteTime = events[i]._time * msPerBeat;
if (noteTime > beatsTime && noteTime <= beatsTime + delta) {
this.generateEvent(events[i]);
}
}
if (this.beatsTimeOffset !== undefined) {
if (this.beatsTimeOffset <= 0) {
this.el.sceneEl.emit('beatloaderpreloadfinish', null, false);
this.songCurrentTime = songComponent.getCurrentTime();
this.songCurrentTime = this.el.components.song.context.currentTime;
this.beatsTimeOffset = undefined;
} else {
this.beatsTimeOffset -= delta;
@@ -195,6 +200,7 @@ AFRAME.registerComponent('beat-loader', {
return function (noteInfo) {
var beatEl;
var color;
const data = this.data;
// if (Math.random() < 0.8) noteInfo._type = 3; // just to DEBUG MINES!
@@ -205,22 +211,21 @@ AFRAME.registerComponent('beat-loader', {
type = 'mine';
color = undefined;
}
beatEl = this.requestBeat(type, color);
if (!beatEl) { return; }
// Apply sword offset. Blocks arrive on beat in front of the user.
beatObj.anticipationPosition = -data.beatAnticipationTime * data.beatSpeed - swordOffset;
beatObj.color = color;
beatObj.cutDirection =
this.orientationsHumanized[this.orientations[noteInfo._cutDirection]];
beatObj.cutDirection = this.orientationsHumanized[noteInfo._cutDirection];
beatObj.horizontalPosition = this.horizontalPositionsHumanized[noteInfo._lineIndex];
beatObj.speed = this.data.beatSpeed;
beatObj.type = type;
beatObj.verticalPosition = this.verticalPositionsHumanized[noteInfo._lineLayer],
beatObj.warmupPosition = -data.beatWarmupTime * data.beatWarmupSpeed;
beatEl.setAttribute('beat', beatObj);
beatEl.object3D.position.set(
this.horizontalPositions[noteInfo._lineIndex],
this.verticalPositions[noteInfo._lineLayer],
-this.data.beatAnticipationTime * this.data.beatSpeed - swordOffset
);
beatEl.object3D.rotation.z = THREE.Math.degToRad(
this.orientations[noteInfo._cutDirection]);
beatEl.components.beat.updatePosition();
beatEl.play();
beatEl.components.beat.onGenerate();
@@ -229,6 +234,7 @@ AFRAME.registerComponent('beat-loader', {
generateWall: function (wallInfo) {
var el = this.el.sceneEl.components.pool__wall.requestEntity();
const data = this.data;
var speed = this.data.beatSpeed;
if (!el) { return; }
@@ -301,7 +307,7 @@ AFRAME.registerComponent('beat-loader', {
*/
clearBeats: function () {
this.beatsTime = 0;
this.beatsTimeOffset = this.data.beatAnticipationTime * 1000;
this.beatsTimeOffset = (this.data.beatAnticipationTime + this.data.beatWarmupTime) * 1000;
for (let i = 0; i < this.beatContainer.children.length; i++) {
let child = this.beatContainer.children[i];
if (child.components.beat) {

View File

@@ -12,12 +12,16 @@ const SIGN_MATERIAL = {shader: 'flat', color: '#88f'};
*/
AFRAME.registerComponent('beat', {
schema: {
warmupPosition: {default: 0},
anticipationPosition: {default: 0},
color: {default: 'red', oneOf: ['red', 'blue']},
cutDirection: {type: 'string'},
cutDirection: {default: 'down'},
debug: {default: false},
horizontalPosition: {default: 'middleleft', oneOf: ['left', 'middleleft', 'middleright', 'right']},
size: {default: 0.30},
speed: {default: 1.0},
type: {default: 'arrow', oneOf: ['arrow', 'dot', 'mine']}
type: {default: 'arrow', oneOf: ['arrow', 'dot', 'mine']},
verticalPosition: {default: 'middle', oneOf: ['bottom', 'middle', 'top']}
},
materialColor: {
@@ -41,6 +45,32 @@ AFRAME.registerComponent('beat', {
dot: 'dotObjTemplate'
},
orientations: [180, 0, 270, 90, 225, 135, 315, 45, 0],
rotations: {
'up': 180,
'down': 0,
'left': 270,
'right': 90,
'upleft': 225,
'upright': 135,
'downleft': 315,
'downright': 45
},
horizontalPositions: {
'left': -0.60,
'middleleft': -0.25,
'middleright': 0.25,
'right': 0.60
},
verticalPositions: {
'bottom': 1.00,
'middle': 1.35,
'top': 1.70
},
init: function () {
this.backToPool = false;
this.beams = document.getElementById('beams').components.beams;
@@ -87,7 +117,21 @@ AFRAME.registerComponent('beat', {
};
},
updatePosition: function () {
const el = this.el;
const data = this.data;
el.object3D.position.set(
this.horizontalPositions[data.horizontalPosition],
this.verticalPositions[data.verticalPosition],
data.anticipationPosition + data.warmupPosition
);
el.object3D.rotation.z = THREE.Math.degToRad(this.rotations[data.cutDirection]);
},
update: function () {
this.updatePosition();
this.updateBlock();
this.updateFragments();
@@ -114,6 +158,7 @@ AFRAME.registerComponent('beat', {
tock: function (time, timeDelta) {
const el = this.el;
const data = this.data;
const position = el.object3D.position;
const rotation = el.object3D.rotation;
@@ -126,14 +171,14 @@ AFRAME.registerComponent('beat', {
if (position.z > collisionZThreshold) { this.checkCollisions(); }
// Move.
if (position.z < this.startPositionZ) {
if (position.z < data.anticipationPosition) {
let newPositionZ = position.z + BEAT_WARMUP_SPEED * (timeDelta / 1000);
// Warm up / warp in.
if (newPositionZ < this.startPositionZ) {
if (newPositionZ < data.warmupPosition) {
this.beams.newBeam(this.data.color, position);
position.z = newPositionZ;
} else {
position.z = this.startPositionZ;
position.z = data.anticipationPosition;
}
} else {
// Standard moving.
@@ -141,7 +186,7 @@ AFRAME.registerComponent('beat', {
rotation.z = this.startRotationZ;
}
if (position.z > (this.startPositionZ - BEAT_WARMUP_ROTATION_OFFSET) &&
if (position.z > (data.anticipationPosition - BEAT_WARMUP_ROTATION_OFFSET) &&
this.currentRotationWarmupTime < BEAT_WARMUP_ROTATION_TIME) {
const progress = AFRAME.ANIME.easings.easeOutBack(
this.currentRotationWarmupTime / BEAT_WARMUP_ROTATION_TIME);
@@ -160,18 +205,14 @@ AFRAME.registerComponent('beat', {
* Called when summoned by beat-loader.
*/
onGenerate: function () {
this.startPositionZ = this.el.object3D.position.z;
this.startRotationZ = this.el.object3D.rotation.z;
this.el.object3D.position.z -= BEAT_WARMUP_OFFSET;
// Set up rotation warmup.
this.currentRotationWarmupTime = 0;
this.rotationZChange = BEAT_WARMUP_ROTATION_CHANGE;
if (Math.random > 0.5) { this.rotationZChange *= -1; }
this.el.object3D.rotation.z -= this.rotationZChange;
this.rotationZStart = this.el.object3D.rotation.z;
// Reset mine.
if (this.data.type == 'mine') { this.resetMineFragments(); }
},