diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index 3a13a1c52f..6c8473b4d7 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -10,13 +10,44 @@ var iteration = 0; -var invaderStepsPerCycle = 30; // the number of update steps it takes then invaders to move one column to the right +var gameOver = false; + +// horizontal movement of invaders +var invaderStepsPerCycle = 120; // the number of update steps it takes then invaders to move one column to the right var invaderStepOfCycle = 0; // current iteration in the cycle var invaderMoveDirection = 1; // 1 for moving to right, -1 for moving to left -var itemLifetimes = 60; -var gameAt = { x: 10, y: 0, z: 10 }; +var itemLifetimes = 60 * 2; // 2 minutes + + +// position the game to be basically near the avatar running the game... var gameSize = { x: 10, y: 20, z: 1 }; +var positionFromAvatarZ = 10; + +var avatarX = MyAvatar.position.x; +var avatarY = MyAvatar.position.y; +var avatarZ = MyAvatar.position.z; +var gameAtX = avatarX; +var gameAtY = avatarY; +var gameAtZ = avatarZ; + +// move the game to be "centered" on our X +if (gameAtX > (gameSize.x/2)) { + gameAtX -= (gameSize.x/2); +} + +// move the game to be "offset slightly" on our Y +if (gameAtY > (gameSize.y/4)) { + gameAtY -= (gameSize.y/4); +} + + +// move the game to be positioned away on our Z +if (gameAtZ > positionFromAvatarZ) { + gameAtZ -= positionFromAvatarZ; +} + +var gameAt = { x: gameAtX, y: gameAtY, z: gameAtZ }; var middleX = gameAt.x + (gameSize.x/2); var middleY = gameAt.y + (gameSize.y/2); @@ -34,9 +65,29 @@ var invadersBottomCorner = { x: gameAt.x, y: middleY , z: gameAt.z }; var rowHeight = ((gameAt.y + gameSize.y) - invadersBottomCorner.y) / numberOfRows; var columnWidth = gameSize.x / (invadersPerRow + emptyColumns); +// vertical movement of invaders +var invaderRowOffset = 0; +var stepsPerRow = 20; // number of steps before invaders really move a whole row down. +var yPerStep = rowHeight/stepsPerRow; +var stepsToGround = (middleY - gameAt.y) / yPerStep; +var maxInvaderRowOffset=stepsToGround; + +// missile related items var missileFired = false; var myMissile; +// sounds +var hitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw"); +var shootSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw"); +var moveSounds = new Array(); +moveSounds[0] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo1.raw"); +moveSounds[1] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo2.raw"); +moveSounds[2] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo3.raw"); +moveSounds[3] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo4.raw"); +var currentMoveSound = 0; +var numberOfSounds = 4; +var stepsPerSound = invaderStepsPerCycle / numberOfSounds; + function initializeMyShip() { myShipProperties = { position: { x: middleX , y: gameAt.y, z: gameAt.z }, @@ -52,16 +103,19 @@ function initializeMyShip() { // calculate the correct invaderPosition for an column row function getInvaderPosition(row, column) { - var xMovePart = 0; var xBasePart = invadersBottomCorner.x + (column * columnWidth); + var xMovePart = 0; if (invaderMoveDirection > 0) { xMovePart = (invaderMoveDirection * columnWidth * (invaderStepOfCycle/invaderStepsPerCycle)); } else { xMovePart = columnWidth + (invaderMoveDirection * columnWidth * (invaderStepOfCycle/invaderStepsPerCycle)); } + + var y = invadersBottomCorner.y + (row * rowHeight) - (invaderRowOffset * rowHeight/stepsPerRow); + var invaderPosition = { x: xBasePart + xMovePart, - y: invadersBottomCorner.y + (row * rowHeight), + y: y, z: invadersBottomCorner.z }; return invaderPosition; @@ -79,6 +133,7 @@ function initializeInvaders() { damping: 0, radius: shipSize, color: { red: 255, green: 0, blue: 0 }, + modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", lifetime: itemLifetimes }); @@ -88,31 +143,67 @@ function initializeInvaders() { } function moveInvaders() { - print("moveInvaders()..."); for (var row = 0; row < numberOfRows; row++) { for (var column = 0; column < invadersPerRow; column++) { props = Particles.getParticleProperties(invaders[row][column]); if (props.isKnownID) { invaderPosition = getInvaderPosition(row, column); - Particles.editParticle(invaders[row][column], { position: invaderPosition }); + Particles.editParticle(invaders[row][column], + { + position: invaderPosition, + velocity: { x: 0, y: 0, z: 0 } // always reset this, incase they got collided with + }); } } } } +function displayGameOver() { + gameOver = true; + print("Game over..."); +} + function update() { - print("updating space invaders... iteration="+iteration); - iteration++; - invaderStepOfCycle++; - if (invaderStepOfCycle > invaderStepsPerCycle) { - invaderStepOfCycle = 0; - if (invaderMoveDirection > 0) { - invaderMoveDirection = -1; - } else { - invaderMoveDirection = 1; + if (!gameOver) { + //print("updating space invaders... iteration="+iteration); + iteration++; + + if (invaderStepOfCycle % stepsPerSound == 0) { + // play the move sound + var options = new AudioInjectionOptions();
 + options.position = getInvaderPosition(invadersPerRow / 2, numberOfRows / 2); + options.volume = 10.0; + Audio.playSound(moveSounds[currentMoveSound], options); + + // get ready for next move sound + currentMoveSound = (currentMoveSound+1) % numberOfSounds; } + + invaderStepOfCycle++; + + + if (invaderStepOfCycle > invaderStepsPerCycle) { + // handle left/right movement + invaderStepOfCycle = 0; + if (invaderMoveDirection > 0) { + invaderMoveDirection = -1; + } else { + invaderMoveDirection = 1; + } + + // handle downward movement + invaderRowOffset++; // move down one row + //print("invaderRowOffset="+invaderRowOffset); + + // check to see if invaders have reached "ground"... + if (invaderRowOffset > maxInvaderRowOffset) { + displayGameOver(); + return; + } + + } + moveInvaders(); } - moveInvaders(); } // register the call back so it fires before each data send @@ -182,6 +273,11 @@ function fireMissile() { lifetime: 5 }); + var options = new AudioInjectionOptions();
 + options.position = missilePosition; + options.volume = 1.0; + Audio.playSound(shootSound, options); + missileFired = true; } } @@ -219,6 +315,13 @@ function deleteIfInvader(possibleInvaderParticle) { if (invaders[row][column].id == possibleInvaderParticle.id) { Particles.deleteParticle(possibleInvaderParticle); Particles.deleteParticle(myMissile); + + // play the hit sound + var options = new AudioInjectionOptions();
 + var invaderPosition = getInvaderPosition(row, column); + options.position = invaderPosition; + options.volume = 1.0; + Audio.playSound(hitSound, options); } } } diff --git a/interface/src/ParticleTreeRenderer.cpp b/interface/src/ParticleTreeRenderer.cpp index d96ac2beaa..7ba714ae93 100644 --- a/interface/src/ParticleTreeRenderer.cpp +++ b/interface/src/ParticleTreeRenderer.cpp @@ -99,7 +99,11 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg // TODO: need to figure out correct scale adjust, this was arbitrarily set to make a couple models work const float MODEL_SCALE = 0.00575f; glm::vec3 scale(1.0f,1.0f,1.0f); - model->setScale(scale * MODEL_SCALE * radius * particle.getModelScale()); + + // TODO: There is some kind of a bug in packing of the particle packets which is causing modelscale to + // sometimes be garbage. + float modelScale = 2.0f; /// particle.getModelScale() + model->setScale(scale * MODEL_SCALE * radius * modelScale); model->simulate(0.0f); model->render(alpha); // TODO: should we allow particles to have alpha on their models?