[common] add GameProgress

This commit is contained in:
2019-04-04 17:12:00 +03:00
parent 9dc0a4ce06
commit c0b4b2a4c1
15 changed files with 145 additions and 113 deletions

View File

@@ -1,9 +1,9 @@
package ru.m.skin; package ru.m.skin;
import haxework.color.ColorUtil;
import haxework.color.Color;
import haxework.view.ButtonView;
import format.SVG; import format.SVG;
import haxework.color.Color;
import haxework.color.ColorUtil;
import haxework.view.ButtonView;
import haxework.view.skin.ISkin; import haxework.view.skin.ISkin;
class ButtonSVGSkin implements ISkin<ButtonView> { class ButtonSVGSkin implements ISkin<ButtonView> {

View File

@@ -1,5 +1,7 @@
package ru.m.tankz; package ru.m.tankz;
import haxework.animate.FadeAnimate;
import haxework.animate.UnFadeAnimate;
import haxework.resources.IResources; import haxework.resources.IResources;
import haxework.resources.Resources; import haxework.resources.Resources;
import haxework.view.popup.PopupManager; import haxework.view.popup.PopupManager;
@@ -64,6 +66,9 @@ class Init {
controlFactory = new ClientControlFactory(); controlFactory = new ClientControlFactory();
popupManager = new PopupManager(); popupManager = new PopupManager();
popupManager.showAnimateFactory = function(v) return new UnFadeAnimate(v, 100);
popupManager.closeAnimateFactory = function(v) return new FadeAnimate(v, 100);
var host:String = getHost(); var host:String = getHost();
L.d('Init', 'host: ${host}'); L.d('Init', 'host: ${host}');
#if flash #if flash

View File

@@ -112,6 +112,11 @@ class Style {
Skin.layout(new Layout().setAlign(NONE, MIDDLE)), Skin.layout(new Layout().setAlign(NONE, MIDDLE)),
Skin.color(lightColor), Skin.color(lightColor),
]); ]);
resources.skin.put("window", [
Skin.color(darkColor),
Skin.border(ColorUtil.multiply(lightColor, 1.5), 1, 2),
Skin.geometry(new Geometry().setPadding(2)),
]);
resources.skin.put("button.settings", [ resources.skin.put("button.settings", [
Skin.size(64, 64), Skin.size(64, 64),

View File

@@ -1,8 +1,8 @@
package ru.m.tankz.storage; package ru.m.tankz.storage;
import ru.m.tankz.game.GameState;
import ru.m.tankz.Type.GameType;
import haxework.storage.SharedObjectStorage; import haxework.storage.SharedObjectStorage;
import ru.m.tankz.game.GameProgress;
import ru.m.tankz.Type.GameType;
class GameStorage extends SharedObjectStorage { class GameStorage extends SharedObjectStorage {
@@ -10,11 +10,11 @@ class GameStorage extends SharedObjectStorage {
super("game"); super("game");
} }
public function get(type:GameType, level:Int):GameState { public function get(type:GameType):GameProgress {
return read('${type}:${level}'); return exists(type) ? read(type) : new GameProgress(type);
} }
public function set(state:GameState):Void { public function set(progress:GameProgress):Void {
write('${state.type}:${state.level}', state); write(progress.type, progress);
} }
} }

View File

@@ -1,6 +1,7 @@
package ru.m.tankz.view; package ru.m.tankz.view;
import haxework.resources.IResources; import haxework.resources.IResources;
import haxework.view.ButtonView;
import haxework.view.DataView; import haxework.view.DataView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.LabelView; import haxework.view.LabelView;
@@ -11,31 +12,34 @@ import ru.m.tankz.game.GameState;
import ru.m.tankz.preset.ClassicGame; import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DeathGame; import ru.m.tankz.preset.DeathGame;
import ru.m.tankz.preset.DotaGame; import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.storage.GameStorage;
import ru.m.tankz.view.classic.ClassicGameFrame; 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.death.DeathGameFrame;
import ru.m.tankz.view.dota.DotaGameFrame; import ru.m.tankz.view.dota.DotaGameFrame;
import ru.m.tankz.view.popup.LevelPopup;
@:template class LevelFrame extends VGroupView { @:template class LevelFrame extends VGroupView {
public static inline var ID = "level"; public static inline var ID = "level";
@:view var header:LabelView; @:view var header:LabelView;
@:view var levels:DataView<LevelConfig, LevelView>; @:view var levels:DataView<Int, ButtonView>;
@:provide var state:GameState; @:provide var state:GameState;
@:provide var resources:IResources; @:provide var resources:IResources;
@:provide var swicther:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var levelBundle:ILevelBundle; @:provide var levelBundle:ILevelBundle;
@:provide var storage:GameStorage;
private var levelPopup:LevelPopup;
public function onShow():Void { public function onShow():Void {
header.text = state.type; header.text = state.type;
levels.data = [for (i in 0...state.config.game.levels) levelBundle.get(state.type, state.config, i)]; levels.data = [for (i in 0...state.config.game.levels) i];
for (view in levels.dataViews) view.onStart.connect(start);
} }
private function start(level:LevelConfig):Void { private function start(level:LevelConfig):Void {
state.level = level.index; state.level = level.index;
swicther.change(switch state.type { switcher.change(switch state.type {
case ClassicGame.TYPE: ClassicGameFrame.ID; case ClassicGame.TYPE: ClassicGameFrame.ID;
case DotaGame.TYPE: DotaGameFrame.ID; case DotaGame.TYPE: DotaGameFrame.ID;
case DeathGame.TYPE: DeathGameFrame.ID; case DeathGame.TYPE: DeathGameFrame.ID;
@@ -43,9 +47,22 @@ import ru.m.tankz.view.dota.DotaGameFrame;
}); });
} }
private function onLevelSelect(index:Int, level:LevelConfig, view:LevelView):Void { private function levelViewFactory(index:Int, level:Int):ButtonView {
for (v in levels.views) { var result = new ButtonView();
cast(v, LevelView).selected = v == view; result.skinId = "button.level";
result.text = '${level}';
result.disabled = !storage.get(state.type).isLevelAvailable(level);
return result;
} }
private function onLevelSelect(index:Int, level:Int, view:ButtonView):Void {
if (!storage.get(state.type).isLevelAvailable(level)) {
return;
}
if (levelPopup == null) {
levelPopup = new LevelPopup();
}
levelPopup.level = levelBundle.get(state.type, state.config, level);
levelPopup.show().then(start).catchError(function(_) {});
} }
} }

View File

@@ -1,8 +1,8 @@
--- ---
skinId: container
layout:
$type: haxework.view.layout.VerticalLayout
views: views:
- $type: haxework.view.VGroupView
skinId: container
views:
- id: header - id: header
$type: haxework.view.LabelView $type: haxework.view.LabelView
skinId: text.header skinId: text.header
@@ -13,6 +13,12 @@ views:
$type: haxework.view.layout.TailLayout $type: haxework.view.layout.TailLayout
rowSize: 10 rowSize: 10
margin: 5 margin: 5
factory: $code:ru.m.tankz.view.common.LevelView.factory factory: $this:levelViewFactory
+onItemSelect: $this:onLevelSelect +onItemSelect: $this:onLevelSelect
geometry.padding: 10 geometry.padding: 10
- $type: haxework.view.HGroupView
skinId: panel
views:
- $type: haxework.view.ButtonView
skinId: button.close
+onPress: $code:switcher.change('start')

View File

@@ -7,9 +7,5 @@ import haxework.view.VGroupView;
public static var ID(default, never):String = "settings"; public static var ID(default, never):String = "settings";
@:provide var frameSwitcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
public function close():Void {
frameSwitcher.change(StartFrame.ID);
}
} }

View File

@@ -16,7 +16,6 @@ views:
- $type: haxework.view.HGroupView - $type: haxework.view.HGroupView
skinId: panel skinId: panel
views: views:
- id: close - $type: haxework.view.ButtonView
$type: haxework.view.ButtonView
skinId: button.close skinId: button.close
+onPress: $code:close() +onPress: $code:switcher.change('start')

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.view.common; package ru.m.tankz.view.common;
import ru.m.tankz.storage.GameStorage;
import flash.events.Event; import flash.events.Event;
import haxe.ds.Option; import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
@@ -24,6 +25,7 @@ class GameFrame extends GroupView {
@:provide var state:GameState; @:provide var state:GameState;
@:provide("result") var result:GameState; @:provide("result") var result:GameState;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var storage:GameStorage;
private var game:Game; private var game:Game;
private var timer:Timer; private var timer:Timer;
@@ -76,7 +78,12 @@ class GameFrame extends GroupView {
public function onGameComplete(state:GameState):Void { public function onGameComplete(state:GameState):Void {
result = state; result = state;
this.state = switch game.next() { this.state = switch game.next() {
case Some(s): s; case Some(s):
// ToDo:
var progress = storage.get(game.type);
progress.completeLevel(result.level);
storage.set(progress);
s;
case None: null; case None: null;
} }
stop(); stop();

View File

@@ -1,46 +0,0 @@
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<LevelConfig> = 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;
}
}

View File

@@ -1,22 +0,0 @@
---
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)

View File

@@ -29,8 +29,8 @@ class FontLabelView extends LabelListItem<Font> {
var values = Font.enumerateFonts(true); var values = Font.enumerateFonts(true);
values.sort(function(a:Font, b:Font) { values.sort(function(a:Font, b:Font) {
return switch [a.fontType, b.fontType] { return switch [a.fontType, b.fontType] {
case [FontType.DEVICE, _]: 1; case [DEVICE, _]: 1;
case [_, FontType.DEVICE]: -1; case [_, DEVICE]: -1;
case _: 0; case _: 0;
} }
}); });

View File

@@ -0,0 +1,20 @@
package ru.m.tankz.view.popup;
import haxework.view.LabelView;
import haxework.view.popup.PopupView;
import ru.m.tankz.config.Config;
@:template class LevelPopup extends PopupView<LevelConfig> {
public var level(default, set):LevelConfig;
@:view var name:LabelView;
private function set_level(value:LevelConfig):LevelConfig {
if (level != value) {
level = value;
name.text = '${level.index}. ${level.name != null ? level.name : "#"}';
}
return level;
}
}

View File

@@ -0,0 +1,23 @@
---
layout.hAlign: center
layout.vAlign: middle
view:
$type: haxework.view.VGroupView
layout.hAlign: center
geometry.size.width: 400
geometry.size.height: 400
skinId: window
views:
- id: name
$type: haxework.view.LabelView
skinId: text
geometry.padding: [20, 15]
- $type: haxework.view.SpriteView
geometry.size.height: 100%
- $type: haxework.view.HGroupView
layout.hAlign: center
skinId: panel
views:
- $type: haxework.view.ButtonView
skinId: button.start
+onPress: $code:close(level)

View File

@@ -0,0 +1,22 @@
package ru.m.tankz.game;
import ru.m.tankz.Type.GameType;
class GameProgress {
public var type(default, null):GameType;
private var completed(default, null):Map<Int, Bool>;
public function new(type:GameType) {
this.type = type;
this.completed = new Map();
}
public function isLevelAvailable(level:Int):Bool {
return level == 0 || completed.get(level - 1);
}
public function completeLevel(level:Int):Void {
completed.set(level, true);
}
}