From 906d913d713529d051a478d4342b934af85b14ad Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 3 Feb 2014 10:05:07 -0800 Subject: [PATCH 1/4] added more examples, updated lookWithMouse.js to support alwaysLook --- examples/lookWithMouse.js | 35 ++++- examples/lookWithTouch.js | 86 ++++++++++++ examples/spaceInvadersExample.js | 224 +++++++++++++++++++++++++++++++ 3 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 examples/lookWithTouch.js create mode 100644 examples/spaceInvadersExample.js diff --git a/examples/lookWithMouse.js b/examples/lookWithMouse.js index f404019bc1..460663c054 100644 --- a/examples/lookWithMouse.js +++ b/examples/lookWithMouse.js @@ -9,29 +9,36 @@ // // +var alwaysLook = true; // if you want the mouse look to happen only when you click, change this to false var isMouseDown = false; var lastX = 0; var lastY = 0; var yawFromMouse = 0; var pitchFromMouse = 0; +var wantDebugging = false; function mousePressEvent(event) { - print("mousePressEvent event.x,y=" + event.x + ", " + event.y); + if (wantDebugging) { + print("mousePressEvent event.x,y=" + event.x + ", " + event.y); + } isMouseDown = true; lastX = event.x; lastY = event.y; } function mouseReleaseEvent(event) { - print("mouseReleaseEvent event.x,y=" + event.x + ", " + event.y); + if (wantDebugging) { + print("mouseReleaseEvent event.x,y=" + event.x + ", " + event.y); + } isMouseDown = false; } function mouseMoveEvent(event) { - print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y); + if (wantDebugging) { + print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y); + } - if (isMouseDown) { - print("isMouseDown... attempting to change pitch..."); + if (alwaysLook || isMouseDown) { var MOUSE_YAW_SCALE = -0.25; var MOUSE_PITCH_SCALE = -12.5; var FIXED_MOUSE_TIMESTEP = 0.016; @@ -43,12 +50,26 @@ function mouseMoveEvent(event) { } function update() { + if (wantDebugging) { + print("update()..."); + } // rotate body yaw for yaw received from mouse - MyAvatar.orientation = Quat.multiply(MyAvatar.orientation, Quat.fromVec3( { x: 0, y: yawFromMouse, z: 0 } )); + var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.fromVec3( { x: 0, y: yawFromMouse, z: 0 } )); + if (wantDebugging) { + print("changing orientation" + + " [old]MyAvatar.orientation="+MyAvatar.orientation.x + "," + MyAvatar.orientation.y + "," + + MyAvatar.orientation.z + "," + MyAvatar.orientation.w + + " newOrientation="+newOrientation.x + "," + newOrientation.y + "," + newOrientation.z + "," + newOrientation.w); + } + MyAvatar.orientation = newOrientation; yawFromMouse = 0; // apply pitch from mouse - MyAvatar.headPitch = MyAvatar.headPitch + pitchFromMouse; + var newPitch = MyAvatar.headPitch + pitchFromMouse; + if (wantDebugging) { + print("changing pitch [old]MyAvatar.headPitch="+MyAvatar.headPitch+ " newPitch="+newPitch); + } + MyAvatar.headPitch = newPitch; pitchFromMouse = 0; } diff --git a/examples/lookWithTouch.js b/examples/lookWithTouch.js new file mode 100644 index 0000000000..bb54a055c4 --- /dev/null +++ b/examples/lookWithTouch.js @@ -0,0 +1,86 @@ +// +// lookWithTouch.js +// hifi +// +// Created by Brad Hefta-Gaub on 1/28/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that demonstrates use of the Controller class +// +// + +var lastX = 0; +var lastY = 0; +var yawFromMouse = 0; +var pitchFromMouse = 0; +var wantDebugging = false; + +function touchBeginEvent(event) { + if (wantDebugging) { + print("touchBeginEvent event.x,y=" + event.x + ", " + event.y); + } + lastX = event.x; + lastY = event.y; +} + +function touchEndEvent(event) { + if (wantDebugging) { + print("touchEndEvent event.x,y=" + event.x + ", " + event.y); + } +} + +function touchUpdateEvent(event) { + if (wantDebugging) { + print("touchUpdateEvent event.x,y=" + event.x + ", " + event.y); + } + + var MOUSE_YAW_SCALE = -0.25; + var MOUSE_PITCH_SCALE = -12.5; + var FIXED_MOUSE_TIMESTEP = 0.016; + yawFromMouse += ((event.x - lastX) * MOUSE_YAW_SCALE * FIXED_MOUSE_TIMESTEP); + pitchFromMouse += ((event.y - lastY) * MOUSE_PITCH_SCALE * FIXED_MOUSE_TIMESTEP); + lastX = event.x; + lastY = event.y; +} + +function update() { + // rotate body yaw for yaw received from mouse + var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.fromVec3( { x: 0, y: yawFromMouse, z: 0 } )); + if (wantDebugging) { + print("changing orientation" + + " [old]MyAvatar.orientation="+MyAvatar.orientation.x + "," + MyAvatar.orientation.y + "," + + MyAvatar.orientation.z + "," + MyAvatar.orientation.w + + " newOrientation="+newOrientation.x + "," + newOrientation.y + "," + newOrientation.z + "," + newOrientation.w); + } + MyAvatar.orientation = newOrientation; + yawFromMouse = 0; + + // apply pitch from mouse + var newPitch = MyAvatar.headPitch + pitchFromMouse; + if (wantDebugging) { + print("changing pitch [old]MyAvatar.headPitch="+MyAvatar.headPitch+ " newPitch="+newPitch); + } + MyAvatar.headPitch = newPitch; + pitchFromMouse = 0; +} + +// Map the mouse events to our functions +Controller.touchBeginEvent.connect(touchBeginEvent); +Controller.touchUpdateEvent.connect(touchUpdateEvent); +Controller.touchEndEvent.connect(touchEndEvent); + +// disable the standard application for mouse events +Controller.captureTouchEvents(); + +function scriptEnding() { + // re-enabled the standard application for mouse events + Controller.releaseTouchEvents(); +} + +MyAvatar.bodyYaw = 0; +MyAvatar.bodyPitch = 0; +MyAvatar.bodyRoll = 0; + +// would be nice to change to update +Script.willSendVisualDataCallback.connect(update); +Script.scriptEnding.connect(scriptEnding); diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js new file mode 100644 index 0000000000..c575cbcd76 --- /dev/null +++ b/examples/spaceInvadersExample.js @@ -0,0 +1,224 @@ +// +// spaceInvadersExample.js +// hifi +// +// Created by Brad Hefta-Gaub on 1/30/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that demonstrates a simple space invaders style of game +// + +var iteration = 0; + +var gameAt = { x: 10, y: 0, z: 10 }; +var gameSize = { x: 10, y: 20, z: 1 }; +var middleX = gameAt.x + (gameSize.x/2); +var middleY = gameAt.y + (gameSize.y/2); + +var shipSize = 0.2; +var missileSize = 0.1; +var myShip; +var myShipProperties; + +// create the rows of space invaders +var invaders = new Array(); +var numberOfRows = 5; +var invadersPerRow = 8; +var emptyColumns = 2; // number of invader width columns not filled with invaders +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); + +var missileFired = false; +var myMissile; + +function initializeMyShip() { + myShipProperties = { + position: { x: middleX , y: gameAt.y, z: gameAt.z }, + velocity: { x: 0, y: 0, z: 0 }, + gravity: { x: 0, y: 0, z: 0 }, + damping: 0, + radius: shipSize, + color: { red: 0, green: 255, blue: 0 }, + lifetime: 60 * 5 // 5 minutes + }; + myShip = Particles.addParticle(myShipProperties); +} + +function initializeInvaders() { + for (var row = 0; row < numberOfRows; row++) { + invaders[row] = new Array(); + for (var column = 0; column < invadersPerRow; column++) { + invaderPosition = { + x: invadersBottomCorner.x + (column * columnWidth), + y: invadersBottomCorner.y + (row * rowHeight), + z: invadersBottomCorner.z }; + + + invaders[row][column] = Particles.addParticle({ + position: invaderPosition, + velocity: { x: 0, y: 0, z: 0 }, + gravity: { x: 0, y: 0, z: 0 }, + damping: 0, + radius: shipSize, + color: { red: 255, green: 0, blue: 0 }, + lifetime: 60 * 5 // 5 minutes + }); + + print("invaders[row][column].creatorTokenID=" + invaders[row][column].creatorTokenID); + } + } +} + +var invadersMovingRight = true; +function moveInvaders() { + print("moveInvaders()..."); + if (invadersMovingRight) { + invaderMoveX = 0.05; + } else { + invaderMoveX = -0.05; + } + for (var row = 0; row < numberOfRows; row++) { + for (var column = 0; column < invadersPerRow; column++) { + props = Particles.getParticleProperties(invaders[row][column]); + if (props.isKnownID) { + newPosition = { x: props.position.x + invaderMoveX, + y: props.position.y, + z: props.position.z }; + Particles.editParticle(invaders[row][column], { position: newPosition }); + } + } + } +} + +function update() { + print("updating space invaders... iteration="+iteration); + iteration++; + if ((iteration % 60) == 0) { + invadersMovingRight = !invadersMovingRight; + } + moveInvaders(); +} + +// register the call back so it fires before each data send +Agent.willSendVisualDataCallback.connect(update); + +function endGame() { + print("ending game..."); + Particles.deleteParticle(myShip); + print("endGame() ... Particles.deleteParticle(myShip)... myShip.id="+myShip.id); + for (var row = 0; row < numberOfRows; row++) { + for (var column = 0; column < invadersPerRow; column++) { + Particles.deleteParticle(invaders[row][column]); + print("endGame() ... Particles.deleteParticle(invaders[row][column])... invaders[row][column].id="+invaders[row][column].id); + } + } + + // clean up our missile + if (missileFired) { + Particles.deleteParticle(myMissile); + } + Agent.stop(); +} + +function moveShipTo(position) { + myShip = Particles.identifyParticle(myShip); + Particles.editParticle(myShip, { position: position }); +} + +function fireMissile() { + // we only allow one missile at a time... + var canFire = false; + + // If we've fired a missile, then check to see if it's still alive + if (missileFired) { + var missileProperties = Particles.getParticleProperties(myMissile); + print("missileProperties.isKnownID=" + missileProperties.isKnownID); + + if (!missileProperties.isKnownID) { + print("canFire = true"); + canFire = true; + } + } else { + canFire = true; + } + + if (canFire) { + print("firing missile"); + var missilePosition = { x: myShipProperties.position.x, + y: myShipProperties.position.y + (2* shipSize), + z: myShipProperties.position.z }; + + myMissile = Particles.addParticle( + { + position: missilePosition, + velocity: { x: 0, y: 5, z: 0}, + gravity: { x: 0, y: 0, z: 0 }, + damping: 0, + radius: missileSize, + color: { red: 0, green: 0, blue: 255 }, + lifetime: 5 + }); + + missileFired = true; + } +} + +function keyPressEvent(key) { + //print("keyPressEvent key.text="+key.text); + if (key.text == ",") { + myShipProperties.position.x -= 0.1; + if (myShipProperties.position.x < gameAt.x) { + myShipProperties.position.x = gameAt.x; + } + moveShipTo(myShipProperties.position); + } else if (key.text == ".") { + myShipProperties.position.x += 0.1; + if (myShipProperties.position.x > gameAt.x + gameSize.x) { + myShipProperties.position.x = gameAt.x + gameSize.x; + } + moveShipTo(myShipProperties.position); + } else if (key.text == " ") { + fireMissile(); + } else if (key.text == "q") { + endGame(); + } +} + +// remap the keys... +Controller.keyPressEvent.connect(keyPressEvent); +Controller.captureKeyEvents({text: " "}); + +function deleteIfInvader(possibleInvaderParticle) { + for (var row = 0; row < numberOfRows; row++) { + for (var column = 0; column < invadersPerRow; column++) { + invaders[row][column] = Particles.identifyParticle(invaders[row][column]); + if (invaders[row][column].isKnownID) { + if (invaders[row][column].id == possibleInvaderParticle.id) { + Particles.deleteParticle(possibleInvaderParticle); + Particles.deleteParticle(myMissile); + } + } + } + } +} + +function particleCollisionWithParticle(particleA, particleB) { + print("particleCollisionWithParticle() a.id="+particleA.id + " b.id=" + particleB.id); + if (missileFired) { + myMissile = Particles.identifyParticle(myMissile); + if (myMissile.id == particleA.id) { + deleteIfInvader(particleB); + } else if (myMissile.id == particleB.id) { + deleteIfInvader(particleA); + } + } +} +Particles.particleCollisionWithParticle.connect(particleCollisionWithParticle); + + +// initialize the game... +initializeMyShip(); +initializeInvaders(); + + From 8b2f18593706d1bbac2d323d3404b4e0c3d59ec4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 3 Feb 2014 10:05:26 -0800 Subject: [PATCH 2/4] always emit update even when no servers --- libraries/script-engine/src/ScriptEngine.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index cf9b582e2c..cf49a9cddb 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -208,11 +208,7 @@ void ScriptEngine::run() { break; } - bool willSendVisualDataCallBack = false; if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) { - // allow the scripter's call back to setup visual data - willSendVisualDataCallBack = true; - // release the queue of edit voxel messages. _voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages(); @@ -223,9 +219,6 @@ void ScriptEngine::run() { } if (_particlesScriptingInterface.getParticlePacketSender()->serversExist()) { - // allow the scripter's call back to setup visual data - willSendVisualDataCallBack = true; - // release the queue of edit voxel messages. _particlesScriptingInterface.getParticlePacketSender()->releaseQueuedMessages(); @@ -251,9 +244,7 @@ void ScriptEngine::run() { nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer); } - if (willSendVisualDataCallBack) { - emit willSendVisualDataCallback(); - } + emit willSendVisualDataCallback(); if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); From f41d2a3c02d0a4aa6d5cf1f7edebe3f5c2c48daa Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 3 Feb 2014 10:35:25 -0800 Subject: [PATCH 3/4] change Agent to Script --- examples/spaceInvadersExample.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index c575cbcd76..5f9d14ebdd 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -10,6 +10,7 @@ var iteration = 0; +var itemLifetimes = 60; var gameAt = { x: 10, y: 0, z: 10 }; var gameSize = { x: 10, y: 20, z: 1 }; var middleX = gameAt.x + (gameSize.x/2); @@ -40,7 +41,7 @@ function initializeMyShip() { damping: 0, radius: shipSize, color: { red: 0, green: 255, blue: 0 }, - lifetime: 60 * 5 // 5 minutes + lifetime: itemLifetimes }; myShip = Particles.addParticle(myShipProperties); } @@ -62,7 +63,7 @@ function initializeInvaders() { damping: 0, radius: shipSize, color: { red: 255, green: 0, blue: 0 }, - lifetime: 60 * 5 // 5 minutes + lifetime: itemLifetimes }); print("invaders[row][column].creatorTokenID=" + invaders[row][column].creatorTokenID); @@ -101,7 +102,7 @@ function update() { } // register the call back so it fires before each data send -Agent.willSendVisualDataCallback.connect(update); +Script.willSendVisualDataCallback.connect(update); function endGame() { print("ending game..."); @@ -118,7 +119,7 @@ function endGame() { if (missileFired) { Particles.deleteParticle(myMissile); } - Agent.stop(); + Script.stop(); } function moveShipTo(position) { From f33f4e9cc22f10d690235e9304808a9984f4bf7c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 3 Feb 2014 11:09:30 -0800 Subject: [PATCH 4/4] change invaders to use absolute positions --- examples/spaceInvadersExample.js | 65 +++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index 5f9d14ebdd..3a13a1c52f 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -10,6 +10,10 @@ var iteration = 0; +var invaderStepsPerCycle = 30; // 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 gameSize = { x: 10, y: 20, z: 1 }; @@ -46,16 +50,28 @@ function initializeMyShip() { myShip = Particles.addParticle(myShipProperties); } +// calculate the correct invaderPosition for an column row +function getInvaderPosition(row, column) { + var xMovePart = 0; + var xBasePart = invadersBottomCorner.x + (column * columnWidth); + if (invaderMoveDirection > 0) { + xMovePart = (invaderMoveDirection * columnWidth * (invaderStepOfCycle/invaderStepsPerCycle)); + } else { + xMovePart = columnWidth + (invaderMoveDirection * columnWidth * (invaderStepOfCycle/invaderStepsPerCycle)); + } + var invaderPosition = { + x: xBasePart + xMovePart, + y: invadersBottomCorner.y + (row * rowHeight), + z: invadersBottomCorner.z }; + + return invaderPosition; +} + function initializeInvaders() { for (var row = 0; row < numberOfRows; row++) { invaders[row] = new Array(); for (var column = 0; column < invadersPerRow; column++) { - invaderPosition = { - x: invadersBottomCorner.x + (column * columnWidth), - y: invadersBottomCorner.y + (row * rowHeight), - z: invadersBottomCorner.z }; - - + invaderPosition = getInvaderPosition(row, column); invaders[row][column] = Particles.addParticle({ position: invaderPosition, velocity: { x: 0, y: 0, z: 0 }, @@ -71,22 +87,14 @@ function initializeInvaders() { } } -var invadersMovingRight = true; function moveInvaders() { print("moveInvaders()..."); - if (invadersMovingRight) { - invaderMoveX = 0.05; - } else { - invaderMoveX = -0.05; - } for (var row = 0; row < numberOfRows; row++) { for (var column = 0; column < invadersPerRow; column++) { props = Particles.getParticleProperties(invaders[row][column]); if (props.isKnownID) { - newPosition = { x: props.position.x + invaderMoveX, - y: props.position.y, - z: props.position.z }; - Particles.editParticle(invaders[row][column], { position: newPosition }); + invaderPosition = getInvaderPosition(row, column); + Particles.editParticle(invaders[row][column], { position: invaderPosition }); } } } @@ -95,8 +103,14 @@ function moveInvaders() { function update() { print("updating space invaders... iteration="+iteration); iteration++; - if ((iteration % 60) == 0) { - invadersMovingRight = !invadersMovingRight; + invaderStepOfCycle++; + if (invaderStepOfCycle > invaderStepsPerCycle) { + invaderStepOfCycle = 0; + if (invaderMoveDirection > 0) { + invaderMoveDirection = -1; + } else { + invaderMoveDirection = 1; + } } moveInvaders(); } @@ -104,14 +118,15 @@ function update() { // register the call back so it fires before each data send Script.willSendVisualDataCallback.connect(update); -function endGame() { - print("ending game..."); +function cleanupGame() { + print("cleaning up game..."); Particles.deleteParticle(myShip); - print("endGame() ... Particles.deleteParticle(myShip)... myShip.id="+myShip.id); + print("cleanupGame() ... Particles.deleteParticle(myShip)... myShip.id="+myShip.id); for (var row = 0; row < numberOfRows; row++) { for (var column = 0; column < invadersPerRow; column++) { Particles.deleteParticle(invaders[row][column]); - print("endGame() ... Particles.deleteParticle(invaders[row][column])... invaders[row][column].id="+invaders[row][column].id); + print("cleanupGame() ... Particles.deleteParticle(invaders[row][column])... invaders[row][column].id=" + +invaders[row][column].id); } } @@ -121,6 +136,12 @@ function endGame() { } Script.stop(); } +Script.scriptEnding.connect(cleanupGame); + +function endGame() { + print("ending game..."); + Script.stop(); +} function moveShipTo(position) { myShip = Particles.identifyParticle(myShip);