diff --git a/assets/img/atlas-guide.png b/assets/img/atlas-guide.png index b327d12..f82cec4 100644 Binary files a/assets/img/atlas-guide.png and b/assets/img/atlas-guide.png differ diff --git a/assets/img/atlas.png b/assets/img/atlas.png index d14c90a..44e349d 100644 Binary files a/assets/img/atlas.png and b/assets/img/atlas.png differ diff --git a/assets/img/play.png b/assets/img/play.png index bc4d878..f90bdba 100755 Binary files a/assets/img/play.png and b/assets/img/play.png differ diff --git a/assets/img/slicebtn.png b/assets/img/slicebtn.png index 6bb6553..dc53ade 100755 Binary files a/assets/img/slicebtn.png and b/assets/img/slicebtn.png differ diff --git a/assets/models/stageadditive.obj b/assets/models/stageadditive.obj index 342d810..6184391 100644 --- a/assets/models/stageadditive.obj +++ b/assets/models/stageadditive.obj @@ -222,3 +222,25 @@ f 78/73 74/75 76/83 f 75/76 77/74 78/73 f 80/78 84/80 82/84 f 83/79 81/82 84/80 +v -2.335000 1.285000 -4.010000 +v -1.285000 1.285000 -4.010000 +v -2.335000 1.735000 -4.010000 +v -1.285000 1.735000 -4.010000 +vt 0.875776 0.376339 +vt 0.906624 0.499321 +vt 0.875776 0.499321 +vt 0.906624 0.376339 +s off +f 86/85 87/86 85/87 +f 86/85 88/88 87/86 +v 1.621500 1.202500 -4.013000 +v 1.978500 1.202500 -4.013000 +v 1.621500 1.577500 -4.013000 +v 1.978500 1.577500 -4.013000 +vt 0.875776 0.376339 +vt 0.906624 0.499321 +vt 0.875776 0.499321 +vt 0.906624 0.376339 +s off +f 90/89 91/90 89/91 +f 90/89 92/92 91/90 diff --git a/assets/models/textglow.obj b/assets/models/textglow.obj new file mode 100644 index 0000000..b7bbd95 --- /dev/null +++ b/assets/models/textglow.obj @@ -0,0 +1,13 @@ +# Blender v2.79 (sub 0) OBJ File: 'stage.blend' +# www.blender.org +v -0.150000 -0.150000 0.000000 +v 0.150000 -0.150000 0.000000 +v -0.150000 0.150000 -0.000000 +v 0.150000 0.150000 -0.000000 +vt 0.875776 0.376339 +vt 0.906624 0.499321 +vt 0.875776 0.499321 +vt 0.906624 0.376339 +s off +f 2/1 3/2 1/3 +f 2/1 4/4 3/2 diff --git a/assets/shaders/stageAdditive.js b/assets/shaders/stageAdditive.js deleted file mode 100644 index 5a5a124..0000000 --- a/assets/shaders/stageAdditive.js +++ /dev/null @@ -1,45 +0,0 @@ -module.exports = { - vertexShader : ` - varying vec2 uvs; - varying vec3 worldPos; - void main() { - uvs.xy = uv.xy; - vec4 p = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - worldPos = (modelMatrix * vec4( position, 1.0 )).xyz; - gl_Position = p; - } - `, - - fragmentShader: ` - varying vec2 uvs; - varying vec3 worldPos; - uniform vec3 tunnelNeon; - uniform vec3 leftLaser; - uniform vec3 rightLaser; - uniform vec3 floorNeon; - uniform sampler2D src; - - void main() { - float mask; - vec4 col = texture2D(src, uvs); - - // tunnel neon - mask = step(0.87, uvs.x) * step(0.5, uvs.y) * (1.0 - step(0.935, uvs.x)) * ( 1.0 - step(0.75, uvs.y)); - col.xyz = mix(col.xyz, col.xyz * tunnelNeon, mask); - - // floor & corridor neons - mask = step(0.935, uvs.x) * step(0.5, uvs.y) * ( 1.0 - step(0.75, uvs.y)); - col.xyz = mix(col.xyz, col.xyz * floorNeon, mask); - - // left laser - mask = step(0.5, uvs.x) * (1.0 - step(0.625, uvs.x)) * (1.0 - step(0.5, uvs.y)); - col.xyz = mix(col.xyz, col.xyz * leftLaser, mask); - - // right laser - mask = step(0.625, uvs.x) * (1.0 - step(0.75, uvs.x)) * (1.0 - step(0.5, uvs.y)); - col.xyz = mix(col.xyz, col.xyz * rightLaser, mask); - - gl_FragColor = col; - } - ` -}; diff --git a/src/assets.html b/src/assets.html index d70a84b..3b1e1fb 100644 --- a/src/assets.html +++ b/src/assets.html @@ -73,7 +73,7 @@ - + @@ -90,7 +90,7 @@ + slice9="src: #slicebtnImg; color: #999; width: 1; right: 52; bottom: 47; left: 77; top: 73; height: 0.22; padding: 0.1" + animation__mouseenter1="property: components.slice9.material.color; type: color; from: #CCC; to: #FFF; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150" + animation__mouseleave1="property: components.slice9.material.color; type: color; from: #FFF; to: #CCC; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150" + animation__mouseenter2="property: scale; from: 1 1 1; to: 1.04 1.04 1.04; startEvents: mouseenter; pauseEvents: mouseleave; dur: 80" + animation__mouseleave2="property: scale; to: 1 1 1; from: 1.04 1.04 1.04; startEvents: mouseleave; pauseEvents: mouseenter; dur: 80"> @@ -189,3 +189,10 @@ animation__rightlasercolorred="isRawProperty: true; property: systems.materials.stageAdditive.uniforms.rightLaser.value; type: color; to: {{ COLORS.NEON_RED }}; dur: 5; easing: linear; startEvents: rightlasercolorred" animation__rightlasercolorredfade="isRawProperty: true; property: systems.materials.stageAdditive.uniforms.rightLaser.value; type: color; from: {{ COLORS.NEON_BRIGHTRED }}; to: {{ COLORS.NEON_RED }}; dur: 500; easing: linear; startEvents: rightlasercolorredfade" > + + + diff --git a/src/components/beat.js b/src/components/beat.js deleted file mode 100644 index 08550c7..0000000 --- a/src/components/beat.js +++ /dev/null @@ -1,855 +0,0 @@ -import {BEAT_WARMUP_OFFSET, BEAT_WARMUP_SPEED, BEAT_WARMUP_TIME} from '../constants/beat'; - -const auxObj3D = new THREE.Object3D(); -const collisionZThreshold = -1.65; -const BEAT_WARMUP_ROTATION_CHANGE = Math.PI / 5; -const BEAT_WARMUP_ROTATION_OFFSET = 0.4; -const BEAT_WARMUP_ROTATION_TIME = 750; -const ONCE = {once: true}; - -const SCORE_POOL = { - OK : 'pool__beatscoreok', - GOOD : 'pool__beatscoregood', - GREAT : 'pool__beatscoregreat', - SUPER : 'pool__beatscoresuper' -}; - -/** - * Bears, beats, Battlestar Galactica. - * Create beat from pool, collision detection, clipping planes, movement, scoring. - */ -AFRAME.registerComponent('beat', { - schema: { - anticipationPosition: {default: 0}, - color: {default: 'red', oneOf: ['red', 'blue']}, - cutDirection: {default: 'down'}, - debug: {default: false}, - horizontalPosition: {default: 'middleleft', oneOf: ['left', 'middleleft', 'middleright', 'right']}, - size: {default: 0.40}, - speed: {default: 1.0}, - type: {default: 'arrow', oneOf: ['arrow', 'dot', 'mine']}, - verticalPosition: {default: 'middle', oneOf: ['bottom', 'middle', 'top']}, - warmupPosition: {default: 0}, - }, - - materialColor: { - blue: '#08083E', - red: '#290404' - }, - - cutColor: { - blue: '#b3dcff', - red: '#ffb3ca' - }, - - models: { - arrow: 'beatObjTemplate', - dot: 'beatObjTemplate', - mine: 'mineObjTemplate' - }, - - signModels: { - arrowred: 'arrowRedObjTemplate', - arrowblue: 'arrowBlueObjTemplate', - dotred: 'dotRedObjTemplate', - dotblue: 'dotBlueObjTemplate' - }, - - 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.75, - middleleft: -0.25, - middleright: 0.25, - right: 0.75 - }, - - verticalPositions: { - bottom: 0.70, - middle: 1.20, - top: 1.70 - }, - - init: function () { - this.backToPool = false; - this.beams = document.getElementById('beams').components.beams; - this.beatBoundingBox = new THREE.Box3(); - this.currentRotationWarmupTime = 0; - this.cutDirection = new THREE.Vector3(); - this.destroyed = false; - this.gravityVelocity = 0; - this.hitEventDetail = {}; - this.hitBoundingBox = new THREE.Box3(); - this.poolName = undefined; - this.returnToPoolTimer = 800; - this.rotationAxis = new THREE.Vector3(); - this.saberEls = this.el.sceneEl.querySelectorAll('[saber-controls]'); - this.scoreEl = null; - this.scoreElTime = undefined; - this.startPositionZ = undefined; - this.rightCutPlanePoints = [ - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3() - ]; - this.leftCutPlanePoints = [ - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3() - ]; - - this.mineParticles = document.getElementById('mineParticles'); - this.wrongElLeft = document.getElementById('wrongLeft'); - this.wrongElRight = document.getElementById('wrongRight'); - this.missElLeft = document.getElementById('missLeft'); - this.missElRight = document.getElementById('missRight'); - this.particles = document.getElementById('saberParticles'); - this.mineParticles = document.getElementById('mineParticles'); - - this.superCuts = document.querySelectorAll('.superCutFx'); - this.superCutIdx = 0; - - this.explodeEventDetail = {position: null, rotation: null}; - this.saberColors = {right: 'blue', left: 'red'}; - - this.onEndStroke = this.onEndStroke.bind(this); - - this.initBlock(); - this.initColliders(); - if (this.data.type === 'mine') { - this.initMineFragments(); - } else { - this.initFragments(); - }; - }, - - 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(); - - if (this.data.type === 'mine') { - this.poolName = `pool__beat-mine`; - } else { - this.poolName = `pool__beat-${this.data.type}-${this.data.color}`; - } - }, - - pause: function () { - this.el.object3D.visible = false; - if (this.data.type !== 'mine') { - this.partLeftEl.object3D.visible = false; - this.partRightEl.object3D.visible = false; - } - }, - - play: function () { - this.blockEl.object3D.visible = true; - this.destroyed = false; - this.el.object3D.visible = true; - }, - - tock: function (time, timeDelta) { - const el = this.el; - const data = this.data; - const position = el.object3D.position; - const rotation = el.object3D.rotation; - - if (this.destroyed) { - this.tockDestroyed(timeDelta); - // Check to remove score entity from pool. - } else { - // Only check collisions when close. - if (position.z > collisionZThreshold) { this.checkCollisions(); } - - // Move. - if (position.z < data.anticipationPosition) { - let newPositionZ = position.z + BEAT_WARMUP_SPEED * (timeDelta / 1000); - // Warm up / warp in. - if (newPositionZ < data.anticipationPosition) { - position.z = newPositionZ; - } else { - position.z = data.anticipationPosition; - this.beams.newBeam(this.data.color, position); - } - } else { - // Standard moving. - position.z += this.data.speed * (timeDelta / 1000); - rotation.z = this.startRotationZ; - } - - 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); - el.object3D.rotation.z = this.rotationZStart + (progress * this.rotationZChange); - this.currentRotationWarmupTime += timeDelta; - } - - // Check. - this.backToPool = position.z >= 2; - if (this.backToPool) { this.missHit(); } - } - this.returnToPool(); - }, - - /** - * Called when summoned by beat-loader. - */ - onGenerate: function () { - this.startRotationZ = this.el.object3D.rotation.z; - - // 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(); } - }, - - initBlock: function () { - var el = this.el; - var blockEl = this.blockEl = document.createElement('a-entity'); - var signEl = this.signEl = document.createElement('a-entity'); - - blockEl.setAttribute('mixin', 'beatBlock'); - blockEl.setAttribute('mixin', 'beatSign'); - - // Small offset to prevent z-fighting when the blocks are far away - signEl.object3D.position.z += 0.02; - blockEl.appendChild(signEl); - el.appendChild(blockEl); - }, - - updateBlock: function () { - const blockEl = this.blockEl; - const signEl = this.signEl; - if (!blockEl) { return; } - - blockEl.setAttribute('material', { - metalness: 0.9, - roughness: 0.10, - sphericalEnvMap: '#envmapTexture', - color: this.materialColor[this.data.color] - }); - this.setObjModelFromTemplate(blockEl, this.models[this.data.type]); - - // Model is 0.29 size. We make it 1.0 so we can easily scale based on 1m size. - blockEl.object3D.scale.set(1, 1, 1); - blockEl.object3D.scale.multiplyScalar(3.45).multiplyScalar(this.data.size); - - if (this.data.type === 'mine') { - const model = blockEl.getObject3D('mesh'); - if (model) { - model.material = this.el.sceneEl.components['stage-colors'].mineMaterial; - } else { - blockEl.addEventListener('model-loaded', () => { - model.material = this.el.sceneEl.components['stage-colors'].mineMaterial; - }, ONCE); - } - } else { - signEl.setAttribute('materials', {name: 'stageAdditive'}); - this.setObjModelFromTemplate(signEl, this.signModels[this.data.type + this.data.color]); - } - }, - - initColliders: function () { - var data = this.data; - var hitColliderConfiguration; - var hitColliderEl; - - if (this.data.type === 'dot' || this.data.type === 'mine') { return; } - - // Hit colliders are 40% larger than the block. - hitColliderConfiguration = { - position: {x: 0, y: data.size / 2, z: 0}, - size: {width: data.size * 1.4, height: data.size / 3.0, depth: data.size* 1.4} - }; - - hitColliderEl = this.hitColliderEl = document.createElement('a-entity'); - hitColliderEl.setAttribute('geometry', { - primitive: 'box', - height: hitColliderConfiguration.size.height, - width: hitColliderConfiguration.size.width, - depth: hitColliderConfiguration.size.depth - }); - - hitColliderEl.object3D.position.copy(hitColliderConfiguration.position); - hitColliderEl.object3D.visible = false; - this.el.appendChild(hitColliderEl); - - if (data.debug) { - hitColliderEl.object3D.visible = true; - hitColliderEl.setAttribute('material', 'color', 'purple'); - } - }, - - initFragments: function () { - var cutEl; - var partEl; - - partEl = this.partLeftEl = document.createElement('a-entity'); - cutEl = this.cutLeftEl = document.createElement('a-entity'); - - partEl.appendChild(cutEl); - this.el.appendChild(partEl); - - partEl = this.partRightEl = document.createElement('a-entity'); - cutEl = this.cutRightEl = document.createElement('a-entity'); - - partEl.appendChild(cutEl); - this.el.appendChild(partEl); - - this.initCuttingClippingPlanes(); - }, - - initMineFragments: function () { - var fragment; - var fragments = this.el.sceneEl.systems['mine-fragments-loader'].fragments.children; - var material = this.el.sceneEl.components['stage-colors'].mineMaterial; - - this.randVec = new THREE.Vector3( - Math.random() * Math.PI, - Math.random() * Math.PI, - Math.random() * Math.PI); - - this.mineFragments = []; - this.mineBroken = document.createElement('a-entity'); - this.el.appendChild(this.mineBroken); - - for (var i = 0; i < fragments.length; i++) { - fragment = new THREE.Mesh(fragments[i].geometry, material); - fragment.speed = new THREE.Vector3(); - fragment.speed.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5); - this.mineFragments.push(fragment); - this.mineBroken.object3D.add(fragment); - } - }, - - updateFragments: function () { - var cutLeftEl = this.cutLeftEl; - var cutRightEl = this.cutRightEl; - var partLeftEl = this.partLeftEl; - var partRightEl = this.partRightEl; - var fragment; - if (!partLeftEl) { return; } - if (this.data.type === 'mine') { - this.resetMineFragments(); - return; - } - - partLeftEl.setAttribute('material', { - metalness: 0.8, - roughness: 0.12, - sphericalEnvMap: '#envmapTexture', - color: this.materialColor[this.data.color], - side: 'double' - }); - this.setObjModelFromTemplate(partLeftEl, this.models.dot); - partLeftEl.object3D.visible = false; - - cutLeftEl.setAttribute('material', { - shader: 'flat', - color: this.data.cutColor, - side: 'double' - }); - this.setObjModelFromTemplate(cutLeftEl, this.models.dot); - - partRightEl.setAttribute('material', { - metalness: 0.8, - roughness: 0.12, - sphericalEnvMap: '#envmapTexture', - color: this.materialColor[this.data.color], - side: 'double' - }); - this.setObjModelFromTemplate(partRightEl, this.models.dot); - partRightEl.object3D.visible = false; - - cutRightEl.setAttribute('material', { - shader: 'flat', - color: this.data.cutColor, - side: 'double' - }); - this.setObjModelFromTemplate(cutRightEl, this.models.dot); - }, - - resetMineFragments: function () { - if (this.data.type !== 'mine') { return; } - for (let i = 0; i < this.mineFragments.length; i++) { - let fragment = this.mineFragments[i]; - fragment.visible = false; - fragment.position.set(0, 0, 0); - fragment.scale.set(1, 1, 1); - fragment.speed.set( - Math.random() * 5 - 2.5, - Math.random() * 5 - 2.5, - Math.random() * 5 - 2.5); - } - }, - - wrongHit: function (hand) { - var wrongEl = hand === 'left' ? this.wrongElLeft : this.wrongElRight; - if (!wrongEl) { return; } - wrongEl.object3D.position.copy(this.el.object3D.position); - wrongEl.object3D.position.y += 0.2; - wrongEl.object3D.position.z -= 0.5; - wrongEl.object3D.visible = true; - wrongEl.emit('beatwrong', null, true); - this.destroyed = true; - }, - - missHit: function (hand) { - var missEl = hand === 'left' ? this.missElLeft : this.missElRight; - if (!missEl || this.data.type === 'mine') { return; } - missEl.object3D.position.copy(this.el.object3D.position); - missEl.object3D.position.y += 0.2; - missEl.object3D.position.z -= 0.5; - missEl.object3D.visible = true; - missEl.emit('beatmiss', null, true); - if (AFRAME.utils.getUrlParameter('synctest')) { - console.log(this.el.sceneEl.components.song.getCurrentTime()); - } - }, - - destroyBeat: (function () { - var parallelPlaneMaterial = new THREE.MeshBasicMaterial({ - color: '#00008b', - side: THREE.DoubleSide - }); - var planeMaterial = new THREE.MeshBasicMaterial({color: 'grey', side: THREE.DoubleSide}); - var point1 = new THREE.Vector3(); - var point2 = new THREE.Vector3(); - var point3 = new THREE.Vector3(); - - return function (saberEl) { - var coplanarPoint; - var cutThickness = this.cutThickness = 0.02; - var direction = this.cutDirection; - var leftBorderInnerPlane = this.leftBorderInnerPlane; - var leftBorderOuterPlane = this.leftBorderOuterPlane; - var leftCutPlane = this.leftCutPlane; - var planeGeometry; - var planeMesh; - var rightBorderInnerPlane = this.rightBorderInnerPlane; - var rightBorderOuterPlane = this.rightBorderOuterPlane; - var rightCutPlane = this.rightCutPlane; - var trailPoints = saberEl.components.trail.saberTrajectory; - - point1.copy(trailPoints[0].top); - point2.copy(trailPoints[0].center); - point3.copy(trailPoints[trailPoints.length - 1].top); - direction.copy(point1).sub(point3); - - this.partRightEl.object3D.position.set(0, 0, 0); - this.partRightEl.object3D.rotation.set(0, 0, 0); - this.partRightEl.object3D.updateMatrixWorld(); - - this.partRightEl.object3D.worldToLocal(this.rightCutPlanePoints[0].copy(point1)); - this.partRightEl.object3D.worldToLocal(this.rightCutPlanePoints[1].copy(point2)); - this.partRightEl.object3D.worldToLocal(this.rightCutPlanePoints[2].copy(point3)); - - this.partLeftEl.object3D.position.set(0, 0, 0); - this.partLeftEl.object3D.rotation.set(0, 0, 0); - this.partLeftEl.object3D.updateMatrixWorld(); - - this.partLeftEl.object3D.worldToLocal(this.leftCutPlanePoints[0].copy(point3)); - this.partLeftEl.object3D.worldToLocal(this.leftCutPlanePoints[1].copy(point2)); - this.partLeftEl.object3D.worldToLocal(this.leftCutPlanePoints[2].copy(point1)); - - this.generateCutClippingPlanes(); - - if (this.data.debug) { - coplanarPoint = new THREE.Vector3(); - planeGeometry = new THREE.PlaneGeometry(4.0, 4.0, 1.0, 1.0); - - rightCutPlane.coplanarPoint(coplanarPoint); - planeGeometry.lookAt(rightCutPlane.normal); - planeGeometry.translate(coplanarPoint.x, coplanarPoint.y, coplanarPoint.z); - - planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); - this.el.sceneEl.setObject3D('rightCutPlane', planeMesh); - - planeGeometry = new THREE.PlaneGeometry(4.0, 4.0, 1.0, 1.0); - - rightBorderOuterPlane.coplanarPoint(coplanarPoint); - planeGeometry.lookAt(rightBorderOuterPlane.normal); - planeGeometry.translate(coplanarPoint.x, coplanarPoint.y, coplanarPoint.z); - - const parallelPlaneMesh = new THREE.Mesh(planeGeometry, parallelPlaneMaterial); - this.el.sceneEl.setObject3D('planeParallel', parallelPlaneMesh); - } - - this.blockEl.object3D.visible = false; - - const partRightMaterial = this.partRightEl.getObject3D('mesh').material; - partRightMaterial.clippingPlanes = partRightMaterial.clippingPlanes || []; - partRightMaterial.clippingPlanes.length = 0; - partRightMaterial.clippingPlanes.push(rightCutPlane); - - const cutRightMaterial = this.cutRightEl.getObject3D('mesh').material; - cutRightMaterial.clippingPlanes = cutRightMaterial.clippingPlanes || []; - cutRightMaterial.clippingPlanes.length = 0; - cutRightMaterial.clippingPlanes.push(rightBorderOuterPlane); - cutRightMaterial.clippingPlanes.push(rightBorderInnerPlane); - - const partLeftMaterial = this.partLeftEl.getObject3D('mesh').material; - partLeftMaterial.clippingPlanes = partLeftMaterial.clippingPlanes || []; - partLeftMaterial.clippingPlanes.length = 0; - partLeftMaterial.clippingPlanes.push(leftCutPlane); - - const cutLeftMaterial = this.cutLeftEl.getObject3D('mesh').material; - cutLeftMaterial.clippingPlanes = cutLeftMaterial.clippingPlanes || []; - cutLeftMaterial.clippingPlanes.length = 0; - cutLeftMaterial.clippingPlanes.push(leftBorderInnerPlane); - cutLeftMaterial.clippingPlanes.push(leftBorderOuterPlane); - - this.partLeftEl.object3D.visible = true; - this.partRightEl.object3D.visible = true; - - this.el.sceneEl.renderer.localClippingEnabled = true; - this.destroyed = true; - this.gravityVelocity = 0.1; - - this.rotationAxis.copy(this.rightCutPlanePoints[0]).sub(this.rightCutPlanePoints[1]); - - this.returnToPoolTimer = 800; - - auxObj3D.up.copy(rightCutPlane.normal); - auxObj3D.lookAt(direction); - this.explodeEventDetail.position = this.el.object3D.position; - this.explodeEventDetail.rotation = auxObj3D.rotation; - this.particles.emit('explode', this.explodeEventDetail, false); - }; - })(), - - destroyMine: function () { - for (let i = 0; i < this.mineFragments.length; i++) { - this.mineFragments[i].visible = true; - } - - this.blockEl.object3D.visible = false; - this.destroyed = true; - this.gravityVelocity = 0.1; - this.returnToPoolTimer = 800; - - this.explodeEventDetail.position = this.el.object3D.position; - this.explodeEventDetail.rotation = this.randVec; - this.mineParticles.emit('explode', this.explodeEventDetail, false); - }, - - initCuttingClippingPlanes: function () { - this.leftCutPlanePointsWorld = [ - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3() - ]; - this.rightCutPlanePointsWorld = [ - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3() - ]; - - this.rightCutPlane = new THREE.Plane(); - this.rightBorderOuterPlane = new THREE.Plane(); - this.rightBorderInnerPlane = new THREE.Plane(); - - this.leftCutPlane = new THREE.Plane(); - this.leftBorderOuterPlane = new THREE.Plane(); - this.leftBorderInnerPlane = new THREE.Plane(); - }, - - generateCutClippingPlanes: function () { - var leftBorderInnerPlane = this.leftBorderInnerPlane; - var leftBorderOuterPlane = this.leftBorderOuterPlane; - var leftCutPlane = this.leftCutPlane; - var leftCutPlanePointsWorld = this.leftCutPlanePointsWorld; - var partLeftEl = this.partLeftEl; - var partRightEl = this.partRightEl; - var rightBorderInnerPlane = this.rightBorderInnerPlane; - var rightBorderOuterPlane = this.rightBorderOuterPlane; - var rightCutPlane = this.rightCutPlane; - var rightCutPlanePointsWorld = this.rightCutPlanePointsWorld; - - partRightEl.object3D.updateMatrixWorld(); - partRightEl.object3D.localToWorld( - rightCutPlanePointsWorld[0].copy(this.rightCutPlanePoints[0])); - partRightEl.object3D.localToWorld( - rightCutPlanePointsWorld[1].copy(this.rightCutPlanePoints[1])); - partRightEl.object3D.localToWorld( - rightCutPlanePointsWorld[2].copy(this.rightCutPlanePoints[2])); - - partLeftEl.object3D.updateMatrixWorld(); - partLeftEl.object3D.localToWorld( - leftCutPlanePointsWorld[0].copy(this.leftCutPlanePoints[0])); - partLeftEl.object3D.localToWorld( - leftCutPlanePointsWorld[1].copy(this.leftCutPlanePoints[1])); - partLeftEl.object3D.localToWorld( - leftCutPlanePointsWorld[2].copy(this.leftCutPlanePoints[2])); - - rightCutPlane.setFromCoplanarPoints( - rightCutPlanePointsWorld[0], rightCutPlanePointsWorld[1], rightCutPlanePointsWorld[2]); - rightBorderOuterPlane.set(rightCutPlane.normal, - rightCutPlane.constant + this.cutThickness); - - leftCutPlane.setFromCoplanarPoints( - leftCutPlanePointsWorld[0], leftCutPlanePointsWorld[1], leftCutPlanePointsWorld[2]); - leftBorderOuterPlane.set(leftCutPlane.normal, leftCutPlane.constant + this.cutThickness); - - rightBorderInnerPlane.setFromCoplanarPoints( - rightCutPlanePointsWorld[2], rightCutPlanePointsWorld[1], rightCutPlanePointsWorld[0]); - leftBorderInnerPlane.setFromCoplanarPoints( - leftCutPlanePointsWorld[2], leftCutPlanePointsWorld[1], leftCutPlanePointsWorld[0]); - }, - - returnToPool: function (force) { - if (!this.backToPool && !force) { return; } - this.el.sceneEl.components[this.poolName].returnEntity(this.el); - }, - - checkCollisions: function () { - const cutDirection = this.data.cutDirection; - const saberColors = this.saberColors; - const saberEls = this.saberEls; - const hitBoundingBox = this.hitColliderEl && this.hitBoundingBox.setFromObject( - this.hitColliderEl.getObject3D('mesh')); - const beatBoundingBox = this.beatBoundingBox.setFromObject( - this.blockEl.getObject3D('mesh')); - - for (let i = 0; i < saberEls.length; i++) { - let saberBoundingBox = saberEls[i].components['saber-controls'].boundingBox; - let saberControls; - let maxAngle; - - if (!saberBoundingBox) { break; } - - const hand = saberEls[i].getAttribute('saber-controls').hand; - - if (hitBoundingBox && saberBoundingBox.intersectsBox(hitBoundingBox)) { - if (saberEls[i].components['saber-controls'].swinging && - this.data.color === saberColors[hand]) { - saberControls = saberEls[i].components['saber-controls']; - this.hitHand = hand; - this.hitSaberEl = saberEls[i]; - this.hitSaberEl.addEventListener('strokeend', this.onEndStroke, ONCE); - if (cutDirection === 'up' || cutDirection === 'down') { - maxAngle = saberControls.maxAnglePlaneX; - } else if (cutDirection === 'left' || cutDirection === 'right') { - maxAngle = saberControls.maxAnglePlaneY; - } else { - maxAngle = saberControls.maxAnglePlaneXY; - } - this.angleBeforeHit = maxAngle; - saberControls.maxAnglePlaneX = 0; - saberControls.maxAnglePlaneY = 0; - saberControls.maxAnglePlaneXY = 0; - } else { - this.wrongHit(hand); - } - - // Notify for haptics. - this.el.emit(`beatcollide${hand}`, null, true); - - // Sound. - this.el.parentNode.components['beat-hit-sound'].playSound( - this.el, this.data.cutDirection); - - if (this.data.type === 'mine') { - this.destroyMine(); - } else { - this.destroyBeat(saberEls[i]); - } - break; - } - - if (saberBoundingBox.intersectsBox(beatBoundingBox)) { - // Notify for haptics. - this.el.emit(`beatcollide${hand}`, null, true); - - // Sound. - this.el.parentNode.components['beat-hit-sound'].playSound(this.el); - - if (this.data.type === 'mine') { - this.el.emit('minehit', null, true); - this.destroyMine(); - break; - } - - this.destroyBeat(saberEls[i]); - - if (this.data.type === 'dot' && saberEls[i].components['saber-controls'].swinging && - this.data.color === saberColors[hand]) { - this.hitSaberEl = saberEls[i]; - this.hitSaberEl.addEventListener('strokeend', this.onEndStroke, ONCE); - saberControls = saberEls[i].components['saber-controls']; - maxAngle = Math.max(saberControls.maxAnglePlaneX, saberControls.maxAnglePlaneY, - saberControls.maxAnglePlaneXY); - this.hitHand = hand; - this.angleBeforeHit = maxAngle; - saberControls.maxAnglePlaneX = 0; - saberControls.maxAnglePlaneY = 0; - saberControls.maxAnglePlaneXY = 0; - - } else { - this.wrongHit(hand); - } - break; - } - } - }, - - onEndStroke: function () { - var cutDirection = this.data.cutDirection; - var hitEventDetail = this.hitEventDetail; - var maxAngle; - var saberControls = this.hitSaberEl.components['saber-controls']; - var scoreText; - - // Harcoded temporarily. - const saberRotation = 3.14 / 12; - - if (cutDirection === 'up' || cutDirection === 'down') { - maxAngle = saberControls.maxAnglePlaneX; - } else if (cutDirection === 'left' || cutDirection === 'right') { - maxAngle = saberControls.maxAnglePlaneY; - } else { - maxAngle = saberControls.maxAnglePlaneXY; - } - - const angleBeforeHit = Math.max(0, (this.angleBeforeHit - saberRotation) * 180 / Math.PI); - const angleAfterHit = Math.max(0, (maxAngle - saberRotation) * 180 / Math.PI); - - let score = 0; - score += angleBeforeHit >= 85 ? 70 : (angleBeforeHit / 80) * 70; - score += angleAfterHit >= 60 ? 30 : (angleAfterHit / 60) * 30; - - hitEventDetail.score = score; - this.el.emit('beathit', hitEventDetail, true); - - let beatScorePool; - if (score < 60) { beatScorePool = SCORE_POOL.OK; } - else if (score < 80) { beatScorePool = SCORE_POOL.GOOD; } - else if (score < 100) { beatScorePool = SCORE_POOL.GREAT; } - else { - beatScorePool = SCORE_POOL.SUPER; - - this.superCuts[this.superCutIdx].components.supercutfx.createSuperCut(this.el.object3D.position); - this.superCutIdx = (this.superCutIdx + 1) % this.superCuts.length; - } - - const scoreEl = this.el.sceneEl.components[beatScorePool].requestEntity(); - if (scoreEl) { - scoreEl.object3D.position.copy(this.el.object3D.position); - scoreEl.play(); - scoreEl.emit('beatscorestart', null, false); - } - }, - - /** - * Destroyed animation. - */ - tockDestroyed: (function () { - var leftCutNormal = new THREE.Vector3(); - var leftRotation = 0; - var rightCutNormal = new THREE.Vector3(); - var rightRotation = 0; - var rotationStep = 2 * Math.PI / 150; - var fragment; - - return function (timeDelta) { - // Update gravity velocity. - this.gravityVelocity = getGravityVelocity(this.gravityVelocity, timeDelta); - this.el.object3D.position.y += this.gravityVelocity * (timeDelta / 1000); - - if (this.data.type == 'mine') { - for (var i = 0; i < this.mineFragments.length; i++) { - fragment = this.mineFragments[i]; - if (!fragment.visible) { continue; } - fragment.position.addScaledVector(fragment.speed, timeDelta / 1000); - fragment.scale.multiplyScalar(0.97) - if (fragment.scale.y < 0.1){ - fragment.visible = false; - } - } - return; - } - - rightCutNormal.copy(this.rightCutPlane.normal) - .multiplyScalar((this.data.speed / 2) * (timeDelta / 500)); - rightCutNormal.y = 0; // Y handled by gravity. - this.partRightEl.object3D.position.add(rightCutNormal); - this.partRightEl.object3D.setRotationFromAxisAngle(this.rotationAxis, rightRotation); - rightRotation = rightRotation >= 2 * Math.PI ? 0 : rightRotation + rotationStep; - - leftCutNormal.copy(this.leftCutPlane.normal) - .multiplyScalar((this.data.speed / 2) * (timeDelta / 500)); - leftCutNormal.y = 0; // Y handled by gravity. - this.partLeftEl.object3D.position.add(leftCutNormal); - this.partLeftEl.object3D.setRotationFromAxisAngle(this.rotationAxis, leftRotation); - leftRotation = leftRotation >= 2 * Math.PI ? 0 : leftRotation + rotationStep; - - this.generateCutClippingPlanes(); - - this.returnToPoolTimer -= timeDelta; - this.backToPool = this.returnToPoolTimer <= 0; - }; - })(), - - /** - * Load OBJ from already parsed and loaded OBJ template. - */ - setObjModelFromTemplate: (function () { - const geometries = {}; - - return function (el, templateId) { - if (!geometries[templateId]) { - const templateEl = document.getElementById(templateId); - if (templateEl.getObject3D('mesh')) { - geometries[templateId] = templateEl.getObject3D('mesh').children[0].geometry; - } else { - templateEl.addEventListener('model-loaded', () => { - geometries[templateId] = templateEl.getObject3D('mesh').children[0].geometry; - this.setObjModelFromTemplate(el, templateId); - }); - return; - } - } - - if (!el.getObject3D('mesh')) { el.setObject3D('mesh', new THREE.Mesh()); } - el.getObject3D('mesh').geometry = geometries[templateId]; - }; - })() -}); - -/** - * Get velocity given current velocity using gravity acceleration. - */ -function getGravityVelocity (velocity, timeDelta) { - const GRAVITY = -9.8; - return velocity + (GRAVITY * (timeDelta / 1000)); -} diff --git a/src/components/gameover.js b/src/components/gameover.js index 065ec58..9fe7368 100644 --- a/src/components/gameover.js +++ b/src/components/gameover.js @@ -36,5 +36,6 @@ AFRAME.registerComponent('gameover', { for (let i = 0; i < this.gameOverEls.length; i++) { this.gameOverEls[i].emit('gameover', null, false); } + this.el.emit('textglowoff', null, false); } }); diff --git a/src/components/materials.js b/src/components/materials.js index 86b4a6a..69b084b 100644 --- a/src/components/materials.js +++ b/src/components/materials.js @@ -21,6 +21,7 @@ AFRAME.registerSystem('materials', { floorNeon: {value: new THREE.Color(COLORS.NEON_BLUE)}, leftLaser: {value: new THREE.Color(COLORS.NEON_BLUE)}, rightLaser: {value: new THREE.Color(COLORS.NEON_BLUE)}, + textGlow: {value: new THREE.Color(COLORS.TEXT_OFF)}, src: {value: new THREE.TextureLoader().load(document.getElementById('atlasImg').src)}, }, vertexShader: stageAdditiveShaders.vertexShader, diff --git a/src/components/score-texts.js b/src/components/score-texts.js index 171bee7..ad24f6d 100644 --- a/src/components/score-texts.js +++ b/src/components/score-texts.js @@ -28,6 +28,7 @@ AFRAME.registerComponent('score-texts', { for (let i = 0; i < this.textEls.length; i++) { this.textEls[i].components['animation__fadein'].beginAnimation(); } + this.el.sceneEl.emit('textglownormal', null, false); } // Started loading. @@ -35,6 +36,7 @@ AFRAME.registerComponent('score-texts', { for (let i = 0; i < this.textEls.length; i++) { this.textEls[i].components.text.material.uniforms.opacity.value = 0; } + this.el.sceneEl.emit('textglowoff', null, false); } } }); diff --git a/src/components/twister.js b/src/components/twister.js index 00a1f23..025e958 100644 --- a/src/components/twister.js +++ b/src/components/twister.js @@ -19,7 +19,6 @@ AFRAME.registerComponent('twister', { pulse: function (twist) { if (!this.data.enabled) { return; } - console.log('PULSE'); if (twist == 0) { twist = 0.03 + Math.random() * 0.25; } else twist = Math.min(twist * 0.4, 0.4); twist *= Math.random() < 0.5 ? -1 : 1; // random direction diff --git a/src/constants/colors.js b/src/constants/colors.js deleted file mode 100644 index 047ac7f..0000000 --- a/src/constants/colors.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - OFF: '#111', - RED: '#f00', - BLUE: '#00f', - - BG_OFF: '#222', - BG_BLUE: '#007AB8', - BG_BRIGHTBLUE: '#5FCCFF', - BG_RED: '#B80000', - BG_BRIGHTRED: '#FF4343', - - NEON_OFF: '#000', - NEON_BLUE: '#00f', - NEON_BRIGHTBLUE: '#aaf', - NEON_RED: '#f00', - NEON_BRIGHTRED: '#faa', -}; diff --git a/src/templates/gameMenu.html b/src/templates/gameMenu.html index 9f041cd..1fad9c3 100644 --- a/src/templates/gameMenu.html +++ b/src/templates/gameMenu.html @@ -1,6 +1,6 @@ @@ -9,7 +9,7 @@ id="gameMenuButtonText" mixin="font" position="0 -0.07 0.01" - text="align: center; wrapCount: 17; color: #F0F0F0"> + text="align: center; wrapCount: 17; color: #FFF"> diff --git a/src/templates/menu.html b/src/templates/menu.html index f5090b0..3c69a71 100644 --- a/src/templates/menu.html +++ b/src/templates/menu.html @@ -229,13 +229,13 @@ id="playButton" play-sound="event: mouseenter; sound: #hoverSound; volume: 0.03" play-sound__click="event: click; sound: #confirmSound; volume: 0.25" - position="0 -0.51 0" + position="0 -0.561 0" proxy-event="event: click; to: a-scene; as: playbuttonclick" - material="shader: flat; src: #playImg; transparent: true; color: #CCC" - width="0.4" - height="0.2" - animation__mouseenter1="property: components.material.material.color; type: color; from: #CCC; to: #FFF; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150" - animation__mouseleave1="property: components.material.material.color; type: color; from: #FFF; to: #CCC; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150" + material="shader: flat; src: #playImg; transparent: true; color: #DDD" + width="0.5" + height="0.25" + animation__mouseenter1="property: components.material.material.color; type: color; from: #DDD; to: #FFF; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150" + animation__mouseleave1="property: components.material.material.color; type: color; from: #FFF; to: #DDD; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150" animation__mouseenter2="property: scale; from: 1 1 1; to: 1.1 1.1 1.1; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150" animation__mouseleave2="property: scale; to: 1 1 1; from: 1.1 1.1 1.1; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150" bind-toggle__raycastable="menuActive && !!menuSelectedChallenge.id && !genreMenuOpen" @@ -315,7 +315,7 @@ bind-toggle__raycastable="menuActive && !genreMenuOpen && !isSearching && !genre" bind__visible="menuActive && !genreMenuOpen && !isSearching && !genre" proxy-event="event: click; to: a-scene; as: genremenuopen"> - + - + @@ -334,7 +334,7 @@ bind__visible="genreMenuOpen" position="0 0.2 -1.9" proxy-event="event: click; to: a-scene; as: genremenuclose"> - + @@ -343,7 +343,7 @@ bind-toggle__raycastable="menuActive && !genreMenuOpen && !isSearching && !search.query" bind__visible="menuActive && !genreMenuOpen && !isSearching && !search.query" proxy-event="event: click; to: a-scene; as: keyboardopen"> - + - + diff --git a/src/templates/score.html b/src/templates/score.html index 1f4d3dc..05365c8 100644 --- a/src/templates/score.html +++ b/src/templates/score.html @@ -1,7 +1,7 @@ + text="color: #FFF; letterSpacing: -2; align: center">