From c3db9f2414eec159072adff0b4577614d12d9a05 Mon Sep 17 00:00:00 2001 From: shmyga Date: Fri, 5 Apr 2019 16:29:17 +0300 Subject: [PATCH] [client] update SoundManager --- .../haxe/ru/m/tankz/render/RenderItem.hx | 30 +++++++- .../haxe/ru/m/tankz/sound/SoundManager.hx | 71 +++++++++++++++--- src/client/haxe/ru/m/tankz/view/ClientView.hx | 17 ++++- .../haxe/ru/m/tankz/view/common/GameFrame.hx | 6 +- .../resources/image/eagle/eagle-protected.png | Bin 612 -> 0 bytes src/client/resources/image/eagle/eagle.png | Bin 365 -> 6640 bytes src/common/haxe/ru/m/tankz/game/Game.hx | 4 +- 7 files changed, 105 insertions(+), 23 deletions(-) delete mode 100644 src/client/resources/image/eagle/eagle-protected.png diff --git a/src/client/haxe/ru/m/tankz/render/RenderItem.hx b/src/client/haxe/ru/m/tankz/render/RenderItem.hx index b628935..aaf5229 100644 --- a/src/client/haxe/ru/m/tankz/render/RenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/RenderItem.hx @@ -233,11 +233,24 @@ class BulletItem extends BitmapItem { } -class EagleItem extends BitmapItem { +class EagleItem extends RenderItem { + private var eagleView:Bitmap; + private var protectView:Animate; private var death:Bool; private var protected:Bool; + public function new(value:Eagle) { + super(value); + view = new Sprite(); + eagleView = new Bitmap(); + view.addChild(eagleView); + protectView = AnimateBundle.tankProtect(); + protectView.visible = false; + view.addChild(protectView); + redraw(); + } + override public function update():Void { super.update(); var d = value.death; @@ -249,8 +262,8 @@ class EagleItem extends BitmapItem { } } - override private function getImage():String { - var suffix = value.death ? '-death' : value.protect.active ? '-protected' : ''; + private function getImage():String { + var suffix = value.death ? '-death' : ''; return 'resources/image/eagle/eagle${suffix}.png'; } @@ -259,7 +272,16 @@ class EagleItem extends BitmapItem { if (!value.color.zero) { image = BitmapUtil.colorize(image, value.color); } - view.bitmapData = image; + eagleView.bitmapData = image; + if (value.protect.active) { + protectView.x = (image.width - protectView.frames[0].image.width) / 2; + protectView.y = (image.height - protectView.frames[0].image.height) / 2; + protectView.playing = true; + protectView.visible = true; + } else { + protectView.playing = false; + protectView.visible = false; + } } } diff --git a/src/client/haxe/ru/m/tankz/sound/SoundManager.hx b/src/client/haxe/ru/m/tankz/sound/SoundManager.hx index 1b2b7a3..c3f230d 100644 --- a/src/client/haxe/ru/m/tankz/sound/SoundManager.hx +++ b/src/client/haxe/ru/m/tankz/sound/SoundManager.hx @@ -1,12 +1,14 @@ package ru.m.tankz.sound; -import openfl.media.Sound; +import flash.events.Event; +import flash.media.Sound; +import flash.media.SoundChannel; +import flash.media.SoundTransform; import openfl.utils.Assets; import ru.m.tankz.core.EntityType; import ru.m.tankz.engine.Engine; import ru.m.tankz.Type; - class SoundManager { private static var TAG(default, never):String = 'SoundManager'; @@ -16,23 +18,68 @@ class SoundManager { private static var type:String = 'ogg'; #end - public function new() {} + public var volume(default, set):Float = 1; + public var mute(default, set):Bool = false; + + private var channels:Array; + private var transform:SoundTransform; + + public function new() { + channels = []; + updateSoundTransform(); + } + + private function updateSoundTransform():Void { + transform = new SoundTransform(mute ? 0 : volume); + for (channel in channels) { + channel.soundTransform = transform; + } + } + + private function set_volume(value:Float):Float { + if (volume != value) { + volume = value; + updateSoundTransform(); + } + return volume; + } + + private function set_mute(value:Bool):Bool { + if (mute != value) { + mute = value; + updateSoundTransform(); + } + return mute; + } public function play(id:String):Void { //L.d(TAG, 'play: ${id}'); var sound:Sound = Assets.getSound('resources/sounds/${id}.${type}'); if (sound != null) { - sound.play(); + var channel = sound.play(0, 0, transform); + channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); + channels.push(channel); } else { L.w(TAG, 'Sound "${id}" not found'); } } + public function stopAll():Void { + for (channel in channels) { + channel.stop(); + } + channels = []; + } + + private function onSoundComplete(event:Event):Void { + channels.remove(event.currentTarget); + } + public function onSpawn(entity:EntityType):Void { switch entity { - case EntityType.BULLET(_.tank.playerId.team => 'human'): + case BULLET(_.tank.playerId.team => 'human'): play('shot'); - case EntityType.BONUS(_): + case BONUS(_): play('bonus_add'); case _: } @@ -40,11 +87,11 @@ class SoundManager { public function onChange(entity:EntityType, change:EntityChange):Void { switch [entity, change] { - case [EntityType.TANK(_), EntityChange.HIT]: + case [TANK(_), HIT]: play('bullet_hit'); - //case [EntityType.TANK(_), EntityChange.LIVE_UP]: + //case [TANK(_), LIVE_UP]: // play('live'); - case [EntityType.EAGLE(_), EntityChange.DEATH(_)]: + case [EAGLE(_), DEATH(_)]: play('boom_player'); case _: } @@ -52,7 +99,7 @@ class SoundManager { public function onCollision(entity:EntityType, with:EntityType):Void { switch [entity, with] { - case [EntityType.BULLET(_), EntityType.CELL(cell)]: + case [BULLET(_), CELL(cell)]: //play('bullet_wall'); case _: } @@ -60,9 +107,9 @@ class SoundManager { public function onDestroy(entity:EntityType, ?playerId:PlayerId):Void { switch entity { - case EntityType.TANK(_): + case TANK(_): play('boom_bot'); - case EntityType.BONUS(_): + case BONUS(_): play('bonus_get'); case _: } diff --git a/src/client/haxe/ru/m/tankz/view/ClientView.hx b/src/client/haxe/ru/m/tankz/view/ClientView.hx index 7bf4caf..40484b6 100644 --- a/src/client/haxe/ru/m/tankz/view/ClientView.hx +++ b/src/client/haxe/ru/m/tankz/view/ClientView.hx @@ -1,27 +1,40 @@ package ru.m.tankz.view; +import haxework.view.IView; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import haxework.resources.IResources; import haxework.view.frame.FrameSwitcher; +import ru.m.tankz.sound.SoundManager; @:template class ClientView extends FrameSwitcher { @:provide var resources:IResources; @:provide var switcher:FrameSwitcher; + @:provide var soundManager:SoundManager; public function init():Void { resources.text.put('version', '${Const.VERSION}'); switcher = this; + onSwitch.connect(onFrameSwitch); } public function launch():Void { content.stage.stageFocusRect = false; content.stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):Void { - if (event.keyCode == Keyboard.ESCAPE) { - change(StartFrame.ID); + switch event.keyCode { + case Keyboard.ESCAPE: + change(StartFrame.ID); + case Keyboard.M: + soundManager.mute = !soundManager.mute; } }); change(StartFrame.ID); } + + private function onFrameSwitch(frame:IView):Void { + if (frame.id == StartFrame.ID) { + soundManager.stopAll(); + } + } } diff --git a/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx index 938e3a7..b1c9941 100644 --- a/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/common/GameFrame.hx @@ -21,7 +21,7 @@ class GameFrame extends GroupView { private var panel(get, null):IGamePanel; @:provide var network:NetworkManager; - @:provide var sound:SoundManager; + @:provide var soundManager:SoundManager; @:provide var state:GameState; @:provide("result") var result:GameState; @:provide var switcher:FrameSwitcher; @@ -45,7 +45,7 @@ class GameFrame extends GroupView { private function start(state:GameState):Void { game = new Game(state.type); game.engine.connect(render); - game.engine.connect(sound); + game.engine.connect(soundManager); game.connect(this); if (panel != null) { game.connect(panel); @@ -55,7 +55,7 @@ class GameFrame extends GroupView { timer.run = updateEngine; content.addEventListener(Event.ENTER_FRAME, _redraw); render.draw(game.engine); - sound.play('start'); + soundManager.play('start'); } private function stop():Void { diff --git a/src/client/resources/image/eagle/eagle-protected.png b/src/client/resources/image/eagle/eagle-protected.png deleted file mode 100644 index 0b593f8409d26b0a2aee5b957109aad98992ce01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 612 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