From c3dfea47122abd200dcbd257af5003e603c61033 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:26:24 -0700 Subject: [PATCH 1/8] initial files --- .../toys/ping_pong_gun/createPingPongGun.js | 43 +++++ examples/toys/ping_pong_gun/pingPongGun.js | 154 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 examples/toys/ping_pong_gun/createPingPongGun.js create mode 100644 examples/toys/ping_pong_gun/pingPongGun.js diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js new file mode 100644 index 0000000000..350fe63d02 --- /dev/null +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -0,0 +1,43 @@ +// createPingPongGun.js +// +// Script Type: Entity Spawner +// Created by James B. Pollack on 9/30/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script creates a gun that shoots ping pong balls when you pull the trigger on a hand controller. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); + + +var scriptURL = Script.resolvePath('pingPongGun.js'); + +var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' +var COLLISION_HULL_URL = ''; +var center = Vec3.sum(Vec3.sum(MyAvatar.position, { + x: 0, + y: 0.5, + z: 0 +}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); + +var pingPongGun = Entities.addEntity({ + type: "Model", + modelURL: MODEL_URL, + position: center, + dimensions: { + x: 0.1, + y: 0.06, + z: 0.03 + }, + collisionsWillMove: true, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL +}); + +function cleanUp() { + +} +Script.scriptEnding.connect(cleanup) \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js new file mode 100644 index 0000000000..48c0347d98 --- /dev/null +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -0,0 +1,154 @@ +// pingPongGun.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn on 9/21/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script shoots a ping pong ball. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +(function() { + + Script.include("../../libraries/utils.js"); + + var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + function PingPongGun() { + return; + } + + //if the trigger value goes below this value, reload the gun. + var RELOAD_THRESHOLD = 0.7; + + var GUN_TIP_OFFSET = 0.095; + // Evaluate the world light entity positions and orientations from the model ones + function evalLightWorldTransform(modelPos, modelRot) { + + return { + p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), + q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) + }; + } + + PingPongGun.prototype = { + hand: null, + whichHand: null, + gunTipPosition: null, + setRightHand: function() { + this.hand = 'RIGHT'; + }, + + setLeftHand: function() { + this.hand = 'LEFT'; + }, + + startNearGrab: function() { + setWhichHand(); + }, + + setWhichHand: function() { + this.whichHand = this.hand; + }, + + continueNearGrab: function() { + if (this.whichHand === null) { + //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten + this.setWhichHand(); + } else { + this.checkTriggerPressure(this.whichHand); + } + }, + + releaseGrab: function() { + + }, + + checkTriggerPressure: function(gunHand) { + var handClickString = gunHand + "_HAND_CLICK"; + + var handClick = Controller.findAction(handClickString); + + this.triggerValue = Controller.getActionValue(handClick); + + if (this.triggerValue < RELOAD_THRESHOLD) { + this.canShoot = true; + } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { + var gunProperties = Entities.getEntityProperties(this.entityID,["position","rotation"]) + this.shootBall(gunProperties); + this.canShoot = false; + } + return; + }, + + shootBall: function(gunProperties,triggerValue) { + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); + //forwardVec = Vec3.normalize(forwardVec); + + var properties = { + type: 'Sphere' + color: { + red: 0, + green: 0, + blue: 255 + }, + dimensions: { + x: 0.04, + y: 0.04, + z: 0.04 + }, + linearDamping: 0.2, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + rotation:gunProperties.rotation, + position: this.gunTipPosition, + velocity: velocity, + lifetime: 10 + }; + var pingPongBall = Entities.addEntity(properties); + }, + + playSoundAtCurrentPosition: function(playOnSound) { + var position = Entities.getEntityProperties(this.entityID, "position").position; + + var audioProperties = { + volume: 0.25, + position: position + }; + + if (playOnSound) { + Audio.playSound(this.ON_SOUND, audioProperties); + } else { + Audio.playSound(this.OFF_SOUND, audioProperties); + } + }, + + getGunTipPosition: function(properties) { + //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position + var upVector = Quat.getUp(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_OFFSET); + var wandTipPosition = Vec3.sum(properties.position, upOffset); + return wandTipPosition; + }, + preload: function(entityID) { + this.entityID = entityID; + this.ON_SOUND = SoundCache.getSound(SHOOT_SOUND_URL); + + }, + + unload: function() { + + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new Flashlight(); +}); \ No newline at end of file From 99fbed6143c17d9061b65889538808fe6ba15272 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:49:47 -0700 Subject: [PATCH 2/8] mostly working --- .../toys/ping_pong_gun/createPingPongGun.js | 11 +-- examples/toys/ping_pong_gun/pingPongGun.js | 69 ++++++++++--------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index 350fe63d02..d045516fc4 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -15,7 +15,8 @@ Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' -var COLLISION_HULL_URL = ''; +var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, @@ -25,6 +26,9 @@ var center = Vec3.sum(Vec3.sum(MyAvatar.position, { var pingPongGun = Entities.addEntity({ type: "Model", modelURL: MODEL_URL, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL, position: center, dimensions: { x: 0.1, @@ -32,12 +36,9 @@ var pingPongGun = Entities.addEntity({ z: 0.03 }, collisionsWillMove: true, - shapeType: 'compound', - compoundShapeURL: COLLISION_HULL_URL, - script: scriptURL }); function cleanUp() { - +Entities.deleteEntity(pingPongGun); } Script.scriptEnding.connect(cleanup) \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 48c0347d98..415b62c71e 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -14,7 +14,6 @@ Script.include("../../libraries/utils.js"); var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) @@ -24,21 +23,21 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.7; - var GUN_TIP_OFFSET = 0.095; - // Evaluate the world light entity positions and orientations from the model ones - function evalLightWorldTransform(modelPos, modelRot) { + // // Evaluate the world light entity positions and orientations from the model ones + // function evalLightWorldTransform(modelPos, modelRot) { - return { - p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), - q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) - }; - } + // return { + // p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), + // q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) + // }; + // } PingPongGun.prototype = { hand: null, whichHand: null, gunTipPosition: null, + canShoot: false, setRightHand: function() { this.hand = 'RIGHT'; }, @@ -48,7 +47,7 @@ }, startNearGrab: function() { - setWhichHand(); + this.setWhichHand(); }, setWhichHand: function() { @@ -76,21 +75,23 @@ this.triggerValue = Controller.getActionValue(handClick); if (this.triggerValue < RELOAD_THRESHOLD) { + print('RELOAD'); this.canShoot = true; } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { - var gunProperties = Entities.getEntityProperties(this.entityID,["position","rotation"]) + var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); this.shootBall(gunProperties); this.canShoot = false; } return; }, - shootBall: function(gunProperties,triggerValue) { - var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); - //forwardVec = Vec3.normalize(forwardVec); + shootBall: function(gunProperties, triggerValue) { + print('SHOOT BALL'); + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + forwardVec = Vec3.normalize(forwardVec); var properties = { - type: 'Sphere' + type: 'Sphere', color: { red: 0, green: 0, @@ -104,42 +105,46 @@ linearDamping: 0.2, gravity: { x: 0, - y: -9.8, + y: -0.05, z: 0 }, - rotation:gunProperties.rotation, - position: this.gunTipPosition, - velocity: velocity, + collisionsWillMove: true, + collisionSoundURL: SHOOTING_SOUND_URL, + rotation: gunProperties.rotation, + position: this.getGunTipPosition(gunProperties), + velocity: forwardVec, lifetime: 10 }; var pingPongBall = Entities.addEntity(properties); + var audioOptions = { + position: gunProperties.position + } + this.playSoundAtCurrentPosition(gunProperties.position); }, - playSoundAtCurrentPosition: function(playOnSound) { - var position = Entities.getEntityProperties(this.entityID, "position").position; + playSoundAtCurrentPosition: function(position) { var audioProperties = { volume: 0.25, position: position }; - if (playOnSound) { - Audio.playSound(this.ON_SOUND, audioProperties); - } else { - Audio.playSound(this.OFF_SOUND, audioProperties); - } + + Audio.playSound(this.SHOOTING_SOUND, audioProperties); + }, getGunTipPosition: function(properties) { //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position - var upVector = Quat.getUp(properties.rotation); - var upOffset = Vec3.multiply(upVector, GUN_TIP_OFFSET); - var wandTipPosition = Vec3.sum(properties.position, upOffset); - return wandTipPosition; + var frontVector = Quat.getFront(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_OFFSET); + var gunTipPosition = Vec3.sum(properties.position, frontOffset); + return gunTipPosition; }, preload: function(entityID) { + print('PRELOAD PING PONG GUN'); this.entityID = entityID; - this.ON_SOUND = SoundCache.getSound(SHOOT_SOUND_URL); + this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL); }, @@ -150,5 +155,5 @@ }; // entity scripts always need to return a newly constructed object of our type - return new Flashlight(); + return new PingPongGun(); }); \ No newline at end of file From ecad7f34f6afd1417e2f2a10863c90a47ded3821 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:58:21 -0700 Subject: [PATCH 3/8] moar --- examples/toys/ping_pong_gun/pingPongGun.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 415b62c71e..c3d10e7198 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -86,21 +86,20 @@ }, shootBall: function(gunProperties, triggerValue) { - print('SHOOT BALL'); var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); - forwardVec = Vec3.normalize(forwardVec); + // forwardVec = Vec3.normalize(forwardVec); var properties = { type: 'Sphere', color: { - red: 0, - green: 0, + red: 255, + green: 255, blue: 255 }, dimensions: { - x: 0.04, - y: 0.04, - z: 0.04 + x: 0.02, + y: 0.02, + z: 0.02 }, linearDamping: 0.2, gravity: { From 8bdf428f41663a74afc125a9c038e2dd3403f59e Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 11:21:51 -0700 Subject: [PATCH 4/8] First version of ping pong gun --- .../toys/ping_pong_gun/createPingPongGun.js | 4 +- examples/toys/ping_pong_gun/pingPongGun.js | 51 +++++++------------ 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index d045516fc4..1bf0415ebd 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -39,6 +39,6 @@ var pingPongGun = Entities.addEntity({ }); function cleanUp() { -Entities.deleteEntity(pingPongGun); + Entities.deleteEntity(pingPongGun); } -Script.scriptEnding.connect(cleanup) \ No newline at end of file +Script.scriptEnding.connect(cleanUp); \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index c3d10e7198..31681bc2d8 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -15,23 +15,14 @@ var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) function PingPongGun() { return; } //if the trigger value goes below this value, reload the gun. - var RELOAD_THRESHOLD = 0.7; - var GUN_TIP_OFFSET = 0.095; - // // Evaluate the world light entity positions and orientations from the model ones - // function evalLightWorldTransform(modelPos, modelRot) { - - // return { - // p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), - // q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) - // }; - // } + var RELOAD_THRESHOLD = 0.95; + var GUN_TIP_FWD_OFFSET = -0.056; + var GUN_TIP_UP_OFFSET = 0.001; PingPongGun.prototype = { hand: null, @@ -64,7 +55,7 @@ }, releaseGrab: function() { - + this.canShoot = false; }, checkTriggerPressure: function(gunHand) { @@ -75,7 +66,7 @@ this.triggerValue = Controller.getActionValue(handClick); if (this.triggerValue < RELOAD_THRESHOLD) { - print('RELOAD'); + // print('RELOAD'); this.canShoot = true; } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); @@ -85,10 +76,10 @@ return; }, - shootBall: function(gunProperties, triggerValue) { + shootBall: function(gunProperties) { var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); - // forwardVec = Vec3.normalize(forwardVec); - + forwardVec = Vec3.normalize(forwardVec); + forwardVec = Vec3.multiply(forwardVec, 2); var properties = { type: 'Sphere', color: { @@ -114,42 +105,36 @@ velocity: forwardVec, lifetime: 10 }; - var pingPongBall = Entities.addEntity(properties); - var audioOptions = { - position: gunProperties.position - } + + Entities.addEntity(properties); + this.playSoundAtCurrentPosition(gunProperties.position); }, playSoundAtCurrentPosition: function(position) { - var audioProperties = { volume: 0.25, position: position }; - Audio.playSound(this.SHOOTING_SOUND, audioProperties); - }, getGunTipPosition: function(properties) { //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position - var frontVector = Quat.getFront(properties.rotation); - var frontOffset = Vec3.multiply(frontVector, GUN_TIP_OFFSET); + var frontVector = Quat.getRight(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET); + var upVector = Quat.getRight(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET); var gunTipPosition = Vec3.sum(properties.position, frontOffset); + gunTipPosition = Vec3.sum(gunTipPosition, upOffset); return gunTipPosition; }, + preload: function(entityID) { - print('PRELOAD PING PONG GUN'); this.entityID = entityID; this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL); - - }, - - unload: function() { - - }, + } }; From 0865f94106111e1483fad157cb3ef8e6e8de37ef Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 11:31:33 -0700 Subject: [PATCH 5/8] magic numbers --- examples/toys/ping_pong_gun/pingPongGun.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 31681bc2d8..da7a4a6d28 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -15,14 +15,21 @@ var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; + function PingPongGun() { return; } //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.056; - var GUN_TIP_UP_OFFSET = 0.001; + var GUN_TIP_FWD_OFFSET = -0.08; + var GUN_TIP_UP_OFFSET = 0.020; + var GUN_FORCE = 5; + var BALL_GRAVITY = { + x: 0, + y: -1, + z: 0 + }; PingPongGun.prototype = { hand: null, @@ -79,7 +86,7 @@ shootBall: function(gunProperties) { var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - forwardVec = Vec3.multiply(forwardVec, 2); + forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { type: 'Sphere', color: { @@ -93,11 +100,7 @@ z: 0.02 }, linearDamping: 0.2, - gravity: { - x: 0, - y: -0.05, - z: 0 - }, + gravity: BALL_GRAVITY, collisionsWillMove: true, collisionSoundURL: SHOOTING_SOUND_URL, rotation: gunProperties.rotation, From c55d627e9bd33f302d4e33a1c323dfb07d2343ad Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 16:12:27 -0700 Subject: [PATCH 6/8] Different model, different sounds, release interval --- .../toys/ping_pong_gun/createPingPongGun.js | 6 +-- examples/toys/ping_pong_gun/pingPongGun.js | 54 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index 1bf0415ebd..d8509d8a63 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -31,9 +31,9 @@ var pingPongGun = Entities.addEntity({ script: scriptURL, position: center, dimensions: { - x: 0.1, - y: 0.06, - z: 0.03 + x:0.67, + y: 0.14, + z: 0.09 }, collisionsWillMove: true, }); diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index da7a4a6d28..0a589fb3fb 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -13,8 +13,7 @@ Script.include("../../libraries/utils.js"); - var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - + var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav'; function PingPongGun() { return; @@ -22,20 +21,36 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.08; - var GUN_TIP_UP_OFFSET = 0.020; - var GUN_FORCE = 5; + var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_UP_OFFSET = 0.040; + var GUN_FORCE = 15; + var BALL_RESTITUTION = 0.6; + var BALL_LINEAR_DAMPING = 0.4; var BALL_GRAVITY = { x: 0, - y: -1, + y: -9.8, z: 0 }; + var BALL_DIMENSIONS = { + x: 0.04, + y: 0.04, + z: 0.04 + } + + + var BALL_COLOR = { + red: 255, + green: 255, + blue: 255 + } + PingPongGun.prototype = { hand: null, whichHand: null, gunTipPosition: null, canShoot: false, + canShootTimeout: null, setRightHand: function() { this.hand = 'RIGHT'; }, @@ -53,16 +68,23 @@ }, continueNearGrab: function() { + if (this.whichHand === null) { //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); } else { + if (this.canShootTimeout !== null) { + Script.clearTimeout(this.canShootTimeout); + } this.checkTriggerPressure(this.whichHand); } }, releaseGrab: function() { - this.canShoot = false; + var _t = this; + this.canShootTimeout = Script.setTimeout(function() { + _t.canShoot = false; + }, 250) }, checkTriggerPressure: function(gunHand) { @@ -89,20 +111,12 @@ forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { type: 'Sphere', - color: { - red: 255, - green: 255, - blue: 255 - }, - dimensions: { - x: 0.02, - y: 0.02, - z: 0.02 - }, - linearDamping: 0.2, + color: BALL_COLOR, + dimensions: BALL_DIMENSIONS, + linearDamping: BALL_LINEAR_DAMPING, gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, collisionsWillMove: true, - collisionSoundURL: SHOOTING_SOUND_URL, rotation: gunProperties.rotation, position: this.getGunTipPosition(gunProperties), velocity: forwardVec, @@ -116,7 +130,7 @@ playSoundAtCurrentPosition: function(position) { var audioProperties = { - volume: 0.25, + volume: 0.1, position: position }; From 861aa91572d6c56c1f9357b641be9149a283eb47 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 12:27:45 -0700 Subject: [PATCH 7/8] shoot out of the right end of the gun --- examples/toys/ping_pong_gun/pingPongGun.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 0a589fb3fb..a980fc1bd3 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -21,7 +21,7 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_FWD_OFFSET = 0.45; var GUN_TIP_UP_OFFSET = 0.040; var GUN_FORCE = 15; var BALL_RESTITUTION = 0.6; @@ -106,7 +106,7 @@ }, shootBall: function(gunProperties) { - var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, -90, 0))); forwardVec = Vec3.normalize(forwardVec); forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { From 4a7e3c66bd80eb1dbe2b6dc6ad7b2151d0276e9f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 15:05:25 -0700 Subject: [PATCH 8/8] Update createPingPongGun.js use relative paths --- examples/toys/ping_pong_gun/createPingPongGun.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index d8509d8a63..4b7ed27643 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -9,8 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); - +Script.include("../../utilities.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); @@ -41,4 +40,4 @@ var pingPongGun = Entities.addEntity({ function cleanUp() { Entities.deleteEntity(pingPongGun); } -Script.scriptEnding.connect(cleanUp); \ No newline at end of file +Script.scriptEnding.connect(cleanUp);