From eb59030a76e275d47980c7734dfef4daf3e4f8bb Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Wed, 30 Jun 2021 15:08:39 +0530 Subject: [PATCH] basic sounds --- src/AudioManager.hx | 30 ++++++++++++++++++ src/DtsObject.hx | 11 ++++--- src/Main.hx | 2 ++ src/Marble.hx | 36 +++++++++++++++++++++ src/MarbleWorld.hx | 35 ++++++++++++++++++--- src/ResourceLoader.hx | 13 ++++++++ src/gui/OptionsDlg.hx | 63 +++++++++++++++++++------------------ src/shapes/AntiGravity.hx | 2 ++ src/shapes/EndPad.hx | 3 ++ src/shapes/Helicopter.hx | 2 ++ src/shapes/LandMine.hx | 3 +- src/shapes/PowerUp.hx | 7 +++++ src/shapes/ShockAbsorber.hx | 2 ++ src/shapes/SuperBounce.hx | 2 ++ src/shapes/SuperJump.hx | 5 ++- src/shapes/SuperSpeed.hx | 4 ++- src/shapes/TimeTravel.hx | 2 ++ src/shapes/Trapdoor.hx | 4 ++- src/triggers/HelpTrigger.hx | 4 ++- 19 files changed, 185 insertions(+), 45 deletions(-) create mode 100644 src/AudioManager.hx diff --git a/src/AudioManager.hx b/src/AudioManager.hx new file mode 100644 index 00000000..b50b1b7b --- /dev/null +++ b/src/AudioManager.hx @@ -0,0 +1,30 @@ +package src; + +import hxd.snd.effect.Spatialization; +import h3d.Vector; +import hxd.res.Sound; +import src.Settings; +import hxd.snd.ChannelGroup; + +class AudioManager { + static var manager:hxd.snd.Manager; + static var soundChannel:hxd.snd.ChannelGroup; + static var musicChannel:hxd.snd.ChannelGroup; + + 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; + } + + public static function playSound(sound:Sound, ?position:Vector) { + AudioManager.manager.play(sound, soundChannel); + if (position != null) { + var audioSrc = new Spatialization(); + audioSrc.position = position; + soundChannel.addEffect(audioSrc); + } + } +} diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 554d4671..f9b1b6d1 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -349,16 +349,17 @@ class DtsObject extends GameObject { } material.shadows = false; if (material.texture == null) { - var dtsshader = new DtsTexture(); - dtsshader.currentOpacity = 1; + // var dtsshader = new DtsTexture(); + // dtsshader.currentOpacity = 1; // Make a 1x1 white texture var bitmap = new hxd.BitmapData(1, 1); bitmap.setPixel(0, 0, 0xFFFFFF); var texture = new Texture(1, 1); texture.uploadBitmap(bitmap); - dtsshader.texture = texture; - material.mainPass.addShader(dtsshader); - material.receiveShadows = true; + material.texture = texture; + // dtsshader.texture = texture; + // material.mainPass.addShader(dtsshader); + // material.shadows = false; } if (flags & 4 > 0) { material.blendMode = BlendMode.Alpha; diff --git a/src/Main.hx b/src/Main.hx index bbf9e84d..01a50392 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -1,5 +1,6 @@ package; +import src.AudioManager; import src.Settings; import src.MarbleGame; import gui.MainMenuGui; @@ -16,6 +17,7 @@ class Main extends hxd.App { super.init(); Settings.init(); + AudioManager.init(); 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 125b1e1c..57a142aa 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1,5 +1,7 @@ package src; +import src.Util; +import src.AudioManager; import src.Settings; import h3d.scene.Mesh; import h3d.col.Bounds; @@ -121,6 +123,9 @@ class Marble extends GameObject { var _minBounceVel = 3; var _minTrailVel = 10; var _bounceKineticFriction = 0.2; + var minVelocityBounceSoft = 2.5; + var minVelocityBounceHard = 12.0; + var bounceMinGain = 0.2; public var _bounceRestitution = 0.5; @@ -349,6 +354,11 @@ class Marble extends GameObject { var velLen = this.velocity.length(); var surfaceVel = this.contacts[i].normal.multiply(surfaceDot); + if (!_bounceYet) { + _bounceYet = true; + playBoundSound(-surfaceDot); + } + if (noBounce) { this.velocity = this.velocity.sub(surfaceVel); } else if (contacts[i].collider != null) { @@ -506,6 +516,7 @@ class Marble extends GameObject { } if (sv < this._jumpImpulse) { this.velocity = this.velocity.add(bestContact.normal.multiply((this._jumpImpulse - sv))); + AudioManager.playSound(ResourceLoader.getAudio("data/sound/jump.wav")); } } for (j in 0...contacts.length) { @@ -607,6 +618,29 @@ class Marble extends GameObject { this._bounceNormal = normal; } + function playBoundSound(contactVel:Float) { + if (minVelocityBounceSoft <= contactVel) { + var hardBounceSpeed = minVelocityBounceHard; + var bounceSoundNum = Math.floor(Math.random() * 4); + var sndList = [ + "data/sound/bouncehard1.wav", + "data/sound/bouncehard2.wav", + "data/sound/bouncehard3.wav", + "data/sound/bouncehard4.wav" + ]; + var snd = ResourceLoader.getAudio(sndList[bounceSoundNum]); + var gain = bounceMinGain; + gain = Util.clamp(Math.pow(contactVel / 12, 1.5), 0, 1); + + // if (hardBounceSpeed <= contactVel) + // gain = 1.0; + // else + // gain = (contactVel - minVelocityBounceSoft) / (hardBounceSpeed - minVelocityBounceSoft) * (1.0 - gain) + gain; + + snd.play(false, Settings.optionsSettings.soundVolume * gain); + } + } + function getIntersectionTime(dt:Float, velocity:Vector) { var searchbox = new Bounds(); searchbox.addSpherePos(this.x, this.y, this.z, _radius); @@ -697,6 +731,8 @@ class Marble extends GameObject { } } + _bounceYet = false; + do { if (timeRemaining <= 0) break; diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 1965b608..4cee148c 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,7 @@ package src; +import src.ResourceLoader; +import src.AudioManager; import src.Settings; import gui.LoadingGui; import gui.PlayMissionGui; @@ -255,7 +257,24 @@ class MarbleWorld extends Scheduler { this.newOrientationQuat = new Quat(); this.deselectPowerUp(); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/spawn.wav')); + this.clearSchedule(); + this.schedule(0.5, () -> { + // setCenterText('ready'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/ready.wav')); + return 0; + }); + this.schedule(2, () -> { + // setCenterText('set'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/set.wav')); + return 0; + }); + this.schedule(3.5, () -> { + // setCenterText('go'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/go.wav')); + return 0; + }); return 0; } @@ -722,7 +741,7 @@ class MarbleWorld extends Scheduler { if (this.gemCount == this.totalGems) { string = "You have all the gems, head for the finish!"; // if (!this.rewinding) - // AudioManager.play('gotallgems.wav'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/gotallgems.wav')); // Some levels with this package end immediately upon collection of all gems // if (this.mission.misFile.activatedPackages.includes('endWithTheGems')) { @@ -741,7 +760,7 @@ class MarbleWorld extends Scheduler { } // if (!this.rewinding) - // AudioManager.play('gotgem.wav'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/gotgem.wav')); } displayAlert(string); @@ -817,7 +836,13 @@ class MarbleWorld extends Scheduler { if (this.finishTime == null) { if (spherebounds.collide(this.endPad.finishBounds)) { if (collision.gjk.GJK.gjk(gjkSphere, this.endPad.finishCollider) != null) { - touchFinish(); + if (!endPad.inFinish) { + touchFinish(); + endPad.inFinish = true; + } + } else { + if (endPad.inFinish) + endPad.inFinish = false; } } } @@ -830,7 +855,7 @@ class MarbleWorld extends Scheduler { return; if (this.gemCount < this.totalGems) { - // AudioManager.play('missinggems.wav'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/missinggems.wav')); displayAlert("You can't finish without all the gems!!"); } else { this.endPad.spawnFirework(this.timeState); @@ -935,7 +960,7 @@ class MarbleWorld extends Scheduler { sky.follow = null; // this.oobCameraPosition = camera.position.clone(); playGui.setCenterText('outofbounds'); - // AudioManager.play('whoosh.wav'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/whoosh.wav')); // if (this.replay.mode != = 'playback') this.schedule(this.timeState.currentAttemptTime + 2, () -> this.restart()); } diff --git a/src/ResourceLoader.hx b/src/ResourceLoader.hx index c030af95..d3fda03f 100644 --- a/src/ResourceLoader.hx +++ b/src/ResourceLoader.hx @@ -1,6 +1,7 @@ package src; import hxd.res.Image; +import hxd.res.Sound; import h3d.mat.Texture; import h3d.scene.Object; import sys.FileSystem; @@ -19,6 +20,7 @@ class ResourceLoader { static var dtsResources:Map = new Map(); static var textureCache:Map = new Map(); static var imageCache:Map = new Map(); + static var audioCache:Map = new Map(); // static var threadPool:FixedThreadPool = new FixedThreadPool(4); @@ -77,6 +79,17 @@ class ResourceLoader { return null; } + public static function getAudio(path:String) { + if (audioCache.exists(path)) + return audioCache.get(path); + if (fileSystem.exists(path)) { + var snd = loader.load(path).toSound(); + audioCache.set(path, snd); + return snd; + } + return null; + } + public static function clearInteriorResources() { interiorResources = new Map(); } diff --git a/src/gui/OptionsDlg.hx b/src/gui/OptionsDlg.hx index 0289de78..117db548 100644 --- a/src/gui/OptionsDlg.hx +++ b/src/gui/OptionsDlg.hx @@ -257,36 +257,6 @@ class OptionsDlg extends GuiImage { shadowsButton.pressed = true; } - applyFunc = () -> { - if (gfx640480.pressed) { - Settings.optionsSettings.screenWidth = 640; - Settings.optionsSettings.screenHeight = 480; - } - if (gfx800600.pressed) { - Settings.optionsSettings.screenWidth = 800; - Settings.optionsSettings.screenHeight = 600; - } - if (gfx1024768.pressed) { - Settings.optionsSettings.screenWidth = 1024; - Settings.optionsSettings.screenHeight = 768; - } - if (gfxFull.pressed) - Settings.optionsSettings.isFullScreen = true; - else - Settings.optionsSettings.isFullScreen = false; - if (gfx16.pressed) - Settings.optionsSettings.colorDepth = 0; - else - Settings.optionsSettings.colorDepth = 1; - if (gfxopengl.pressed) - Settings.optionsSettings.videoDriver = 0; - else - Settings.optionsSettings.videoDriver = 1; - Settings.optionsSettings.shadows = shadowsButton.pressed; - - Settings.applySettings(); - } - // AUDIO PANEL var audioPane = new GuiControl(); @@ -337,6 +307,39 @@ Renderer: Software Extensions: EAX 2.0, EAX 3.0, EAX Unified, and EAX-AC3"; audTxtWndo.addChild(audInfo); + applyFunc = () -> { + if (gfx640480.pressed) { + Settings.optionsSettings.screenWidth = 640; + Settings.optionsSettings.screenHeight = 480; + } + if (gfx800600.pressed) { + Settings.optionsSettings.screenWidth = 800; + Settings.optionsSettings.screenHeight = 600; + } + if (gfx1024768.pressed) { + Settings.optionsSettings.screenWidth = 1024; + Settings.optionsSettings.screenHeight = 768; + } + if (gfxFull.pressed) + Settings.optionsSettings.isFullScreen = true; + else + Settings.optionsSettings.isFullScreen = false; + if (gfx16.pressed) + Settings.optionsSettings.colorDepth = 0; + else + Settings.optionsSettings.colorDepth = 1; + if (gfxopengl.pressed) + Settings.optionsSettings.videoDriver = 0; + else + Settings.optionsSettings.videoDriver = 1; + Settings.optionsSettings.shadows = shadowsButton.pressed; + + Settings.optionsSettings.musicVolume = audMusKnob.sliderValue; + Settings.optionsSettings.soundVolume = audSndKnob.sliderValue; + + Settings.applySettings(); + } + // CONTROLS PANEL var controlsPane = new GuiControl(); controlsPane.position = new Vector(44, 58); diff --git a/src/shapes/AntiGravity.hx b/src/shapes/AntiGravity.hx index 0d9e8153..4d582195 100644 --- a/src/shapes/AntiGravity.hx +++ b/src/shapes/AntiGravity.hx @@ -1,5 +1,6 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import h3d.Vector; @@ -14,6 +15,7 @@ class AntiGravity extends PowerUp { this.identifier = "AntiGravity"; this.pickUpName = "Gravity Modifier"; this.autoUse = true; + this.pickupSound = ResourceLoader.getAudio("data/sound/gravitychange.wav"); } public function pickUp():Bool { diff --git a/src/shapes/EndPad.hx b/src/shapes/EndPad.hx index a4278f44..385b5641 100644 --- a/src/shapes/EndPad.hx +++ b/src/shapes/EndPad.hx @@ -1,5 +1,6 @@ package shapes; +import src.AudioManager; import h3d.Quat; import h3d.mat.Material; import h3d.scene.Mesh; @@ -24,6 +25,7 @@ class EndPad extends DtsObject { var finishCollider:ConvexHull; var finishBounds:Bounds; + var inFinish:Bool = false; public function new() { super(); @@ -43,6 +45,7 @@ class EndPad extends DtsObject { function spawnFirework(time:TimeState) { var firework = new Firework(this.getAbsPos().getPosition(), time.timeSinceLoad, this.level); this.fireworks.push(firework); + // AudioManager.playSound(ResourceLoader.getAudio("data/sound/firewrks.wav")); // AudioManager.play(this.sounds[0], 1, AudioManager.soundGain, this.worldPosition); } diff --git a/src/shapes/Helicopter.hx b/src/shapes/Helicopter.hx index a061e211..01c5394c 100644 --- a/src/shapes/Helicopter.hx +++ b/src/shapes/Helicopter.hx @@ -1,5 +1,6 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.DtsObject; @@ -13,6 +14,7 @@ class Helicopter extends PowerUp { this.showSequences = false; this.identifier = "Helicopter"; this.pickUpName = "Gyrocopter PowerUp"; + this.pickupSound = ResourceLoader.getAudio("data/sound/pugyrocoptervoice.wav"); } public function pickUp():Bool { diff --git a/src/shapes/LandMine.hx b/src/shapes/LandMine.hx index 377737da..ced7e60f 100644 --- a/src/shapes/LandMine.hx +++ b/src/shapes/LandMine.hx @@ -1,5 +1,6 @@ package shapes; +import src.AudioManager; import src.TimeState; import collision.CollisionHull; import collision.CollisionInfo; @@ -120,7 +121,7 @@ class LandMine extends DtsObject { this.setCollisionEnabled(false); // if (!this.level.rewinding) - // AudioManager.play(this.sounds[0]); + AudioManager.playSound(ResourceLoader.getAudio("data/sound/explode1.wav")); this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition()); this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition()); this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition()); diff --git a/src/shapes/PowerUp.hx b/src/shapes/PowerUp.hx index e0888681..4338883c 100644 --- a/src/shapes/PowerUp.hx +++ b/src/shapes/PowerUp.hx @@ -1,5 +1,7 @@ package shapes; +import src.AudioManager; +import hxd.res.Sound; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.Util; @@ -31,6 +33,7 @@ abstract class PowerUp extends DtsObject { public var powerupParams:PowerupParams = new PowerupParams(); public var pickUpName:String; public var element:MissionElementItem; + public var pickupSound:Sound; public function new(element:MissionElementItem) { super(); @@ -54,6 +57,10 @@ abstract class PowerUp extends DtsObject { this.level.displayAlert('You picked up a ${this.pickUpName}!'); if (this.element.showhelponpickup == "1" && !this.autoUse) this.level.displayHelp('Press to use the ${this.pickUpName}!'); + + if (pickupSound != null) { + AudioManager.playSound(pickupSound); + } } } diff --git a/src/shapes/ShockAbsorber.hx b/src/shapes/ShockAbsorber.hx index 5e615d61..1172ab55 100644 --- a/src/shapes/ShockAbsorber.hx +++ b/src/shapes/ShockAbsorber.hx @@ -1,5 +1,6 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.DtsObject; @@ -12,6 +13,7 @@ class ShockAbsorber extends PowerUp { this.isTSStatic = false; this.identifier = "ShockAbsorber"; this.pickUpName = "Shock Absorber PowerUp"; + this.pickupSound = ResourceLoader.getAudio("data/sound/pushockabsorbervoice.wav"); } public function pickUp():Bool { diff --git a/src/shapes/SuperBounce.hx b/src/shapes/SuperBounce.hx index 8c1cf420..a3d2b05d 100644 --- a/src/shapes/SuperBounce.hx +++ b/src/shapes/SuperBounce.hx @@ -1,5 +1,6 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.DtsObject; @@ -12,6 +13,7 @@ class SuperBounce extends PowerUp { this.isTSStatic = false; this.identifier = "SuperBounce"; this.pickUpName = "Super Bounce PowerUp"; + this.pickupSound = ResourceLoader.getAudio("data/sound/pusuperbouncevoice.wav"); } public function pickUp():Bool { diff --git a/src/shapes/SuperJump.hx b/src/shapes/SuperJump.hx index 50d75b55..08d668f1 100644 --- a/src/shapes/SuperJump.hx +++ b/src/shapes/SuperJump.hx @@ -1,10 +1,12 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import src.ResourceLoader; import src.ParticleSystem.ParticleData; import h3d.Vector; +import src.AudioManager; import src.DtsObject; final superJumpParticleOptions:src.ParticleSystem.ParticleEmitterOptions = { @@ -43,6 +45,7 @@ class SuperJump extends PowerUp { sjEmitterParticleData = new ParticleData(); sjEmitterParticleData.identifier = "superJumpParticle"; sjEmitterParticleData.texture = ResourceLoader.getTexture("data/particles/twirl.png"); + this.pickupSound = ResourceLoader.getAudio("data/sound/pusuperjumpvoice.wav"); } public function pickUp():Bool { @@ -55,7 +58,7 @@ class SuperJump extends PowerUp { this.level.particleManager.createEmitter(superJumpParticleOptions, this.sjEmitterParticleData, null, () -> marble.getAbsPos().getPosition()); // marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity // if (!this.level.rewinding) - // AudioManager.play(this.sounds[1]); + AudioManager.playSound(ResourceLoader.getAudio("data/sound/dosuperjump.wav")); // this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition())); this.level.deselectPowerUp(); } diff --git a/src/shapes/SuperSpeed.hx b/src/shapes/SuperSpeed.hx index 54ef7274..ceb0ac3f 100644 --- a/src/shapes/SuperSpeed.hx +++ b/src/shapes/SuperSpeed.hx @@ -8,6 +8,7 @@ import src.ParticleSystem.ParticleEmitterOptions; import h3d.Quat; import h3d.Vector; import src.DtsObject; +import src.AudioManager; final superSpeedParticleOptions:ParticleEmitterOptions = { ejectionPeriod: 5, @@ -50,6 +51,7 @@ class SuperSpeed extends PowerUp { ssEmitterParticleData = new ParticleData(); ssEmitterParticleData.identifier = "superSpeedParticle"; ssEmitterParticleData.texture = ResourceLoader.getTexture("data/particles/spark.png"); + this.pickupSound = ResourceLoader.getAudio("data/sound/pusuperspeedvoice.wav"); } public function pickUp():Bool { @@ -74,7 +76,7 @@ class SuperSpeed extends PowerUp { // marble.body.addLinearVelocity(Util.vecThreeToOimo(movementVector).scale(24.7)); // Whirligig's determined value // marble.body.addLinearVelocity(this.level.currentUp.scale(20)); // Simply add to vertical velocity // if (!this.level.rewinding) - // AudioManager.play(this.sounds[1]); + AudioManager.playSound(ResourceLoader.getAudio("data/sound/dosuperspeed.wav")); this.level.particleManager.createEmitter(superSpeedParticleOptions, this.ssEmitterParticleData, null, () -> marble.getAbsPos().getPosition()); this.level.deselectPowerUp(); } diff --git a/src/shapes/TimeTravel.hx b/src/shapes/TimeTravel.hx index 20b4a1e0..ee93e31f 100644 --- a/src/shapes/TimeTravel.hx +++ b/src/shapes/TimeTravel.hx @@ -1,5 +1,6 @@ package shapes; +import src.ResourceLoader; import mis.MissionElement.MissionElementItem; import src.TimeState; import mis.MisParser; @@ -22,6 +23,7 @@ class TimeTravel extends PowerUp { this.cooldownDuration = 1e8; this.useInstancing = true; this.autoUse = true; + this.pickupSound = ResourceLoader.getAudio("data/sound/putimetravelvoice.wav"); } public function pickUp():Bool { diff --git a/src/shapes/Trapdoor.hx b/src/shapes/Trapdoor.hx index 4e1fcca6..fb4a11f0 100644 --- a/src/shapes/Trapdoor.hx +++ b/src/shapes/Trapdoor.hx @@ -6,6 +6,8 @@ import src.Util; import src.DtsObject; import h3d.Vector; import src.ForceObject; +import src.ResourceLoader; +import src.AudioManager; class Trapdoor extends DtsObject { var lastContactTime = -1e8; @@ -37,7 +39,7 @@ class Trapdoor extends DtsObject { direction = -1; if (direction != 0 && direction != this.lastDirection) { // If the direction has changed, play the sound - // AudioManager.play(this.sounds[0], 1, AudioManager.soundGain, this.worldPosition); + // AudioManager.playSound(this.sounds[0], 1, AudioManager.soundGain, this.worldPosition); } this.lastCompletion = currentCompletion; diff --git a/src/triggers/HelpTrigger.hx b/src/triggers/HelpTrigger.hx index 4c51017d..3731e0f7 100644 --- a/src/triggers/HelpTrigger.hx +++ b/src/triggers/HelpTrigger.hx @@ -1,10 +1,12 @@ package triggers; import src.TimeState; +import src.ResourceLoader; +import src.AudioManager; class HelpTrigger extends Trigger { override function onMarbleEnter(timeState:TimeState) { - // AudioManager.play('infotutorial.wav'); + AudioManager.playSound(ResourceLoader.getAudio('data/sound/infotutorial.wav')); this.level.displayHelp(this.element.text); // this.level.replay.recordMarbleEnter(this); }