diff --git a/scripts/tutorials/entity_scripts/balloonSpawner/balloonParty.json b/scripts/tutorials/entity_scripts/balloonSpawner/balloonParty.json new file mode 100644 index 0000000000..c0457dec6d --- /dev/null +++ b/scripts/tutorials/entity_scripts/balloonSpawner/balloonParty.json @@ -0,0 +1,20 @@ +{ + "Entities": [ + { + "description": "Spawns balloons", + "dimensions": { + "x": 2, + "y": 0.1, + "z": 2 + }, + "name": "Balloon Spawner", + "serverScripts": "http://mpassets.highfidelity.com/8410ef73-9506-4dc7-b364-0174998a859e-v1/Scripts/spawnBalloons.js", + "type": "Shape", + "shape": "Cube", + "visible": "false", + "collisionless": "true", + "userData": "{\"spawnRate\":1000,\"xRangeMax\":1,\"zRangeMax\":1,\"gravityCoefficient\":0.25,\"balloonLifetime\":10,\"spawnDuration\":300,\"spawnMusicURL\":\"http://mpassets.highfidelity.com/8410ef73-9506-4dc7-b364-0174998a859e-v1/Audio/Blue_Skies.wav\",\"spawnMusicVolume\":0.1}" + } + ], + "Version": 63 +} \ No newline at end of file diff --git a/scripts/tutorials/entity_scripts/balloonSpawner/spawnBalloons.js b/scripts/tutorials/entity_scripts/balloonSpawner/spawnBalloons.js new file mode 100644 index 0000000000..3aa956491e --- /dev/null +++ b/scripts/tutorials/entity_scripts/balloonSpawner/spawnBalloons.js @@ -0,0 +1,224 @@ +"use strict"; + +// +// spawnBalloons.js +// +// Created by Johnathan Franck on 3 May 2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function () { + var RED_BALLOON_URL = Script.resolvePath("../Models/redBalloon.fbx"); + var BLUE_BALLOON_URL = Script.resolvePath("../Models/blueBalloon.fbx"); + var GREEN_BALLOON_URL = Script.resolvePath("../Models/greenBalloon.fbx"); + var YELLOW_BALLOON_URL = Script.resolvePath("../Models/yellowBalloon.fbx"); + var ORANGE_BALLOON_URL = Script.resolvePath("../Models/orangeBalloon.fbx"); + var CYAN_BALLOON_URL = Script.resolvePath("../Models/cyanBalloon.fbx"); + var PURPLE_BALLOON_URL = Script.resolvePath("../Models/purpleBalloon.fbx"); + //'Blue Skies' by Silent Partner from youtube audio library. Listed as attribution not required + var SPAWN_MUSIC_URL = Script.resolvePath("../Audio/Blue_Skies.wav"); + + var BALLOON_COLORS = ["red", "blue", "green", "yellow", "orange", "cyan", "purple"]; + var BALLOON_URLS = [RED_BALLOON_URL, BLUE_BALLOON_URL, GREEN_BALLOON_URL, + YELLOW_BALLOON_URL, ORANGE_BALLOON_URL, CYAN_BALLOON_URL, PURPLE_BALLOON_URL]; + + var NUM_COLORS = 7; + var COUNTDOWN_SECONDS = 9; + //Lowering the spawn rate below 10 spawns so many balloons that the interface slows down + var MIN_SPAWN_RATE = 10; + var MILLISECONDS_IN_SECOND = 1000; + + var _this = this; + var spawnRate = 2000; + var xRangeMax = 1; + var zRangeMax = 1; + var gravityCoefficient = 0.25; + var balloonLifetime = 10; + var spawnDuration = 300; + var musicInjector; + var spawnIntervalID; + var spawnMusic; + var countdownIntervalID; + var countdownEntityID; + + _this.preload = function (pEntityID) { + var parentProperties = Entities.getEntityProperties(pEntityID, ["userData"]), + spawnMusicURL, + spawnerSettings; + if (parentProperties.userData) { + spawnerSettings = JSON.parse(parentProperties.userData); + } + spawnMusicURL = spawnerSettings.spawnMusicURL ? spawnerSettings.spawnMusicURL : SPAWN_MUSIC_URL; + spawnMusic = SoundCache.getSound(spawnMusicURL); + + _this.startCountdown(pEntityID); + }; + + _this.startCountdown = function (pEntityID) { + var countdownSeconds = COUNTDOWN_SECONDS, + parentProperties = Entities.getEntityProperties(pEntityID, ["position"]), + countdownEntityProperties; + + countdownEntityProperties = { + type: "Text", + text: countdownSeconds, + lineHeight: 0.71, + dimensions: { + x: 0.5, + y: 1, + z: 0.01 + }, + textColor: { + red: 0, + blue: 255, + green: 0 + }, + backgroundColor: { + red: 255, + blue: 255, + green: 255 + }, + parentID: pEntityID, + position: parentProperties.position + }; + + countdownEntityID = Entities.addEntity(countdownEntityProperties); + countdownIntervalID = Script.setInterval(function () { + countdownSeconds -= 1; + if (countdownSeconds < 0) { + Script.clearInterval(countdownIntervalID); + Entities.deleteEntity(countdownEntityID); + } else { + Entities.editEntity(countdownEntityID, {"text": countdownSeconds}); + if (countdownSeconds === 0) { + _this.spawnBalloons(pEntityID); + } + } + }, 1000); + }; + + _this.spawnBalloons = function (pEntityID) { + var parentProperties = Entities.getEntityProperties(pEntityID, ["position", "userData"]), + spawnerSettings, + spawnMusicVolume, + spawnCount = 0; + + if (parentProperties.userData) { + spawnerSettings = JSON.parse(parentProperties.userData); + } + + xRangeMax = !isNaN(spawnerSettings.xRangeMax) ? spawnerSettings.xRangeMax : xRangeMax; + zRangeMax = !isNaN(spawnerSettings.zRangeMax) ? spawnerSettings.zRangeMax : zRangeMax; + gravityCoefficient = !isNaN(spawnerSettings.gravityCoefficient) ? spawnerSettings.gravityCoefficient : gravityCoefficient; + spawnDuration = !isNaN(spawnerSettings.spawnDuration) ? spawnerSettings.spawnDuration : spawnDuration; + balloonLifetime = !isNaN(spawnerSettings.balloonLifetime) ? spawnerSettings.balloonLifetime : balloonLifetime; + spawnRate = !isNaN(spawnerSettings.spawnRate) ? spawnerSettings.spawnRate : spawnRate; + spawnMusicVolume = !isNaN(spawnerSettings.spawnMusicVolume) ? spawnerSettings.spawnMusicVolume : 0.1; + + if (spawnRate < MIN_SPAWN_RATE) { + spawnRate = MIN_SPAWN_RATE; + print("The lowest balloon spawn rate allowed is " + MIN_SPAWN_RATE); + } + + if (spawnMusic.downloaded) { + musicInjector = Audio.playSound(spawnMusic, { + position: parentProperties.position, + volume: spawnMusicVolume, + loop: true + }); + } + + spawnIntervalID = Script.setInterval(function () { + var colorID = Math.floor(Math.random() * NUM_COLORS), + color = BALLOON_COLORS[colorID], + balloonURL = BALLOON_URLS[colorID], + balloonPosition = {}, + balloonProperties; + + spawnCount ++; + //Randomize balloon spawn position + balloonPosition.y = parentProperties.position.y + 0.5; + balloonPosition.x = parentProperties.position.x + (Math.random() - 0.5) * 2 * xRangeMax; + balloonPosition.z = parentProperties.position.z + (Math.random() - 0.5) * 2 * zRangeMax; + + balloonProperties = { + position: balloonPosition, + lifetime: balloonLifetime, + angularVelocity: { + x: -0.03654664754867554, + y: -0.4030083637684583664 + Math.random(), + z: 0.02576472796499729 + }, + collisionsWillMove: 1, + density: 100, + description: "A happy " + color + " balloon", + dimensions: { + x: 0.3074322044849396, + y: 0.40930506587028503, + z: 0.30704551935195923 + }, + dynamic: 1, + gravity: { + x: 0, + y: gravityCoefficient, + z: 0 + }, + modelURL: balloonURL, + name: color + " balloon", + queryAACube: { + scale: 0.596927285194397, + x: -0.2984636425971985, + y: -0.2984636425971985, + z: -0.2984636425971985 + }, + restitution: 0.9900000095367432, + rotation: { + w: -0.10368101298809052, + x: 0.5171623826026917, + y: 0.1211432576179504, + z: -0.670971691608429 + Math.random() + }, + shapeType: "sphere", + type : "Model", + velocity: { + x: 0.003623033408075571, + y: 0.0005839366931468248, + z: -0.01512028019875288 + } + }; + Entities.addEntity(balloonProperties); + + //Clean up after spawnDuration + if (spawnCount * spawnRate / MILLISECONDS_IN_SECOND > spawnDuration) { + _this.cleanUp(pEntityID); + } + }, spawnRate); + }; + + _this.unload = function () { + _this.cleanUp(); + }; + + _this.cleanUp = function (pEntityID) { + if (spawnIntervalID ) { + Script.clearInterval(spawnIntervalID); + } + if (countdownIntervalID) { + Script.clearInterval(countdownIntervalID); + } + if (countdownEntityID) { + Entities.deleteEntity(countdownEntityID); + } + if (musicInjector !== undefined && musicInjector.isPlaying) { + musicInjector.stop(); + musicInjector = undefined; + } + if (pEntityID) { + Entities.deleteEntity(pEntityID); + } + }; + +});