From 934575a78a1216c89c8636b3d7aa352d82e259d4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Oct 2015 16:46:07 -0700 Subject: [PATCH] Refactor pitching.js --- examples/baseball/pitching.js | 332 ++++++++++++++-------------------- 1 file changed, 139 insertions(+), 193 deletions(-) diff --git a/examples/baseball/pitching.js b/examples/baseball/pitching.js index b419e8935c..5cb29ac5d7 100644 --- a/examples/baseball/pitching.js +++ b/examples/baseball/pitching.js @@ -1,16 +1,25 @@ -//var PITCH_THUNK_SOUND_URL = "file:///C:/Users/Ryan/Downloads/323725__reitanna__thunk.wav"; -var PITCH_THUNK_SOUND_URL = "file:///C:/Users/Ryan/Downloads/thunk.wav"; +Script.include("line.js"); + +var AUDIO = { + crowdBoos: [ + SoundCache.getSound("atp:c632c92b166ade60aa16b23ff1dfdf712856caeb83bd9311980b2d5edac821af.wav", false) + ], + crowdCheers: [ + SoundCache.getSound("atp:0821bf2ac60dd2f356dfdd948e8bb89c23984dc3584612f6c815765154f02cae.wav", false), + SoundCache.getSound("atp:b8044401a846ed29f881a0b9b80cf1ba41f26327180c28fc9c70d144f9b70045.wav", false), + ], + batHit: [ + SoundCache.getSound("atp:6f0b691a0c9c9ece6557d97fe242b1faec4020fe26efc9c17327993b513c5fe5.wav", false), + SoundCache.getSound("atp:5be5806205158ebdc5c3623ceb7ae73315028b51ffeae24292aff7042e3fa6a9.wav", false), + SoundCache.getSound("atp:e68661374e2145c480809c26134782aad11e0de456c7802170c7abccc4028873.wav", false), + SoundCache.getSound("atp:787e3c9af17dd3929527787176ede83d6806260e63ddd5a4cef48cd22e32c6f7.wav", false), + SoundCache.getSound("atp:fc65383431a6238c7a4749f0f6f061f75a604ed5e17d775ab1b2955609e67ebb.wav", false), + ] +} + var PITCH_THUNK_SOUND_URL = "http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav"; var pitchSound = SoundCache.getSound(PITCH_THUNK_SOUND_URL, false); -function info(message) { - print("[INFO] " + message); -} - -function error(message) { - print("[ERROR] " + message); -} - var PITCHING_MACHINE_URL = "atp:87d4879530b698741ecc45f6f31789aac11f7865a2c3bec5fe9b061a182c80d4.fbx"; var PITCHING_MACHINE_OUTPUT_OFFSET_PCT = { x: 0.0, @@ -23,7 +32,7 @@ var PITCHING_MACHINE_PROPERTIES = { position: { x: 0, y: 0.8, - z: -22.3, + z: -18.3, }, velocity: { x: 0, @@ -51,12 +60,13 @@ var PITCHING_MACHINE_PROPERTIES = { shapeType: "Box", }; PITCHING_MACHINE_PROPERTIES.dimensions = Vec3.multiply(2.5, PITCHING_MACHINE_PROPERTIES.dimensions); - +var DISTANCE_FROM_PLATE = PITCHING_MACHINE_PROPERTIES.position.z; var PITCH_RATE = 5000; var BASEBALL_MODEL_URL = "atp:7185099f1f650600ca187222573a88200aeb835454bd2f578f12c7fb4fd190fa.fbx"; -var BASEBALL_SPEED = 2.7; +var BASEBALL_MIN_SPEED = 2.7; +var BASEBALL_MAX_SPEED = 5.7; var BASEBALL_RADIUS = 0.07468; var BASEBALL_PROPERTIES = { name: "Baseball", @@ -78,13 +88,17 @@ var BASEBALL_PROPERTIES = { x: 17.0, y: 0, z: -8.0, + + x: 0.0, + y: 0, + z: 0.0, }, angularDamping: 0.0, damping: 0.0, restitution: 0.5, friction: 0.0, lifetime: 20, - collisionSoundURL: PITCH_THUNK_SOUND_URL, + //collisionSoundURL: PITCH_THUNK_SOUND_URL, gravity: { x: 0, y: 0,//-9.8, @@ -107,23 +121,44 @@ function shallowCopy(obj) { } function randomInt(low, high) { - return low + (Math.random() * (high - low)); + return Math.floor(randomFloat(low, high)); +} + +function randomFloat(low, high) { + if (high === undefined) { + high = low; + low = 0; + } + return low + Math.random() * (high - low); } var ACCELERATION_SPREAD = 10.15; -function createBaseball(position, velocity, ballScale) { +function Baseball(position, velocity, ballScale) { + var self = this; + + // Setup entity properties var properties = shallowCopy(BASEBALL_PROPERTIES); properties.position = position; properties.velocity = velocity; - properties.acceleration = { + /* + properties.gravity = { x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), z: 0.0, }; + */ properties.dimensions = Vec3.multiply(ballScale, properties.dimensions); - var entityID = Entities.addEntity(properties); - Script.addEventHandler(entityID, "collisionWithEntity", buildBaseballHitCallback(entityID)); + + // Create entity + this.entityID = Entities.addEntity(properties); + this.trail = null; + this.onHit = function() { return true; }; + this.hasBeenHit = false; + + this.boundCollisionCallback = function(a, b, c) { self.collisionCallback.call(self, a, b, c); }; + Script.addEventHandler(this.entityID, "collisionWithEntity", this.boundCollisionCallback); + /* if (false && Math.random() < 0.5) { for (var i = 0; i < 50; i++) { Script.setTimeout(function() { @@ -137,26 +172,39 @@ function createBaseball(position, velocity, ballScale) { }, i * 100); } } - return entityID; + */ } -var buildBaseballHitCallback = function(entityID) { - var f = function(entityA, entityB, collision) { - print("Got baseball hit callback"); - var properties = Entities.getEntityProperties(entityID, ['position', 'velocity']); - var line = new InfiniteLine(properties.position, { red: 255, green: 128, blue: 89 }); +Baseball.prototype = { + collisionCallback: function(entityA, entityB, collision) { + var self = this; + + this.hasBeenHit = true; + var properties = Entities.getEntityProperties(this.entityID, ['position', 'velocity']); + this.trail = new InfiniteLine(properties.position, { red: 255, green: 128, blue: 89 }); var lastPosition = properties.position; - Vec3.print("Velocity", properties.velocity); - Vec3.print("VelocityChange", collision.velocityChange); - Script.setInterval(function() { - var properties = Entities.getEntityProperties(entityID, ['position']); + //Vec3.print("Velocity", properties.velocity); + //Vec3.print("VelocityChange", collision.velocityChange); + var speed = Vec3.length(properties.velocity); + playRandomSound(AUDIO.batHit, { + position: properties.position, + volume: 2.0 + }); + var sounds = null; + if (speed < 5.0) { + sounds = AUDIO.crowdBoos; + } else { + sounds = AUDIO.crowdCheers; + } + var self = this; + this.trailInterval = Script.setInterval(function() { + var properties = Entities.getEntityProperties(self.entityID, ['position']); if (Vec3.distance(properties.position, lastPosition)) { - line.enqueuePoint(properties.position); + self.trail.enqueuePoint(properties.position); lastPosition = properties.position; } }, 50); - var speed = Vec3.length(properties.velocity); - Entities.editEntity(entityID, { + Entities.editEntity(self.entityID, { velocity: Vec3.multiply(2, properties.velocity), gravity: { x: 0, @@ -164,12 +212,35 @@ var buildBaseballHitCallback = function(entityID) { z: 0 } }); - print("Baseball hit!"); - Script.removeEventHandler(entityID, "collisionWithEntity", f); - }; - return f; + + var removeHandler = this.onHit(entityB, collision); + if (removeHandler) { + Script.removeEventHandler(self.entityID, "collisionWithEntity", self.boundCollisionCallback); + } + }, + cleanupTrail: function() { + if (this.trail) { + Script.clearInterval(this.trailInterval); + this.trailInterval = null; + + this.trail.destroy(); + this.trail = null; + } + } } +function playRandomSound(sounds, options) { + if (options === undefined) { + options = { + volume: 1.0, + position: MyAvatar.position, + } + } + Audio.playSound(sounds[randomInt(sounds.length)], options); +} + +var lastTrail = null; + function vec3Mult(a, b) { return { @@ -179,8 +250,14 @@ function vec3Mult(a, b) { }; } +var lastBall = null; var injector = null; + function pitchBall() { + if (lastBall) { + lastBall.cleanupTrail(); + } + var machineProperties = Entities.getEntityProperties(pitchingMachineID, ["dimensions", "position", "rotation"]); var pitchFromPositionBase = machineProperties.position; var pitchFromOffset = vec3Mult(machineProperties.dimensions, PITCHING_MACHINE_OUTPUT_OFFSET_PCT); @@ -189,7 +266,32 @@ function pitchBall() { var pitchDirection = Quat.getFront(machineProperties.rotation); var ballScale = machineProperties.dimensions.x / PITCHING_MACHINE_PROPERTIES.dimensions.x; print("Creating baseball"); - var ballEntityID = createBaseball(pitchFromPosition, Vec3.multiply(BASEBALL_SPEED, pitchDirection), ballScale); + + var speed = randomFloat(BASEBALL_MIN_SPEED, BASEBALL_MAX_SPEED) + var timeToPassPlate = (DISTANCE_FROM_PLATE + 1.0) / speed; + + var baseball = new Baseball(pitchFromPosition, Vec3.multiply(speed, pitchDirection), ballScale); + lastBall = baseball; + + baseball.onHit = function(entityB, collision) { + var properties = Entities.getEntityProperties(entityB, ["name"]); + var name = properties.name; + print("Hit: " + name); + if (name == "backstop") { + print("STRIKE"); + } else if (name == "bat") { + print("HIT"); + Script.setTimeout(function() { + playRandomSound(sounds, { + position: { x: 0 ,y: 0, z: 0 }, + volume: 1.0, + }); + }, 500); + } + //Script.clearTimeout(strikeTimeout); + return true; + } + if (!injector) { injector = Audio.playSound(pitchSound, { position: pitchFromPosition, @@ -209,159 +311,3 @@ Script.setInterval(pitchBall, PITCH_RATE); -/****************************************************************************** - * PolyLine - *****************************************************************************/ -var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 }; -var MAX_LINE_LENGTH = 40; // This must be 2 or greater; -var PolyLine = function(position, color, defaultStrokeWidth) { - //info("Creating polyline"); - //Vec3.print("New line at", position); - this.position = position; - this.color = color; - this.defaultStrokeWidth = 0.10; - this.points = [ - { x: 0, y: 0, z: 0 }, - ]; - this.strokeWidths = [ - this.defaultStrokeWidth, - ] - this.normals = [ - { x: 1, y: 0, z: 0 }, - ] - this.entityID = Entities.addEntity({ - type: "PolyLine", - position: position, - linePoints: this.points, - normals: this.normals, - strokeWidths: this.strokeWidths, - dimensions: LINE_DIMENSIONS, - color: color, - lifetime: 20, - }); -}; - -PolyLine.prototype.enqueuePoint = function(position) { - if (this.isFull()) { - error("Hit max PolyLine size"); - return; - } - - //Vec3.print("pos", position); - //info("Number of points: " + this.points.length); - - position = Vec3.subtract(position, this.position); - this.points.push(position); - this.normals.push({ x: 1, y: 0, z: 0 }); - this.strokeWidths.push(this.defaultStrokeWidth); - Entities.editEntity(this.entityID, { - linePoints: this.points, - normals: this.normals, - strokeWidths: this.strokeWidths, - }); -}; - -PolyLine.prototype.dequeuePoint = function() { - if (this.points.length == 0) { - error("Hit min PolyLine size"); - return; - } - - this.points = this.points.slice(1); - this.normals = this.normals.slice(1); - this.strokeWidths = this.strokeWidths.slice(1); - - Entities.editEntity(this.entityID, { - linePoints: this.points, - normals: this.normals, - strokeWidths: this.strokeWidths, - }); -}; - -PolyLine.prototype.getFirstPoint = function() { - return Vec3.sum(this.position, this.points[0]); -}; - -PolyLine.prototype.getLastPoint = function() { - return Vec3.sum(this.position, this.points[this.points.length - 1]); -}; - -PolyLine.prototype.getSize = function() { - return this.points.length; -} - -PolyLine.prototype.isFull = function() { - return this.points.length >= MAX_LINE_LENGTH; -}; - -PolyLine.prototype.destroy = function() { - Entities.deleteEntity(this.entityID); - this.points = []; -}; - - -/****************************************************************************** - * InfiniteLine - *****************************************************************************/ -InfiniteLine = function(position, color) { - this.position = position; - this.color = color; - this.lines = [new PolyLine(position, color)]; - this.size = 0; -}; - -InfiniteLine.prototype.enqueuePoint = function(position) { - var currentLine; - - if (this.lines.length == 0) { - currentLine = new PolyLine(position, this.color); - this.lines.push(currentLine); - } else { - currentLine = this.lines[this.lines.length - 1]; - } - - if (currentLine.isFull()) { - //info("Current line is full, creating new line"); - //Vec3.print("Last line is", currentLine.getLastPoint()); - //Vec3.print("New line is", position); - var newLine = new PolyLine(currentLine.getLastPoint(), this.color); - this.lines.push(newLine); - currentLine = newLine; - } - - currentLine.enqueuePoint(position); - - ++this.size; -}; - -InfiniteLine.prototype.dequeuePoint = function() { - if (this.lines.length == 0) { - error("Trying to dequeue from InfiniteLine when no points are left"); - return; - } - - var lastLine = this.lines[0]; - lastLine.dequeuePoint(); - - if (lastLine.getSize() <= 1) { - this.lines = this.lines.slice(1); - } - - --this.size; -}; - -InfiniteLine.prototype.getFirstPoint = function() { - return this.lines.length > 0 ? this.lines[0].getFirstPoint() : null; -}; - -InfiniteLine.prototype.getLastPoint = function() { - return this.lines.length > 0 ? this.lines[lines.length - 1].getLastPoint() : null; -}; - -InfiniteLine.prototype.destroy = function() { - for (var i = 0; i < this.lines.length; ++i) { - this.lines[i].destroy(); - } - - this.size = 0; -};