Created
February 25, 2012 17:05
-
-
Save chandlerprall/1909535 to your computer and use it in GitHub Desktop.
tower source code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| var collisionsound1 = new buzz.sound( "assets/sounds/collision1", { | |
| formats: [ 'wav' ] | |
| }); | |
| collisionsound1.load(); | |
| var collisionsound2 = new buzz.sound( "assets/sounds/collision2", { | |
| formats: [ 'wav' ] | |
| }); | |
| collisionsound2.load(); | |
| var collisionsound3 = new buzz.sound( "assets/sounds/collision3", { | |
| formats: [ 'wav' ] | |
| }); | |
| collisionsound3.load(); | |
| var newGame = function() { | |
| document.getElementById('endgame').style.display = 'none'; | |
| if ( tower ) { | |
| tower.unload(); | |
| } | |
| tower = new Tower(); | |
| tower.handleResize(); | |
| tower.init(); | |
| }; | |
| window['requestAnimFrame'] = (function(){ | |
| return window.requestAnimationFrame || | |
| window.webkitRequestAnimationFrame || | |
| window.mozRequestAnimationFrame || | |
| window.oRequestAnimationFrame || | |
| window.msRequestAnimationFrame || | |
| function(/* function */ callback, /* DOMElement */ element){ | |
| window.setTimeout(callback, 1000 / 60); | |
| }; | |
| })(); | |
| var Tower = function() { | |
| var i; | |
| this.paused = false; | |
| this.pausedtime = null; | |
| this.createBlock = this.createBlock.bind( this ); | |
| this.updateHeight = this.updateHeight.bind( this ); | |
| this.totaltime = 45; | |
| this.starttime = Math.floor(new Date().getTime() / 1000); | |
| this.timeleft = this.totaltime; | |
| this.height = -2; | |
| this.active_block = null; | |
| this.boxes = []; | |
| this.last_manifolds = 0; | |
| this.intervals = []; | |
| this.timeouts = []; | |
| this.timebonuses = [ | |
| { | |
| height: 10, | |
| bonus: 20, | |
| achieved: false, | |
| element: null | |
| }, | |
| { | |
| height: 22, | |
| bonus: 20, | |
| achieved: false, | |
| element: null | |
| }, | |
| { | |
| height: 37, | |
| bonus: 20, | |
| achieved: false, | |
| element: null | |
| }, | |
| { | |
| height: 55, | |
| bonus: 20, | |
| achieved: false, | |
| element: null | |
| } | |
| ]; | |
| for ( i = 0; i < this.timebonuses.length; i++ ) { | |
| this.timebonuses[i].element = document.createElement('div'); | |
| this.timebonuses[i].element.className = 'timebonus'; | |
| if ( i === 0 ) { | |
| this.timebonuses[i].element.style.display = 'block'; | |
| } | |
| document.getElementById('viewport').appendChild( this.timebonuses[i].element ); | |
| } | |
| this.cursor_position = new THREE.Vector2( 0, 10 ); | |
| this.initEvents(); | |
| }; | |
| Tower.prototype.onPopupShowing = function() {}; | |
| Tower.prototype.onPopupShown = function() { | |
| this.handleResize(); | |
| if (!Detector.webgl) { | |
| var nowebgl = document.getElementById('nowebgl'), | |
| content = document.getElementById('content'); | |
| nowebgl.style.display = 'block'; | |
| nowebgl.style.left = this.workarea_size.width / 2 - nowebgl.clientWidth / 2 + 'px'; | |
| nowebgl.style.top = this.workarea_size.height / 2 - nowebgl.clientHeight / 2 + 'px' | |
| } | |
| if ( this.pausedtime ) { | |
| this.paused = false; | |
| this.totaltime += Math.floor(new Date().getTime() / 1000) - this.pausedtime; | |
| this.pausedtime = null; | |
| } | |
| }; | |
| Tower.prototype.onPopupHidden = function() { this.paused = true; this.pausedtime = Math.floor(new Date().getTime() / 1000); }; | |
| Tower.prototype.onPopupUnload = function() {}; | |
| Tower.prototype.init = function() { | |
| this.initGUI(); | |
| this.initThree(); | |
| this.initTextures(); | |
| this.initScene(); | |
| this.start(); | |
| }; | |
| Tower.prototype.showInstructions = function() { | |
| var instructions_panel = document.getElementById('instructions'); | |
| instructions_panel.style.display = 'block'; | |
| instructions_panel.style.left = this.workarea_size.width / 2 - instructions_panel.clientWidth / 2 + 'px'; | |
| instructions_panel.style.top = this.workarea_size.height / 2 - instructions_panel.clientHeight / 2 + 'px'; | |
| this.showPanel( 1 ); | |
| }; | |
| Tower.prototype.showPanel = function( index ) { | |
| var i, panels = document.getElementsByClassName( 'panel' ); | |
| for ( i = 0; i < panels.length; i++ ) { | |
| if ( i === index-1 ) { | |
| panels[i].style.display = 'block'; | |
| } else { | |
| panels[i].style.display = 'none'; | |
| } | |
| } | |
| } | |
| Tower.prototype.endGame = function() { | |
| var dialog = document.getElementById('endgame'); | |
| var response = document.getElementById('endgame_text'); | |
| dialog.style.display = 'block'; | |
| dialog.style.left = this.workarea_size.width / 2 - dialog.clientWidth / 2 + 'px'; | |
| dialog.style.top = this.workarea_size.height / 2 - dialog.clientHeight / 2 + 'px'; | |
| response.innerHTML = [ | |
| 'Oh no, you ran out of time!', | |
| 'Your tower finished at <strong>' + (Math.floor(this.height * 100) / 100) + ' meters</strong> tall.', | |
| ].join('<br />'); | |
| }; | |
| Tower.prototype.to2D = function ( pos ) { | |
| var projScreenMat = new THREE.Matrix4(); | |
| projScreenMat.multiply( this.camera.projectionMatrix, this.camera.matrixWorldInverse ); | |
| projScreenMat.multiplyVector3( pos ); | |
| return { | |
| x: ( pos.x + 1 ) * this.renderer.domElement.clientWidth / 2, | |
| y: ( - pos.y + 1) * this.renderer.domElement.clientHeight / 2 | |
| }; | |
| } | |
| Tower.prototype.initEvents = function() { | |
| this.onPopupShown = this.onPopupShown.bind( this ); | |
| this.onPopupUnload = this.onPopupUnload.bind( this ); | |
| this.onPopupShowing = this.onPopupShowing.bind( this ); | |
| this.onPopupHidden = this.onPopupHidden.bind( this ); | |
| }; | |
| Tower.prototype.initGUI = function() { | |
| this.gui = { | |
| currentheight: document.getElementById('currentheight'), | |
| timeleft: document.getElementById('timeleft') | |
| }; | |
| }; | |
| Tower.prototype.updateGUI = function() { | |
| var i, formatted_time, self = this; | |
| // Time left | |
| formatted_time = { | |
| m: Math.floor(this.timeleft / 60), | |
| s: Math.floor((this.timeleft % 60) * 100) / 100 | |
| }; | |
| this.gui.timeleft.textContent = (formatted_time.m + ':') + ( formatted_time.s < 10 ? '0' + formatted_time.s : formatted_time.s ); | |
| // Height | |
| this.gui.currentheight.textContent = Math.floor(this.height * 100) / 100 + 'm'; | |
| // Time bonuses | |
| for ( i = 0; i < this.timebonuses.length; i++ ) { | |
| if ( !this.timebonuses[i].achieved ) { | |
| if ( this.height >= this.timebonuses[i].height ) { | |
| this.totaltime += this.timebonuses[i].bonus; | |
| this.timebonuses[i].achieved = true; | |
| (function(timebonus) { | |
| var iterations = 0, interval; | |
| self.intervals.push( interval = setInterval( | |
| function() { | |
| if ( ++iterations == 90 ) { | |
| clearInterval( interval ); | |
| timebonus.element.style.display = 'none'; | |
| return; | |
| } | |
| timebonus.element.style.webkitTransform = 'scale(' + ( 1 + iterations / 30 ) + ')'; | |
| timebonus.element.style.opacity = 1 - iterations / 90; | |
| }, | |
| 1 / 60 | |
| ) ); | |
| })(this.timebonuses[i]); | |
| if ( this.timebonuses[i+1] ) { | |
| this.timebonuses[i+1].element.style.display = 'block'; | |
| } | |
| } else { | |
| this.timebonuses[i].element.style.top = this.to2D( new THREE.Vector3( 0, this.timebonuses[i].height, 0 ) ).y + 'px'; | |
| break; | |
| } | |
| } | |
| } | |
| }; | |
| Tower.prototype.initThree = function() { | |
| // Projector | |
| this.projector = new THREE.Projector(); | |
| // Renderer | |
| this.renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| this.renderer.setSize( this.workarea_size.width, this.workarea_size.height ); | |
| document.getElementById('viewport').appendChild( this.renderer.domElement ); | |
| this.renderer.shadowMapEnabled = true; | |
| this.renderer.shadowMapSoft = true; | |
| // Event bindings | |
| this.renderer.domElement.addEventListener( 'mousemove', this.handleMouseMove.bind( this, this.renderer.domElement ) ); | |
| this.renderer.domElement.addEventListener( 'mouseup', this.handleMouseUp.bind( this, this.renderer.domElement ) ); | |
| this.renderer.domElement.addEventListener( 'contextmenu', function( evt) { evt.preventDefault(); } ); | |
| this.handleMouseWheel = this.handleMouseWheel.bind( this ); | |
| window.document.addEventListener( 'mousewheel', this.handleMouseWheel ); | |
| // Scene | |
| this.scene = new THREE.Scene(); | |
| // Camera | |
| this.camera = new THREE.PerspectiveCamera( | |
| 35, | |
| this.workarea_size.width / this.workarea_size.height, | |
| 1, | |
| 100 | |
| ); | |
| this.camera.position.set( 0, 65, 20 ); | |
| this.scene.add( this.camera ); | |
| }; | |
| Tower.prototype.initTextures = function() { | |
| var shader, uniforms, parameters; | |
| this.textures = {}; | |
| this.materials = {}; | |
| this.materials.empty = new THREE.MeshBasicMaterial; | |
| // Container | |
| this.materials.container = new THREE.MeshBasicMaterial({ color: 0xa6d8ed, transparent: true, opacity: .2 }); | |
| // Ground | |
| this.textures.grass = THREE.ImageUtils.loadTexture( 'assets/textures/ground.png' ); | |
| this.textures.grass.wrapS = this.textures.grass.wrapT = THREE.RepeatWrapping; | |
| this.textures.grass.repeat.x = 5; | |
| this.textures.grass.repeat.y = 4; | |
| this.materials.ground = new THREE.MeshLambertMaterial({ map: this.textures.grass }) | |
| // wood | |
| this.textures.wood = THREE.ImageUtils.loadTexture( 'assets/textures/wood.jpg' ); | |
| this.textures.wood.wrapS = this.textures.wood.wrapT = THREE.RepeatWrapping; | |
| this.textures.wood.repeat.x = 1; | |
| this.textures.wood.repeat.y = 1; | |
| this.materials.wood = new THREE.MeshLambertMaterial({ map: this.textures.wood }); | |
| // Stone | |
| this.textures.stone_diffuse = THREE.ImageUtils.loadTexture( 'assets/textures/stone_diffuse.png' ); | |
| this.textures.stone_diffuse.wrapS = this.textures.stone_diffuse.wrapT = THREE.RepeatWrapping; | |
| this.textures.stone_normal = THREE.ImageUtils.loadTexture( 'assets/textures/stone_normal.png' ); | |
| this.textures.stone_normal.wrapS = this.textures.stone_normal.wrapT = THREE.RepeatWrapping; | |
| var shader = THREE.ShaderUtils.lib[ "normal" ]; | |
| var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); | |
| uniforms[ "enableAO" ].value = false; | |
| uniforms[ "enableDiffuse" ].value = true; | |
| uniforms[ "enableSpecular" ].value = false; | |
| uniforms[ "enableReflection" ].value = false; | |
| uniforms[ "tNormal" ].texture = this.textures.stone_normal; | |
| uniforms[ "tDiffuse" ].texture = this.textures.stone_diffuse; | |
| //uniforms[ "tDisplacement" ].texture = THREE.ImageUtils.loadTexture( "assets/textures/stone_displacement.png" ); | |
| uniforms[ "uDisplacementBias" ].value = 0; | |
| uniforms[ "uDisplacementScale" ].value = 0; | |
| uniforms[ "uSpecularColor" ].value.setHex( 0x080808 ); | |
| uniforms[ "uAmbientColor" ].value.setHex( 0x050505 ); | |
| uniforms[ "uShininess" ].value = 2; | |
| uniforms[ "uRepeat" ].value.set( 1.4, 1.4 ); | |
| var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: false }; | |
| this.materials.stone = new THREE.ShaderMaterial( parameters ); | |
| }; | |
| Tower.prototype.initScene = function() { | |
| var i; | |
| // Sky | |
| this.sky = document.getElementById('sky'); | |
| // ammo setup | |
| var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration(); | |
| var dispatcher = new Ammo.btCollisionDispatcher( collisionConfiguration ); | |
| var overlappingPairCache = new Ammo.btDbvtBroadphase(); | |
| var solver = new Ammo.btSequentialImpulseConstraintSolver(); | |
| this.scene.world = new Ammo.btDiscreteDynamicsWorld( dispatcher, overlappingPairCache, solver, collisionConfiguration ); | |
| this.scene.world.setGravity(new Ammo.btVector3(0, -12, 0)); | |
| // light | |
| var light = new THREE.DirectionalLight( 0xffffff ); | |
| light.position.set( 10, 50, 40 ); | |
| light.target.position.set( 0, 0, 0 ); | |
| light.castShadow = true; | |
| light.shadowCameraLeft = -20; | |
| light.shadowCameraRight = 20; | |
| light.shadowCameraTop = 20; | |
| light.shadowCameraBottom = -20; | |
| light.shadowBias = .0001; | |
| light.shadowDarkness = 0.35; | |
| light.shadowMapWidth = 2048; | |
| light.shadowMapHeight = 2048; | |
| this.scene.add( light ); | |
| // ground | |
| var ground = new THREE.Mesh( | |
| new THREE.CubeGeometry( 60, 2, 60, 1, 1, 1, [ | |
| this.materials.empty, | |
| this.materials.empty, | |
| this.materials.ground, | |
| this.materials.empty, | |
| this.materials.empty, | |
| this.materials.empty | |
| ], | |
| { px: false, nx: false, py: true, ny: false, pz: false, nz: false } | |
| ), | |
| new THREE.MeshFaceMaterial | |
| ); | |
| ground.receiveShadow = true; | |
| ground.position.y = -2; | |
| ground.id = 'ground'; | |
| var groundShape = new Ammo.btBoxShape(new Ammo.btVector3( 30, 1, 30 )); | |
| var groundTransform = new Ammo.btTransform(); | |
| groundTransform.setIdentity(); | |
| groundTransform.setOrigin(new Ammo.btVector3( 0, -2, 0 )); | |
| var mass = 0; | |
| var localInertia = new Ammo.btVector3(0, 0, 0); | |
| var myMotionState = new Ammo.btDefaultMotionState( groundTransform ); | |
| var rbInfo = new Ammo.btRigidBodyConstructionInfo( 0, myMotionState, groundShape, localInertia ); | |
| var groundbody = new Ammo.btRigidBody( rbInfo ); | |
| this.scene.world.addRigidBody( groundbody ); | |
| groundbody.mesh = ground; | |
| this.scene.add( ground ); | |
| // Tower container | |
| this.container = new THREE.Mesh( | |
| new THREE.CubeGeometry( | |
| 15, 400, 12, 1, 1, 1, [], | |
| { px: true, nx: true, py: false, ny: false, pz: false, nz: false} | |
| ), | |
| this.materials.container | |
| ); | |
| this.container.doubleSided = true; | |
| this.container.position.y = 198; | |
| this.scene.add( this.container ); | |
| }; | |
| Tower.prototype.handleResize = function() { | |
| this.workarea_size = pokki.getWorkAreaSize(); | |
| if ( this.workarea_size.width > 910) this.workarea_size.width = 910; | |
| if ( this.workarea_size.height > 710) this.workarea_size.height = 710; | |
| pokki.setPopupClientSize(this.workarea_size.width, this.workarea_size.height); | |
| // Update content container | |
| document.getElementById('content').style.width = this.workarea_size.width + 'px'; | |
| document.getElementById('content').style.height = this.workarea_size.height + 'px'; | |
| }; | |
| Tower.prototype.start = function() { | |
| this.createBlock(); | |
| this.updateCamera({ delay: 2000 }); | |
| this.starttime = Math.floor(new Date().getTime() / 1000); | |
| this.render(); | |
| this.updateHeight(); | |
| }; | |
| Tower.prototype.render = function() { | |
| var i, self = this, now = Math.floor(new Date().getTime() / 1000); | |
| if (this.paused) { | |
| requestAnimFrame( function() { self.render(); } ); | |
| return false; | |
| } | |
| this.timeleft = this.totaltime - (now - this.starttime); | |
| this.scene.world.stepSimulation( 1 / 60, 20 ); | |
| var transform = new Ammo.btTransform(); | |
| for ( i = 0; i < this.boxes.length; i++ ) { | |
| this.boxes[i].getMotionState().getWorldTransform( transform ); | |
| var origin = transform.getOrigin(); | |
| this.boxes[i].mesh.position.x = origin.x(); | |
| this.boxes[i].mesh.position.y = origin.y(); | |
| this.boxes[i].mesh.position.z = origin.z(); | |
| var rotation = transform.getRotation(); | |
| this.boxes[i].mesh.quaternion.x = rotation.x(); | |
| this.boxes[i].mesh.quaternion.y = rotation.y(); | |
| this.boxes[i].mesh.quaternion.z = rotation.z(); | |
| this.boxes[i].mesh.quaternion.w = rotation.w(); | |
| if ( i >= this.boxes.length - 3 ) | |
| this.boxes[i].activate(); // sometimes a box will get stuck from not moving | |
| } | |
| if ( this.active_block ) { | |
| this.active_block.activate(); // sometimes this box will get stuck from not moving | |
| this.active_block.setLinearVelocity( new Ammo.btVector3( 0, 0, 0 ) ); | |
| this.active_block.setAngularVelocity( new Ammo.btVector3( 0, 0, 0 ) ); | |
| this.active_block.clearForces(); | |
| this.active_block.getMotionState().getWorldTransform( transform ); | |
| var position = this.cursor_position.x, | |
| halfwidth = this.active_block.rotated ? this.active_block.mesh.geometry.boundingBox.max.y : this.active_block.mesh.geometry.boundingBox.max.x ; | |
| position = Math.max( | |
| Math.min( position, 7.5 - halfwidth ), | |
| -7.5 + halfwidth | |
| ); | |
| transform.setOrigin(new Ammo.btVector3( position, this.height + 4, 0 )); | |
| this.active_block.setCenterOfMassTransform( transform ); | |
| } | |
| this.updateGUI(); | |
| var manifolds = this.scene.world.getDispatcher().getNumManifolds(); | |
| if ( manifolds > this.last_manifolds ) { | |
| switch ( Math.floor(Math.random() * 3) ) { | |
| case 0: | |
| collisionsound1.play(); | |
| case 1: | |
| collisionsound2.play(); | |
| case 2: | |
| collisionsound3.play(); | |
| } | |
| }; | |
| this.last_manifolds = manifolds; | |
| if (this.timeleft > 0) { | |
| this.renderer.render( this.scene, this.camera ); | |
| requestAnimFrame( function() { self.render(); } ); | |
| } else { | |
| this.endGame(); | |
| } | |
| }; | |
| Tower.prototype.handleMouseMove = function( element, evt ) { | |
| var vector = new THREE.Vector3( | |
| ( evt.clientX / this.renderer.domElement.clientWidth ) * 2 - 1, | |
| ( evt.clientY / this.renderer.domElement.clientHeight ) * 2 - 1, | |
| 1 | |
| ); | |
| this.projector.unprojectVector( vector, this.camera ); | |
| vector.subSelf( this.camera.position ).normalize(); | |
| vector.y *= -1; | |
| vector.multiplyScalar( -this.camera.position.z / vector.z ); | |
| var position = new THREE.Vector3().copy( this.camera.position ).addSelf( vector ); | |
| this.cursor_position.set( position.x, position.y ); | |
| }; | |
| Tower.prototype.handleMouseUp = function( element, evt ) { | |
| switch ( evt.button ) { | |
| case 0: | |
| // main mouse button | |
| if ( this.active_block ) { | |
| console.debug('here'); | |
| this.active_block.setLinearVelocity( new Ammo.btVector3( 0, 0, 0 ) ); | |
| this.active_block.setAngularVelocity( new Ammo.btVector3( 0, 0, 0 ) ); | |
| this.active_block.clearForces(); | |
| this.active_block = null; | |
| this.timeouts.push( setTimeout( this.createBlock, 2000 ) ); | |
| } | |
| break; | |
| case 2: | |
| // alternate mouse button | |
| if ( this.active_block ) { | |
| var transform = new Ammo.btTransform; | |
| this.active_block.getMotionState().getWorldTransform( transform ); | |
| var rotation = transform.getRotation(); | |
| if ( this.active_block.rotated ) { | |
| rotation.setEuler( 0, 0, 0 ); | |
| this.active_block.rotated = false; | |
| } else { | |
| rotation.setEuler( 0, 0, Math.PI / 2 ); | |
| this.active_block.rotated = true; | |
| } | |
| transform.setRotation( rotation ); | |
| this.active_block.setWorldTransform( transform ); | |
| } | |
| break; | |
| } | |
| evt.preventDefault(); | |
| evt.cancelBubble = true; | |
| }; | |
| Tower.prototype.handleMouseWheel = function( evt ) { | |
| if ( evt.wheelDelta < 0 ) { | |
| this.updateCamera({ adjust: -8 }); | |
| } else { | |
| this.updateCamera({ adjust: 8 }); | |
| } | |
| } | |
| Tower.prototype.createBlock = function() { | |
| var mesh, | |
| width, height, mass, | |
| startTransform, localInertia, boxShape, myMotionState, rbInfo, box; | |
| this.height = this.getHeight(); | |
| // Update camera position | |
| this.updateCamera(); | |
| var block_type = Math.round(Math.random() * 1), material; | |
| switch( block_type ) { | |
| case 1: | |
| // wood | |
| material = this.materials.wood; | |
| width = Math.ceil( .001 + Math.round(Math.random() * 1) ); | |
| height = Math.ceil( 4 + Math.random() * 3 ); | |
| mass = width * height * 2; | |
| break; | |
| default: | |
| // stone | |
| material = this.materials.stone; | |
| width = Math.ceil( 1 + Math.random() * 4 ); | |
| height = Math.ceil( 1 + Math.random() * 3 ) | |
| mass = width * height * 4; | |
| break; | |
| } | |
| mesh = new THREE.Mesh( | |
| new THREE.CubeGeometry( width, height, 5 ), | |
| material | |
| ); | |
| mesh.geometry.computeBoundingBox(); | |
| mesh.geometry.computeTangents(); | |
| mesh.receiveShadow = true; | |
| mesh.castShadow = true; | |
| mesh.useQuaternion = true; | |
| this.scene.add( mesh ); | |
| startTransform = new Ammo.btTransform(); | |
| startTransform.setIdentity(); | |
| startTransform.setOrigin(new Ammo.btVector3( this.cursor_position.x, this.height + 4, 0 )); | |
| localInertia = new Ammo.btVector3(0, 0, 0); | |
| boxShape = new Ammo.btBoxShape(new Ammo.btVector3( width / 2, height / 2, 2.5 )); | |
| boxShape.calculateLocalInertia( mass, localInertia ); | |
| myMotionState = new Ammo.btDefaultMotionState( startTransform ); | |
| rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, myMotionState, boxShape, localInertia ); | |
| box = new Ammo.btRigidBody( rbInfo ); | |
| this.scene.world.addRigidBody( box ); | |
| box.mesh = mesh; | |
| this.boxes.push( box ); | |
| this.active_block = box; | |
| return box; | |
| }; | |
| Tower.prototype.getHeight = function( exclusive ) { | |
| var i, obj_height, height = 0; | |
| for ( i = 0; i < this.boxes.length - ( exclusive ? 1 : 0 ); i++ ) { | |
| obj_height = this.boxes[i].mesh.position.y + this.boxes[i].mesh.boundRadius; | |
| if ( obj_height > height ) { | |
| height = obj_height; | |
| } | |
| } | |
| return height; | |
| }; | |
| Tower.prototype.updateHeight = function() { | |
| this.height = this.getHeight( true ); | |
| this._updateHeight = this.timeouts.push( setTimeout( this.updateHeight ) ); | |
| }; | |
| Tower.prototype.updateCamera = function( options ) { | |
| if ( this._cameratween ) { | |
| this._cameratween.stop(); | |
| this._skytween.stop(); | |
| } | |
| options = options || {}; | |
| var target_height, target_depth; | |
| if ( options.adjust ) { | |
| target_height = this.camera.position.y + options.adjust; | |
| target_depth = 35 + (target_height) / 5; | |
| } else { | |
| target_height = this.height; | |
| target_depth = 35 + this.height / 5; | |
| } | |
| target_height = Math.min( Math.max( 4, target_height ), 65 ); | |
| target_depth = Math.min( 40, target_depth ); | |
| this._cameratween = new TWEEN.Tween( this.camera.position ).to( | |
| { y: target_height, z: target_depth }, | |
| options.delay || 500 | |
| ).easing( TWEEN.Easing.Quadratic.EaseOut ).start(); | |
| this._skytween = new TWEEN.Tween( this.sky ).to( | |
| { scrollTop: 3500 - target_height * 60 }, | |
| options.delay || 500 | |
| ).easing( TWEEN.Easing.Quadratic.EaseOut ).start(); | |
| }; | |
| Tower.prototype.unload = function() { | |
| var i; | |
| for ( i = 0; i < this.timeouts.length; i++ ) { | |
| clearTimeout( this.timeouts[i] ); | |
| } | |
| for ( i = 0; i < this.intervals.length; i++ ) { | |
| clearInterval( this.intervals[i] ); | |
| } | |
| this.renderer.domElement.parentNode.removeChild( this.renderer.domElement ); | |
| window.document.removeEventListener( 'mousewheel', this.handleMouseWheel ); | |
| for ( i = 0; i < this.timebonuses.length; i++ ) { | |
| document.getElementById('viewport').removeChild( this.timebonuses[i].element ); | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment