diff --git a/src/client/haxe/ru/m/tankz/Init.hx b/src/client/haxe/ru/m/tankz/Init.hx index 932cc6c..280947c 100644 --- a/src/client/haxe/ru/m/tankz/Init.hx +++ b/src/client/haxe/ru/m/tankz/Init.hx @@ -1,10 +1,8 @@ package ru.m.tankz; -import ru.m.tankz.storage.MultiplayerStorage; -import ru.m.tankz.storage.SettingsStorage; -import haxework.view.popup.PopupManager; import haxework.resources.IResources; import haxework.resources.Resources; +import haxework.view.popup.PopupManager; import ru.m.connect.IConnection; import ru.m.tankz.bundle.ConfigBundle; import ru.m.tankz.bundle.IConfigBundle; @@ -16,6 +14,9 @@ import ru.m.tankz.network.NetworkManager; import ru.m.tankz.proto.pack.Request; import ru.m.tankz.proto.pack.Response; import ru.m.tankz.sound.SoundManager; +import ru.m.tankz.storage.GameStorage; +import ru.m.tankz.storage.MultiplayerStorage; +import ru.m.tankz.storage.SettingsStorage; #if flash import flash.Lib; #elseif html5 @@ -29,6 +30,7 @@ class Init { @:provide static var configBundle:IConfigBundle; @:provide static var settingsStorage:SettingsStorage; @:provide static var multiplayerStorage:MultiplayerStorage; + @:provide static var gameStorage:GameStorage; @:provide static var soundManager:SoundManager; @:provide static var networkManager:NetworkManager; @:provide static var controlFactory:IControlFactory; @@ -57,6 +59,7 @@ class Init { configBundle = new ConfigBundle(); settingsStorage = new SettingsStorage(); multiplayerStorage = new MultiplayerStorage(); + gameStorage = new GameStorage(); soundManager = new SoundManager(); controlFactory = new ClientControlFactory(); popupManager = new PopupManager(); diff --git a/src/client/haxe/ru/m/tankz/Style.hx b/src/client/haxe/ru/m/tankz/Style.hx index 3264ad5..b09fda2 100644 --- a/src/client/haxe/ru/m/tankz/Style.hx +++ b/src/client/haxe/ru/m/tankz/Style.hx @@ -125,5 +125,9 @@ class Style { Skin.size(64, 64), new ButtonSVGSkin(Assets.getText("resources/image/icon/arrow-alt-circle-right-solid.svg"), lightColor), ]); + resources.skin.put("button.start", [ + Skin.size(64, 64), + new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), lightColor), + ]); } } diff --git a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx index 0cc7103..71de1b3 100644 --- a/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx +++ b/src/client/haxe/ru/m/tankz/bundle/LevelBundle.hx @@ -7,10 +7,17 @@ import ru.m.tankz.util.LevelUtil; class LevelBundle implements ILevelBundle { + private var cache:Map = new Map(); + public function new() {} public function get(type:GameType, config:Config, level:Int):LevelConfig { - var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(level)}.txt'); - return LevelUtil.loads(config, data); + var key = '${type}:${level}'; + if (!cache.exists(key)) { + var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(level)}.txt'); + cache[key] = LevelUtil.loads(config, data); + cache[key].index = level; + } + return cache[key]; } } diff --git a/src/client/haxe/ru/m/tankz/storage/GameStorage.hx b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx new file mode 100644 index 0000000..ec671ac --- /dev/null +++ b/src/client/haxe/ru/m/tankz/storage/GameStorage.hx @@ -0,0 +1,20 @@ +package ru.m.tankz.storage; + +import ru.m.tankz.game.GameState; +import ru.m.tankz.Type.GameType; +import haxework.storage.SharedObjectStorage; + +class GameStorage extends SharedObjectStorage { + + public function new() { + super("game"); + } + + public function get(type:GameType, level:Int):GameState { + return read('${type}:${level}'); + } + + public function set(state:GameState):Void { + write('${state.type}:${state.level}', state); + } +} diff --git a/src/client/haxe/ru/m/tankz/view/ClientView.yaml b/src/client/haxe/ru/m/tankz/view/ClientView.yaml index 065c3ba..50531f2 100755 --- a/src/client/haxe/ru/m/tankz/view/ClientView.yaml +++ b/src/client/haxe/ru/m/tankz/view/ClientView.yaml @@ -5,26 +5,15 @@ skinId: dark views: - id: start $type: ru.m.tankz.view.StartFrame - # classic - - id: classic.level - $type: ru.m.tankz.view.classic.ClassicLevelFrame - - id: classic.game + - id: level + $type: ru.m.tankz.view.LevelFrame + - id: classic $type: ru.m.tankz.view.classic.ClassicGameFrame - # dota - - id: dota.level - $type: ru.m.tankz.view.dota.DotaLevelFrame - - id: dota.game + - id: dota $type: ru.m.tankz.view.dota.DotaGameFrame - # death - - id: death.level - $type: ru.m.tankz.view.death.DeathLevelFrame - - id: death.game + - id: death $type: ru.m.tankz.view.death.DeathGameFrame - # result - id: result $type: ru.m.tankz.view.ResultFrame - # - id: network - # $type: ru.m.tankz.view.NetworkFrame - # settings - id: settings $type: ru.m.tankz.view.SettingsFrame diff --git a/src/client/haxe/ru/m/tankz/view/LevelFrame.hx b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx new file mode 100644 index 0000000..1bf9201 --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/LevelFrame.hx @@ -0,0 +1,51 @@ +package ru.m.tankz.view; + +import haxework.resources.IResources; +import haxework.view.DataView; +import haxework.view.frame.FrameSwitcher; +import haxework.view.LabelView; +import haxework.view.VGroupView; +import ru.m.tankz.bundle.ILevelBundle; +import ru.m.tankz.config.Config; +import ru.m.tankz.game.GameState; +import ru.m.tankz.preset.ClassicGame; +import ru.m.tankz.preset.DeathGame; +import ru.m.tankz.preset.DotaGame; +import ru.m.tankz.view.classic.ClassicGameFrame; +import ru.m.tankz.view.common.LevelView; +import ru.m.tankz.view.death.DeathGameFrame; +import ru.m.tankz.view.dota.DotaGameFrame; + +@:template class LevelFrame extends VGroupView { + public static inline var ID = "level"; + + @:view var header:LabelView; + @:view var levels:DataView; + + @:provide var state:GameState; + @:provide var resources:IResources; + @:provide var swicther:FrameSwitcher; + @:provide var levelBundle:ILevelBundle; + + public function onShow():Void { + header.text = state.type; + levels.data = [for (i in 0...state.config.game.levels) levelBundle.get(state.type, state.config, i)]; + for (view in levels.dataViews) view.onStart.connect(start); + } + + private function start(level:LevelConfig):Void { + state.level = level.index; + swicther.change(switch state.type { + case ClassicGame.TYPE: ClassicGameFrame.ID; + case DotaGame.TYPE: DotaGameFrame.ID; + case DeathGame.TYPE: DeathGameFrame.ID; + case _: StartFrame.ID; + }); + } + + private function onLevelSelect(index:Int, level:LevelConfig, view:LevelView):Void { + for (v in levels.views) { + cast(v, LevelView).selected = v == view; + } + } +} diff --git a/src/client/haxe/ru/m/tankz/view/LevelFrame.yaml b/src/client/haxe/ru/m/tankz/view/LevelFrame.yaml new file mode 100644 index 0000000..44dc165 --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/LevelFrame.yaml @@ -0,0 +1,18 @@ +--- +skinId: container +layout: + $type: haxework.view.layout.VerticalLayout +views: + - id: header + $type: haxework.view.LabelView + skinId: text.header + - id: levels + $type: haxework.view.DataView + geometry.size.width: 100% + layout: + $type: haxework.view.layout.TailLayout + rowSize: 10 + margin: 5 + factory: $code:ru.m.tankz.view.common.LevelView.factory + +onItemSelect: $this:onLevelSelect + geometry.padding: 10 diff --git a/src/client/haxe/ru/m/tankz/view/StartFrame.hx b/src/client/haxe/ru/m/tankz/view/StartFrame.hx index ce0ea6b..a57ca26 100644 --- a/src/client/haxe/ru/m/tankz/view/StartFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/StartFrame.hx @@ -1,34 +1,23 @@ package ru.m.tankz.view; -import haxework.view.ButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.VGroupView; -import ru.m.tankz.view.classic.ClassicLevelFrame; -import ru.m.tankz.view.death.DeathLevelFrame; -import ru.m.tankz.view.dota.DotaLevelFrame; +import ru.m.tankz.game.GameState; +import ru.m.tankz.Type.GameType; import ru.m.tankz.view.popup.FontPopup; @:template class StartFrame extends VGroupView { public static var ID(default, never):String = "start"; - @:provide var frameSwitcher:FrameSwitcher; + @:provide var state:GameState; + @:provide var swicther:FrameSwitcher; private var fontPopup:FontPopup; - private function onPress(view:ButtonView):Void { - switch (view.id) { - case 'classic': - frameSwitcher.change(ClassicLevelFrame.ID); - case 'dota': - frameSwitcher.change(DotaLevelFrame.ID); - case 'death': - frameSwitcher.change(DeathLevelFrame.ID); - case 'network': - //frameSwitcher.change(NetworkFrame.ID); - case 'settings': - frameSwitcher.change(SettingsFrame.ID); - } + private function startGame(type:GameType):Void { + state = new GameState(type); + swicther.change(LevelFrame.ID); } private function choiceFont():Void { diff --git a/src/client/haxe/ru/m/tankz/view/StartFrame.yaml b/src/client/haxe/ru/m/tankz/view/StartFrame.yaml index 010a521..4834b3b 100644 --- a/src/client/haxe/ru/m/tankz/view/StartFrame.yaml +++ b/src/client/haxe/ru/m/tankz/view/StartFrame.yaml @@ -9,39 +9,25 @@ views: skinId: font fontSize: 100 geometry.margin.bottom: 30 - - id: classic - $type: haxework.view.ButtonView + - $type: haxework.view.ButtonView skinId: button - +onPress: $this:onPress + +onPress: $code:startGame('classic') text: Classic - - id: dota - $type: haxework.view.ButtonView + - $type: haxework.view.ButtonView skinId: button - +onPress: $this:onPress + +onPress: $code:startGame('dota') text: DotA - - id: death - $type: haxework.view.ButtonView + - $type: haxework.view.ButtonView skinId: button - +onPress: $this:onPress + +onPress: $code:startGame('death') text: DeathMatch -# - id: font -# $type: haxework.view.ButtonView -# skinId: button -# +onPress: $code:choiceFont() -# text: Font -# - id: network -# $type: haxework.view.ButtonView -# skinId: button -# +onPress: $this:onPress -# text: Network (in developing) -# fontColor: 0xff0000 - $type: haxework.view.HGroupView skinId: panel views: - id: settings $type: haxework.view.ButtonView skinId: button.settings - +onPress: $this:onPress + +onPress: $code:swicther.change('settings') - $type: haxework.view.SpriteView geometry.size.width: 100% - $type: haxework.view.LabelView diff --git a/src/client/haxe/ru/m/tankz/view/classic/ClassicGameFrame.hx b/src/client/haxe/ru/m/tankz/view/classic/ClassicGameFrame.hx index 6e71d1e..b8028bb 100755 --- a/src/client/haxe/ru/m/tankz/view/classic/ClassicGameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/classic/ClassicGameFrame.hx @@ -5,7 +5,7 @@ import ru.m.tankz.render.Render; import ru.m.tankz.view.common.GameFrame; @:template class ClassicGameFrame extends GameFrame { - public static inline var ID = "classic.game"; + public static inline var ID = "classic"; @:view("render") private var renderView(default, null):Render; @:view("panel") private var panelView(default, null):IGamePanel; diff --git a/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.hx b/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.hx deleted file mode 100644 index ad260c4..0000000 --- a/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.hx +++ /dev/null @@ -1,52 +0,0 @@ -package ru.m.tankz.view.classic; - -import haxework.view.ButtonView; -import haxework.view.DataView; -import haxework.view.frame.FrameSwitcher; -import haxework.view.ToggleButtonView; -import ru.m.tankz.config.Config; -import ru.m.tankz.view.common.LevelFrame; -import ru.m.tankz.preset.ClassicGame; - -@:template class ClassicLevelFrame extends LevelFrame { - public static inline var ID = "classic.level"; - - @:view var presets(default, null):DataView; - @:view var levels(default, null):DataView; - - @:provide var frames:FrameSwitcher; - - private function onShow():Void { - gameType = ClassicGame.TYPE; - levels.data = [for (i in 0...config.game.levels) i]; - presets.data = config.presets; - setSelectedPreset(preset); - } - - private function setSelectedPreset(preset:GamePreset) { - for (view in presets.views) { - cast(view, ToggleButtonView).on = view.id == preset.id; - } - } - - private function presetViewFactory(index:Int, preset:GamePreset):ToggleButtonView { - var view = new ToggleButtonView(); - view.id = preset.id; - view.text = '${preset.id}'; - resources.skin.bind("button.simple", view, "skin"); - return view; - } - - override private function set_preset(value:GamePreset):GamePreset { - var result = super.set_preset(value); - setSelectedPreset(result); - return result; - } - - - override private function set_level(value:Int):Int { - var result = super.set_level(value); - frames.change(ClassicGameFrame.ID); - return result; - } -} diff --git a/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.yaml b/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.yaml deleted file mode 100644 index 3adfa5a..0000000 --- a/src/client/haxe/ru/m/tankz/view/classic/ClassicLevelFrame.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -skinId: container -layout: - $type: haxework.view.layout.VerticalLayout -views: - - $type: haxework.view.LabelView - skinId: text.header - text: Classic - - id: presets - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.HorizontalLayout - hAlign: center - margin: 2 - factory: $this:presetViewFactory - +onDataSelect: $code:function(value) preset = value - geometry.padding: 10 - - id: levels - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.TailLayout - rowSize: 10 - margin: 5 - factory: $this:levelViewFactory - +onDataSelect: $code:function(value) level = value - geometry.padding: 10 diff --git a/src/client/haxe/ru/m/tankz/view/common/LevelFrame.hx b/src/client/haxe/ru/m/tankz/view/common/LevelFrame.hx deleted file mode 100644 index 5e3758e..0000000 --- a/src/client/haxe/ru/m/tankz/view/common/LevelFrame.hx +++ /dev/null @@ -1,50 +0,0 @@ -package ru.m.tankz.view.common; - -import haxework.resources.IResources; -import haxework.view.ButtonView; -import haxework.view.GroupView; -import ru.m.tankz.bundle.IConfigBundle; -import ru.m.tankz.config.Config; -import ru.m.tankz.game.GameState; -import ru.m.tankz.Type; - -class LevelFrame extends GroupView { - - public var gameType(default, set):GameType; - public var preset(default, set):GamePreset; - public var level(default, set):Int; - private var config(default, null):Config; - - @:provide var configBundle:IConfigBundle; - @:provide var state:GameState; - @:provide var resources:IResources; - - private function set_gameType(value:GameType):GameType { - if (gameType != value || true) { // ToDo: - gameType = value; - config = configBundle.get(gameType); - preset = config.presets[0]; - } - return gameType; - } - - private function set_preset(value:GamePreset):GamePreset { - if (preset != value || true) { // ToDo: - preset = value; - state = new GameState(gameType, preset.id); - } - return preset; - } - - private function set_level(value:Int):Int { - state.level = value; - return state.level; - } - - private function levelViewFactory(index:Int, level:Int):ButtonView { - var view = new ButtonView(); - view.text = '${level}'; - resources.skin.bind("button.level", view, "skin"); - return view; - } -} diff --git a/src/client/haxe/ru/m/tankz/view/common/LevelView.hx b/src/client/haxe/ru/m/tankz/view/common/LevelView.hx new file mode 100644 index 0000000..825f6d5 --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/common/LevelView.hx @@ -0,0 +1,46 @@ +package ru.m.tankz.view.common; + +import haxework.signal.Signal; +import haxework.view.core.Geometry; +import haxework.view.GroupView; +import haxework.view.LabelView; +import haxework.view.VGroupView; +import ru.m.tankz.config.Config; + +@:template class LevelView extends VGroupView { + + public var level(default, set):LevelConfig; + public var selected(default, set):Bool = false; + public var onStart:Signal = new Signal(); + + @:view("index") var indexView:LabelView; + @:view("name") var nameView:LabelView; + @:view("info") var infoView:GroupView; + + private function set_level(value:LevelConfig):LevelConfig { + if (level != value) { + level = value; + nameView.text = '${level.index}. ${level.name != null ? level.name : "#"}'; + indexView.text = '${level.index}'; + } + return level; + } + + private function set_selected(value:Bool):Bool { + if (selected != value) { + selected = value; + infoView.visible = selected; + infoView.geometry.position = selected ? Position.LAYOUT : Position.ABSOLUTE; + indexView.visible = !selected; + indexView.geometry.position = selected ? Position.ABSOLUTE : Position.LAYOUT; + toUpdateParent(); + } + return selected; + } + + public static function factory(index:Int, level:LevelConfig):LevelView { + var view = new LevelView(); + view.level = level; + return view; + } +} diff --git a/src/client/haxe/ru/m/tankz/view/common/LevelView.yaml b/src/client/haxe/ru/m/tankz/view/common/LevelView.yaml new file mode 100644 index 0000000..25c866a --- /dev/null +++ b/src/client/haxe/ru/m/tankz/view/common/LevelView.yaml @@ -0,0 +1,22 @@ +--- +skinId: light +views: + - id: index + $type: haxework.view.LabelView + skinId: text + geometry.padding: [20, 15] + - id: info + geometry.padding: [20, 15] + geometry.position: absolute + layout.margin: 10 + visible: false + $type: haxework.view.VGroupView + views: + - id: name + $type: haxework.view.LabelView + skinId: text + - $type: haxework.view.HGroupView + views: + - $type: haxework.view.ButtonView + skinId: button.start + +onPress: $code:onStart.emit(level) diff --git a/src/client/haxe/ru/m/tankz/view/death/DeathGameFrame.hx b/src/client/haxe/ru/m/tankz/view/death/DeathGameFrame.hx index 2a31e60..8cfe1f2 100755 --- a/src/client/haxe/ru/m/tankz/view/death/DeathGameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/death/DeathGameFrame.hx @@ -6,7 +6,7 @@ import ru.m.tankz.view.common.IGamePanel; @:template class DeathGameFrame extends GameFrame { - public static inline var ID = "death.game"; + public static inline var ID = "death"; @:view("render") private var renderView(default, null):Render; @:view("panel") private var panelView(default, null):IGamePanel; diff --git a/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.hx b/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.hx deleted file mode 100644 index e9ed3c2..0000000 --- a/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.hx +++ /dev/null @@ -1,38 +0,0 @@ -package ru.m.tankz.view.death; - -import Lambda; -import haxework.view.ButtonView; -import haxework.view.DataView; -import haxework.view.frame.FrameSwitcher; -import ru.m.tankz.game.GameState; -import ru.m.tankz.preset.DeathGame; -import ru.m.tankz.view.common.LevelFrame; -import ru.m.tankz.view.common.PlayerView; - -@:template class DeathLevelFrame extends LevelFrame { - public static inline var ID = "death.level"; - - @:view var levels(default, null):DataView; - @:view var players(default, null):DataView, PlayerView>; - - @:provide var frames:FrameSwitcher; - - private function onShow():Void { - gameType = DeathGame.TYPE; - levels.data = [for (i in 0...config.game.levels) i]; - players.data = [for (i in 0...2) Lambda.array(state.players)]; - } - - private function playerViewFactory(index:Int, data:Array):PlayerView { - var view = new PlayerView(); - view.item_index = index; - view.data = data; - return view; - } - - override private function set_level(value:Int):Int { - var result = super.set_level(value); - frames.change(DeathGameFrame.ID); - return result; - } -} diff --git a/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.yaml b/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.yaml deleted file mode 100644 index ac5c701..0000000 --- a/src/client/haxe/ru/m/tankz/view/death/DeathLevelFrame.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -skinId: container -layout: - $type: haxework.view.layout.VerticalLayout -views: - - $type: haxework.view.LabelView - skinId: text.header - text: DeathMatch - - id: players - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.VerticalLayout - hAlign: right - factory: $this:playerViewFactory - geometry.padding: 10 - - id: levels - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.TailLayout - rowSize: 10 - margin: 5 - factory: $this:levelViewFactory - +onDataSelect: $code:function(value) level = value - geometry.padding: 10 diff --git a/src/client/haxe/ru/m/tankz/view/dota/DotaGameFrame.hx b/src/client/haxe/ru/m/tankz/view/dota/DotaGameFrame.hx index 6befb37..77c1a76 100755 --- a/src/client/haxe/ru/m/tankz/view/dota/DotaGameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/dota/DotaGameFrame.hx @@ -6,7 +6,7 @@ import ru.m.tankz.render.Render; @:template class DotaGameFrame extends GameFrame { - public static inline var ID = "dota.game"; + public static inline var ID = "dota"; @:view("render") private var renderView(default, null):Render; @:view("panel") private var panelView(default, null):IGamePanel; diff --git a/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.hx b/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.hx deleted file mode 100644 index 1c38396..0000000 --- a/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.hx +++ /dev/null @@ -1,39 +0,0 @@ -package ru.m.tankz.view.dota; - -import Lambda; -import haxework.view.ButtonView; -import haxework.view.DataView; -import haxework.view.frame.FrameSwitcher; -import ru.m.tankz.view.common.LevelFrame; -import ru.m.tankz.view.common.PlayerView; -import ru.m.tankz.game.GameState; -import ru.m.tankz.preset.DotaGame; - -@:template class DotaLevelFrame extends LevelFrame { - public static inline var ID = "dota.level"; - - @:view var levels(default, null):DataView; - @:view var players(default, null):DataView, PlayerView>; - - @:provide var frames:FrameSwitcher; - - private function onShow():Void { - gameType = DotaGame.TYPE; - levels.data = [for (i in 0...config.game.levels) i]; - players.data = [for (i in 0...2) Lambda.array(state.players)]; - } - - private function playerViewFactory(index:Int, data:Array):PlayerView { - var view = new PlayerView(); - view.item_index = index; - view.data = data; - view.colorize = true; - return view; - } - - override private function set_level(value:Int):Int { - var result = super.set_level(value); - frames.change(DotaGameFrame.ID); - return result; - } -} diff --git a/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.yaml b/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.yaml deleted file mode 100644 index f70f6f9..0000000 --- a/src/client/haxe/ru/m/tankz/view/dota/DotaLevelFrame.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -skinId: container -layout: - $type: haxework.view.layout.VerticalLayout -views: - - $type: haxework.view.LabelView - skinId: text.header - text: DotA - - id: players - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.VerticalLayout - hAlign: right - factory: $this:playerViewFactory - geometry.padding: 10 - - id: levels - $type: haxework.view.DataView - layout: - $type: haxework.view.layout.TailLayout - rowSize: 10 - margin: 5 - factory: $this:levelViewFactory - +onDataSelect: $code:function(value) level = value - geometry.padding: 10 diff --git a/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.hx b/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.hx index ed963d2..4674379 100644 --- a/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.hx +++ b/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.hx @@ -1,6 +1,5 @@ package ru.m.tankz.view.settings; -import haxework.view.ButtonView; import haxework.view.DataView; import haxework.view.LabelView; import haxework.view.VGroupView; @@ -14,9 +13,6 @@ import ru.m.tankz.storage.SettingsStorage; @:view var label:LabelView; @:view var list:DataView; - @:view var change:ButtonView; - @:view var clear:ButtonView; - @:view var reset:ButtonView; @:provide var storage:SettingsStorage; @@ -34,44 +30,35 @@ import ru.m.tankz.storage.SettingsStorage; return view; } - public function onPress(view:ButtonView):Void { - switch (view.id) { - case "change": _change(); - case "clear": _clear(); - case "reset": _reset(); - case _: - } - } - private function onItemSelect(index:Int, value:ActionItem, view:ActionView):Void { view.edit(); } - private function _change():Void { + private function change():Void { var p: Promise = Promise.promise(0); for (view in list.views) { var v: ActionView = cast view; p = p.pipe(function(_):Promise return v.edit()); } - p.then(function(_) _save()); + p.then(function(_) save()); } - private function _clear():Void { + private function clear():Void { for (item in list.data) { item.key = -1; } list.data = list.data; list.toUpdate(); - _save(); + save(); } - private function _reset():Void { + private function reset():Void { list.data = SettingsStorage.getDefaultActionConfig(controlIndex).data; list.toUpdate(); - _save(); + save(); } - private function _save():Void { + private function save():Void { storage.setActionConffig(controlIndex, new ActionConfig(list.data)); } } diff --git a/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.yaml b/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.yaml index 7b7f0e8..b9bee76 100644 --- a/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.yaml +++ b/src/client/haxe/ru/m/tankz/view/settings/SettingsEditor.yaml @@ -9,17 +9,17 @@ views: views: - id: change $type: haxework.view.ButtonView - +onPress: $this:onPress + +onPress: $code:change() skinId: button.simple text: Change - id: clear $type: haxework.view.ButtonView - +onPress: $this:onPress + +onPress: $code:clear() skinId: button.simple text: Clear - id: reset $type: haxework.view.ButtonView - +onPress: $this:onPress + +onPress: $code:reset() skinId: button.simple text: Reset - id: list diff --git a/src/client/resources/image/icon/play-circle-solid.svg b/src/client/resources/image/icon/play-circle-solid.svg new file mode 100644 index 0000000..cc067c5 --- /dev/null +++ b/src/client/resources/image/icon/play-circle-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index c7e048a..978aff1 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -75,7 +75,7 @@ typedef PlayerConfig = { @:optional var protect:Float; @:optional var life:Int; @:optional var color:Color; - @:optional var human:Bool; + @:optional var human:Int; } typedef EagleConfig = { @@ -97,6 +97,7 @@ typedef GamePreset = { } typedef LevelConfig = { + @:optional var index:Int; var data:Array; @:optional var name:String; @:optional var points:Array; diff --git a/src/common/haxe/ru/m/tankz/game/Game.hx b/src/common/haxe/ru/m/tankz/game/Game.hx index d76ff3d..9a52c2b 100644 --- a/src/common/haxe/ru/m/tankz/game/Game.hx +++ b/src/common/haxe/ru/m/tankz/game/Game.hx @@ -55,7 +55,7 @@ class Game extends GameDispatcher { public var teams(default, null):Map; public var config(default, null):Config; public var engine(default, null):Engine; - public var loser(default, null):Null; + public var winner(default, null):Null; public var state(default, null):GameState; @@ -108,7 +108,7 @@ class Game extends GameDispatcher { public function start(state:GameState):Void { this.state = state; - this.loser = null; + this.winner = null; var level:LevelConfig = levelBundle.get(type, config, state.level); points = level.points != null ? level.points : config.points; engine.map.setData(level.data); @@ -162,6 +162,27 @@ class Game extends GameDispatcher { onGameChange.emit(state); } + private function checkComplete() { + var actives:Array = []; + for (team in teams.iterator()) { + if (team.isAlive) { + if (team.eagleId > 0) { + if (!cast(engine.entities[team.eagleId], Eagle).death) { + actives.push(team.id); + } + } else { + actives.push(team.id); + } + } + } + if (actives.length == 1) { + win(actives[0]); + } + if (actives.length == 0) { + win(null); + } + } + private function complete():Void { for (team in teams.iterator()) { for (player in team.players) { @@ -190,7 +211,7 @@ class Game extends GameDispatcher { case [EAGLE(eagle), DEATH(playerId)]: if (eagle.death) { getPlayer(playerId).state.score += eagle.score * (eagle.team == playerId.team ? 0 : 1); - lose(eagle.team); + checkComplete(); onGameChange.emit(state); } case [TANK(tank), HIT]: @@ -233,7 +254,7 @@ class Game extends GameDispatcher { team.spawner.push(player.id); } if (!team.isAlive) { - lose(team.id); + checkComplete(); } if (tank.bonus) { spawnBonus(); @@ -252,8 +273,8 @@ class Game extends GameDispatcher { } } - private function lose(teamId:TeamId):Void { - loser = teamId; + private function win(teamId:TeamId):Void { + winner = teamId; complete(); } @@ -263,7 +284,7 @@ class Game extends GameDispatcher { public function next():Option { for (rule in config.game.complete) { - if (rule.team != null && rule.team == loser) { + if (rule.team != null && rule.team != winner) { return Option.None; } } diff --git a/src/common/haxe/ru/m/tankz/game/GameState.hx b/src/common/haxe/ru/m/tankz/game/GameState.hx index 04686ee..237d806 100644 --- a/src/common/haxe/ru/m/tankz/game/GameState.hx +++ b/src/common/haxe/ru/m/tankz/game/GameState.hx @@ -78,9 +78,9 @@ class GameState { @:provide private var configBundle:IConfigBundle; - public function new(type:GameType, presetId:PresetId, level:Int = 0, state:GameState = null) { + public function new(type:GameType, presetId:PresetId = null, level:Int = 0, state:GameState = null) { this.type = type; - this.presetId = presetId; + this.presetId = presetId != null ? presetId : config.presets[0].id; this.level = level; if (state == null) { this.teams = new Map(); @@ -89,7 +89,7 @@ class GameState { var teamState = new TeamState(team.id); for (player in team.players) { var playerId = new PlayerId(team.id, player.index); - var controller = player.human ? HUMAN(player.index) : NONE; + var controller = player.human > 0 ? HUMAN(player.human - 1) : NONE; var playerState = new PlayerState(playerId, controller); players[playerId] = playerState; teamState.players[player.index] = playerState; diff --git a/src/common/resources/classic/config.yaml b/src/common/resources/classic/config.yaml index 4f4d8ac..cb422ea 100644 --- a/src/common/resources/classic/config.yaml +++ b/src/common/resources/classic/config.yaml @@ -23,7 +23,6 @@ player: human: &human life: 3 protect: 5 - human: true tanks: - {type: human0, rate: 1} bot: &bot @@ -41,7 +40,7 @@ presets: teams: - id: human players: - - {<<: *human, index: 0, color: 0xFFFF00} + - {<<: *human, index: 0, color: 0xFFFF00, human: 1} - id: bot spawnInterval: 3000 life: 20 @@ -55,8 +54,8 @@ presets: teams: - id: human players: - - {<<: *human, index: 0, color: 0xFFFF00} - - {<<: *human, index: 1, color: 0x15C040} + - {<<: *human, index: 0, color: 0xFFFF00, human: 1} + - {<<: *human, index: 1, color: 0x15C040, human: 2} - id: bot spawnInterval: 3000 life: 20 diff --git a/src/common/resources/death/config.yaml b/src/common/resources/death/config.yaml index 23abf1a..f58aba5 100644 --- a/src/common/resources/death/config.yaml +++ b/src/common/resources/death/config.yaml @@ -1,7 +1,8 @@ game: levels: 1 friendlyFire: true - complete: [] + complete: + - team: alpha map: cellWidth: 22 @@ -35,6 +36,8 @@ presets: teams: - id: alpha color: 0xFF4422 + players: + - {<<: *player, index: 0, human: 1} <<: *team - id: beta color: 0xFFD000 diff --git a/src/common/resources/death/levels/level000.txt b/src/common/resources/death/levels/level000.txt index c40192b..4319ff4 100644 --- a/src/common/resources/death/levels/level000.txt +++ b/src/common/resources/death/levels/level000.txt @@ -1,2 +1,3 @@ points: [{y: 0, type: tank, direction: right, x: 0, team: alpha, index: 0}, {y: 0, type: tank, direction: right, x: 6, team: beta, index: 0}, {y: 0, type: tank, direction: right, x: 12, team: gamma, index: 0}, {y: 0, type: tank, direction: right, x: 18, team: delta, index: 0}, {y: 18, type: tank, direction: right, x: 0, team: epsilon, index: 0}, {y: 18, type: tank, direction: right, x: 6, team: zeta, index: 0}, {y: 18, type: tank, direction: right, x: 12, team: eta, index: 0}, {y: 18, type: tank, direction: right, x: 18, team: theta, index: 0}] data: "0004400004400004400000044000044000044000555555555555555555550000000000000000000002520000022000002520055503330550333055500252035502205530252000000352000025300000000000000110000000000525252011110252525005252520111102525250000000000110000000000000035200002530000002520355022055302520055503330550333055500252000002200000252000000000000000000000555555555555555555550004400004400004400000044000044000044000" +name: DeathMatch test diff --git a/src/common/resources/dota/config.yaml b/src/common/resources/dota/config.yaml index a2c4b31..1a3cf47 100644 --- a/src/common/resources/dota/config.yaml +++ b/src/common/resources/dota/config.yaml @@ -1,7 +1,8 @@ game: levels: 23 friendlyFire: true - complete: [] + complete: + - team: radiant map: cellWidth: 22 @@ -33,22 +34,28 @@ player: team: base: &team life: 20 + eagle: + score: 500 + radiant: &radiant + <<: *team + id: radiant + color: 0xff4422 + players: + - {<<: *player-slow, index: 0, human: 1, color: 0xff8866} + - {<<: *player-fast, index: 1} + - {<<: *player-slow, index: 2} + - {<<: *player-fast, index: 3} + - {<<: *player-slow, index: 4} + dire: &dire + <<: *team + id: dire + color: 0x3284ff players: - {<<: *player-slow, index: 0} - {<<: *player-fast, index: 1} - {<<: *player-slow, index: 2} - {<<: *player-fast, index: 3} - {<<: *player-slow, index: 4} - eagle: - score: 500 - radiant: &radiant - id: radiant - color: 0xff4422 - <<: *team - dire: &dire - id: dire - color: 0x3284ff - <<: *team presets: - id: default