From 9c3348bea55477ba5a32855e4bac78158004d2e7 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Thu, 1 Jul 2021 16:18:18 +0530 Subject: [PATCH] music and more sounds --- src/AudioManager.hx | 31 +++++++++++---- src/Main.hx | 1 + src/Marble.hx | 81 ++++++++++++++++++++++++++++++++++++++- src/MarbleGame.hx | 8 ++++ src/MarbleWorld.hx | 1 + src/Mission.hx | 1 + src/gui/GuiButton.hx | 17 ++++++++ src/gui/GuiControl.hx | 16 ++++++++ src/gui/GuiSlider.hx | 10 ++++- src/gui/OptionsDlg.hx | 4 ++ src/gui/PlayMissionGui.hx | 3 ++ 11 files changed, 163 insertions(+), 10 deletions(-) diff --git a/src/AudioManager.hx b/src/AudioManager.hx index 161ed44c..590028d1 100644 --- a/src/AudioManager.hx +++ b/src/AudioManager.hx @@ -1,5 +1,7 @@ package src; +import src.ResourceLoader; +import hxd.snd.SoundGroup; import h3d.scene.Scene; import hxd.snd.effect.Spatialization; import h3d.Vector; @@ -9,15 +11,15 @@ import hxd.snd.ChannelGroup; class AudioManager { static var manager:hxd.snd.Manager; - static var soundChannel:hxd.snd.ChannelGroup; - static var musicChannel:hxd.snd.ChannelGroup; + static var soundGroup:hxd.snd.SoundGroup; + static var musicGroup:hxd.snd.SoundGroup; public static function init() { AudioManager.manager = hxd.snd.Manager.get(); - AudioManager.soundChannel = new ChannelGroup("sound"); - soundChannel.volume = Settings.optionsSettings.soundVolume; - AudioManager.musicChannel = new ChannelGroup("music"); - musicChannel.volume = Settings.optionsSettings.musicVolume; + AudioManager.soundGroup = new SoundGroup("sound"); + soundGroup.volume = Settings.optionsSettings.soundVolume; + AudioManager.musicGroup = new SoundGroup("music"); + musicGroup.volume = Settings.optionsSettings.musicVolume; } public static function update(scene3d:Scene) { @@ -25,7 +27,7 @@ class AudioManager { } public static function playSound(sound:Sound, ?position:Vector, ?loop:Bool = false) { - var ch = AudioManager.manager.play(sound, soundChannel); + var ch = AudioManager.manager.play(sound, null, soundGroup); ch.loop = loop; if (position != null) { var audioSrc = new Spatialization(); @@ -35,7 +37,20 @@ class AudioManager { return ch; } + public static function playShell() { + AudioManager.manager.stopByName("music"); + var snd = ResourceLoader.getAudio("data/sound/shell.ogg"); + var ch = AudioManager.manager.play(snd, null, musicGroup); + ch.loop = true; + } + + public static function playMusic(music:Sound) { + AudioManager.manager.stopByName("music"); + var ch = AudioManager.manager.play(music, null, musicGroup); + ch.loop = true; + } + public static function stopAllSounds() { - manager.stopByName("sound"); + AudioManager.manager.stopByName("sound"); } } diff --git a/src/Main.hx b/src/Main.hx index 01a50392..30d1d400 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -18,6 +18,7 @@ class Main extends hxd.App { Settings.init(); AudioManager.init(); + AudioManager.playShell(); marbleGame = new MarbleGame(s2d, s3d); MarbleGame.canvas.setContent(new MainMenuGui()); // world = new MarbleWorld(s3d, s2d, mission); diff --git a/src/Marble.hx b/src/Marble.hx index 2bfe006d..8c727a45 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1,5 +1,8 @@ package src; +import hxd.snd.effect.Pitch; +import hxd.snd.effect.Spatialization; +import hxd.snd.Channel; import shapes.TriangleBumper; import shapes.RoundBumper; import src.Util; @@ -142,6 +145,7 @@ class Marble extends GameObject { public var _mass:Float = 1; public var contacts:Array = []; + public var bestContact:CollisionInfo; public var contactEntities:Array = []; var queuedContacts:Array = []; @@ -161,6 +165,13 @@ class Marble extends GameObject { var trailEmitterData:ParticleData; var trailEmitterNode:ParticleEmitter; + var rollSound:Channel; + var slipSound:Channel; + + var superbounceSound:Channel; + var shockabsorberSound:Channel; + var helicopterSound:Channel; + public var mode:Mode = Play; public var startPad:StartPad; @@ -189,6 +200,12 @@ class Marble extends GameObject { this.trailEmitterData = new ParticleData(); this.trailEmitterData.identifier = "MarbleTrailParticle"; this.trailEmitterData.texture = ResourceLoader.getTexture("data/particles/smoke.png"); + + this.rollSound = AudioManager.playSound(ResourceLoader.getAudio("data/sound/rolling_hard.wav"), this.getAbsPos().getPosition(), true); + this.slipSound = AudioManager.playSound(ResourceLoader.getAudio("data/sound/sliding.wav"), this.getAbsPos().getPosition(), true); + this.shockabsorberSound = AudioManager.playSound(ResourceLoader.getAudio("data/sound/superbounceactive.wav"), null, true); + this.superbounceSound = AudioManager.playSound(ResourceLoader.getAudio("data/sound/forcefield.wav"), null, true); + this.helicopterSound = AudioManager.playSound(ResourceLoader.getAudio("data/sound/use_gyrocopter.wav"), null, true); } public function init(level:MarbleWorld) { @@ -514,7 +531,7 @@ class Marble extends GameObject { } } } - var bestContact = (bestSurface != -1) ? contacts[bestSurface] : new CollisionInfo(); + bestContact = (bestSurface != -1) ? contacts[bestSurface] : null; var canJump = bestSurface != -1; if (canJump && m.jump) { var velDifference = this.velocity.sub(bestContact.velocity); @@ -649,6 +666,48 @@ class Marble extends GameObject { } } + function updateRollSound(contactPct:Float, slipAmount:Float) { + var rSpat = rollSound.getEffect(Spatialization); + rSpat.position = this.getAbsPos().getPosition(); + rSpat.referenceDistance = 5; + + var sSpat = slipSound.getEffect(Spatialization); + sSpat.position = this.getAbsPos().getPosition(); + sSpat.referenceDistance = 5; + + var rollVel = bestContact != null ? this.velocity.sub(bestContact.velocity) : this.velocity; + var scale = rollVel.length(); + scale /= this._maxRollVelocity; + + var rollVolume = 2 * scale; + if (rollVolume > 1) + rollVolume = 1; + if (contactPct < 0.05) + rollVolume = 0; + + var slipVolume = 0.0; + if (slipAmount > 0) { + slipVolume = slipAmount / 5; + if (slipVolume > 1) + slipVolume = 1; + rollVolume = (1 - slipVolume) * rollVolume; + } + + rollSound.volume = rollVolume; + slipSound.volume = slipVolume; + + if (rollSound.getEffect(Pitch) == null) { + rollSound.addEffect(new Pitch()); + } + + var pitch = scale; + if (scale > 1.0) + pitch = 1.0; + + var rPitch = rollSound.getEffect(Pitch); + rPitch.value = pitch; + } + function getIntersectionTime(dt:Float, velocity:Vector) { var searchbox = new Bounds(); searchbox.addSpherePos(this.x, this.y, this.z, _radius); @@ -741,6 +800,8 @@ class Marble extends GameObject { _bounceYet = false; + var contactTime = 0.0; + do { if (timeRemaining <= 0) break; @@ -842,9 +903,14 @@ class Marble extends GameObject { this.level.callCollisionHandlers(cast this, tempTimeState); } + if (contacts.length != 0) + contactTime += timeStep; + timeRemaining -= timeStep; } while (true); this.queuedContacts = []; + + this.updateRollSound(contactTime / timeState.dt, this._slipAmount); } public function update(timeState:TimeState, collisionWorld:CollisionWorld, pathedInteriors:Array) { @@ -889,6 +955,17 @@ class Marble extends GameObject { } public function updatePowerupStates(currentTime:Float, dt:Float) { + if (currentTime - this.shockAbsorberEnableTime < 5) { + this.shockabsorberSound.pause = false; + } else { + this.shockabsorberSound.pause = true; + } + if (currentTime - this.superBounceEnableTime < 5) { + this.superbounceSound.pause = false; + } else { + this.superbounceSound.pause = true; + } + if (currentTime - this.shockAbsorberEnableTime < 5) { this.forcefield.setPosition(0, 0, 0); } else if (currentTime - this.superBounceEnableTime < 5) { @@ -901,8 +978,10 @@ class Marble extends GameObject { if (currentTime - this.helicopterEnableTime < 5) { this.helicopter.setPosition(x, y, z); this.helicopter.setRotationQuat(this.level.getOrientationQuat(currentTime)); + this.helicopterSound.pause = false; } else { this.helicopter.setPosition(1e8, 1e8, 1e8); + this.helicopterSound.pause = true; } } diff --git a/src/MarbleGame.hx b/src/MarbleGame.hx index afa12a11..014d7858 100644 --- a/src/MarbleGame.hx +++ b/src/MarbleGame.hx @@ -1,5 +1,7 @@ package src; +import src.ResourceLoader; +import src.AudioManager; import gui.PlayMissionGui; import gui.ExitGameDlg; import hxd.Key; @@ -75,6 +77,12 @@ class MarbleGame { } public function playMission(mission:Mission) { + var musicFileName = [ + 'data/sound/groovepolice.ogg', + 'data/sound/classic vibe.ogg', + 'data/sound/beach party.ogg' + ][(mission.index + 1) % 3]; + AudioManager.playMusic(ResourceLoader.getAudio(musicFileName)); canvas.clearContent(); mission.load(); world = new MarbleWorld(scene, scene2d, mission); diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 24792d4a..87622088 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -996,6 +996,7 @@ class MarbleWorld extends Scheduler { scene.removeChildren(); this._disposed = true; AudioManager.stopAllSounds(); + AudioManager.playShell(); } } diff --git a/src/Mission.hx b/src/Mission.hx index 9a18b1bd..379cc6a8 100644 --- a/src/Mission.hx +++ b/src/Mission.hx @@ -17,6 +17,7 @@ class Mission { public var type:String; public var path:String; public var missionInfo:MissionElementScriptObject; + public var index:Int; public function new() {} diff --git a/src/gui/GuiButton.hx b/src/gui/GuiButton.hx index c2a4e18e..beeff032 100644 --- a/src/gui/GuiButton.hx +++ b/src/gui/GuiButton.hx @@ -1,9 +1,11 @@ package gui; +import src.AudioManager; import hxd.Key; import gui.GuiControl.MouseState; import hxd.Window; import h2d.Tile; +import src.ResourceLoader; enum ButtonType { Normal; @@ -22,12 +24,19 @@ class GuiButton extends GuiAnim { public var buttonType:ButtonType = Normal; public var pressed:Bool = false; + public var buttonSounds:Bool = true; + public function new(anim:Array) { super(anim); } public override function update(dt:Float, mouseState:MouseState) { var renderRect = getRenderRectangle(); + if (renderRect.inRect(mouseState.position) && !disabled) { + if (buttonSounds && Key.isPressed(Key.MOUSE_LEFT)) { + AudioManager.playSound(ResourceLoader.getAudio("data/sound/buttonpress.wav")); + } + } if (buttonType == Normal) { if (renderRect.inRect(mouseState.position) && !disabled) { if (Key.isDown(Key.MOUSE_LEFT)) { @@ -69,4 +78,12 @@ class GuiButton extends GuiAnim { pressed = !pressed; } } + + public override function onMouseEnter(mouseState:MouseState) { + super.onMouseEnter(mouseState); + + if (buttonSounds) { + AudioManager.playSound(ResourceLoader.getAudio("data/sound/buttonover.wav")); + } + } } diff --git a/src/gui/GuiControl.hx b/src/gui/GuiControl.hx index 86bd58fa..3444cb50 100644 --- a/src/gui/GuiControl.hx +++ b/src/gui/GuiControl.hx @@ -40,6 +40,8 @@ class GuiControl { var parent:GuiControl; + var _entered:Bool = false; + public function new() {} public function render(scene2d:Scene) { @@ -75,6 +77,16 @@ class GuiControl { mouseState.button = Key.MOUSE_RIGHT; this.onMouseDown(mouseState); } + + if (!_entered) { + _entered = true; + this.onMouseEnter(mouseState); + } + } else { + if (_entered) { + _entered = false; + this.onMouseLeave(mouseState); + } } for (c in children) { c.update(dt, mouseState); @@ -175,6 +187,10 @@ class GuiControl { public function onMouseRelease(mouseState:MouseState) {} + public function onMouseEnter(mouseState:MouseState) {} + + public function onMouseLeave(mouseState:MouseState) {} + public function onRemove() { for (c in this.children) { c.onRemove(); diff --git a/src/gui/GuiSlider.hx b/src/gui/GuiSlider.hx index c9b56d65..456be3a9 100644 --- a/src/gui/GuiSlider.hx +++ b/src/gui/GuiSlider.hx @@ -1,5 +1,7 @@ package gui; +import hxd.snd.Channel; +import hxd.res.Sound; import hxd.Key; import gui.GuiControl.MouseState; import src.Util; @@ -7,14 +9,20 @@ import src.Util; class GuiSlider extends GuiImage { public var sliderValue:Float = 0; + public var slidingSound:Channel; + public override function update(dt:Float, mouseState:MouseState) { var renderRect = getRenderRectangle(); if (renderRect.inRect(mouseState.position)) { if (Key.isDown(Key.MOUSE_LEFT)) { sliderValue = (mouseState.position.x - renderRect.position.x - bmp.width / 2) / renderRect.extent.x; sliderValue = Util.clamp(sliderValue, 0, 1); + + if (slidingSound != null) + slidingSound.pause = false; } - } + } else if (slidingSound != null) + slidingSound.pause = true; super.update(dt, mouseState); this.bmp.x = renderRect.position.x + renderRect.extent.x * sliderValue; this.bmp.width = this.bmp.tile.width; diff --git a/src/gui/OptionsDlg.hx b/src/gui/OptionsDlg.hx index 117db548..ee7c08c7 100644 --- a/src/gui/OptionsDlg.hx +++ b/src/gui/OptionsDlg.hx @@ -1,5 +1,6 @@ package gui; +import src.AudioManager; import hxd.Key; import src.Settings; import src.Marble; @@ -287,6 +288,9 @@ class OptionsDlg extends GuiImage { audSndKnob.position = new Vector(137, 95); audSndKnob.extent = new Vector(254, 37); audSndKnob.sliderValue = Settings.optionsSettings.soundVolume; + var testingSnd = AudioManager.playSound(ResourceLoader.getAudio("data/sound/testing.wav"), null, true); + testingSnd.pause = true; + audSndKnob.slidingSound = testingSnd; audSndKnob.pressedAction = (sender) -> { Settings.optionsSettings.soundVolume = audSndKnob.sliderValue; } diff --git a/src/gui/PlayMissionGui.hx b/src/gui/PlayMissionGui.hx index 569bb500..0d5157fb 100644 --- a/src/gui/PlayMissionGui.hx +++ b/src/gui/PlayMissionGui.hx @@ -1,5 +1,6 @@ package gui; +import src.AudioManager; import src.Settings.Score; import src.Settings.Settings; import haxe.io.Path; @@ -142,6 +143,7 @@ class PlayMissionGui extends GuiImage { pmPlay.extent = new Vector(121, 62); pmPlay.pressedAction = (sender) -> { // Wacky hacks + currentList[currentSelection].index = currentSelection; cast(this.parent, Canvas).marbleGame.playMission(currentList[currentSelection]); } pmBox.addChild(pmPlay); @@ -229,6 +231,7 @@ class PlayMissionGui extends GuiImage { localContainer.removeChild(tabAdvanced); localContainer.removeChild(tabCustom); localContainer.removeChild(pmBox); + AudioManager.playSound(ResourceLoader.getAudio("data/sound/buttonpress.wav")); if (category == "beginner") { localContainer.addChild(tabIntermediate); localContainer.addChild(tabAdvanced);