[common] diffilicity presets support

This commit is contained in:
2019-04-08 14:53:44 +03:00
parent d0104e4361
commit 13d01293f6
28 changed files with 248 additions and 132 deletions

View File

@@ -28,6 +28,7 @@ class ButtonSVGSkin implements ISkin<ButtonView> {
svgs.set(ButtonState.UP, buildSVG(color));
svgs.set(ButtonState.DOWN, buildSVG(ColorUtil.diff(color, -24)));
svgs.set(ButtonState.OVER, buildSVG(ColorUtil.diff(color, 24)));
svgs.set(ButtonState.DISABLED, buildSVG(ColorUtil.grey(color)));
}
public function draw(view:ButtonView):Void {

View File

@@ -134,5 +134,38 @@ class Style {
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), lightColor),
]);
resources.skin.put("preset.easy", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/smile-solid.svg"), lightColor),
]);
resources.skin.put("preset.normal", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/frown-open-solid.svg"), lightColor),
]);
resources.skin.put("preset.hard", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/sad-cry-solid.svg"), lightColor),
]);
resources.skin.put("preset.default", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), lightColor),
]);
resources.skin.put("preset.easy.complete", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/smile-solid.svg"), 0x337733),
]);
resources.skin.put("preset.normal.complete", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/frown-open-solid.svg"), 0x337733),
]);
resources.skin.put("preset.hard.complete", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/sad-cry-solid.svg"), 0x337733),
]);
resources.skin.put("preset.default.complete", [
Skin.size(64, 64),
new ButtonSVGSkin(Assets.getText("resources/image/icon/play-circle-solid.svg"), 0x337733),
]);
}
}

View File

@@ -11,12 +11,12 @@ class LevelBundle implements ILevelBundle {
public function new() {}
public function get(type:GameType, config:Config, level:Int):LevelConfig {
var key = '${type}:${level}';
public function get(type:GameType, config:Config, levelId:LevelId):LevelConfig {
var key = '${type}:${levelId}';
if (!cache.exists(key)) {
var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(level)}.txt');
var data:String = Assets.getText('resources/${type}/levels/level${LevelUtil.formatLevel(levelId)}.txt');
cache[key] = LevelUtil.loads(config, data);
cache[key].index = level;
cache[key].id = levelId;
}
return cache[key];
}

View File

@@ -2,7 +2,6 @@ package ru.m.tankz.control;
import ru.m.tankz.bot.StupidBotControl;
import ru.m.tankz.bot.HardBotControl;
import ru.m.tankz.control.Control.Controller;
import ru.m.tankz.Type;
class ClientControlFactory implements IControlFactory {

View File

@@ -6,8 +6,10 @@ import ru.m.tankz.Type.GameType;
class GameStorage extends SharedObjectStorage {
private static inline var VERSION = 1;
public function new() {
super("game");
super('game_${VERSION}');
}
public function get(type:GameType):GameProgress {

View File

@@ -1,6 +1,5 @@
package ru.m.tankz.view;
import haxework.resources.IResources;
import haxework.view.ButtonView;
import haxework.view.DataView;
import haxework.view.frame.FrameSwitcher;
@@ -13,6 +12,7 @@ import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DeathGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.storage.GameStorage;
import ru.m.tankz.Type;
import ru.m.tankz.view.classic.ClassicGameFrame;
import ru.m.tankz.view.death.DeathGameFrame;
import ru.m.tankz.view.dota.DotaGameFrame;
@@ -22,10 +22,9 @@ import ru.m.tankz.view.popup.LevelPopup;
public static inline var ID = "level";
@:view var header:LabelView;
@:view var levels:DataView<Int, ButtonView>;
@:view var levels:DataView<LevelId, ButtonView>;
@:provide var state:GameState;
@:provide var resources:IResources;
@:provide var switcher:FrameSwitcher;
@:provide var levelBundle:ILevelBundle;
@:provide var storage:GameStorage;
@@ -37,8 +36,9 @@ import ru.m.tankz.view.popup.LevelPopup;
levels.data = [for (i in 0...state.config.game.levels) i];
}
private function start(level:LevelConfig):Void {
state.level = level.index;
private function start(level:LevelConfig, preset:GamePreset):Void {
state.levelId = level.id;
state.presetId = preset.id;
switcher.change(switch state.type {
case ClassicGame.TYPE: ClassicGameFrame.ID;
case DotaGame.TYPE: DotaGameFrame.ID;
@@ -47,22 +47,29 @@ import ru.m.tankz.view.popup.LevelPopup;
});
}
private function levelViewFactory(index:Int, level:Int):ButtonView {
private function levelViewFactory(index:Int, levelId:LevelId):ButtonView {
var progress = storage.get(state.type);
var result = new ButtonView();
result.skinId = "button.level";
result.text = '${level}';
result.disabled = !storage.get(state.type).isLevelAvailable(level);
var presetsLine = [for (p in state.config.presets) progress.isPresetCompleted(levelId, p.id) ? '*' : '_'].join('');
result.text = '${levelId}\n${presetsLine}';
result.disabled = !progress.isLevelAvailable(levelId);
return result;
}
private function onLevelSelect(index:Int, level:Int, view:ButtonView):Void {
if (!storage.get(state.type).isLevelAvailable(level)) {
private function onLevelSelect(index:Int, levelId:LevelId, view:ButtonView):Void {
if (!storage.get(state.type).isLevelAvailable(levelId)) {
return;
}
if (levelPopup == null) {
levelPopup = new LevelPopup();
}
levelPopup.level = levelBundle.get(state.type, state.config, level);
levelPopup.show().then(start).catchError(function(_) {});
var level = levelBundle.get(state.type, state.config, levelId);
levelPopup.setData(
level,
state.config.presets,
storage.get(state.type)
);
levelPopup.show().then(function(preset) start(level, preset)).catchError(function(_) {});
}
}

View File

@@ -1,17 +1,16 @@
package ru.m.tankz.view;
import haxework.view.LabelView;
import haxework.view.ButtonView;
import haxework.view.DataView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.LabelView;
import haxework.view.VGroupView;
import ru.m.tankz.control.Control;
import ru.m.tankz.view.classic.ClassicGameFrame;
import ru.m.tankz.view.common.LifeView;
import ru.m.tankz.view.dota.DotaGameFrame;
import ru.m.tankz.game.GameState;
import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.view.classic.ClassicGameFrame;
import ru.m.tankz.view.common.LifeView;
import ru.m.tankz.view.dota.DotaGameFrame;
@:template class ResultFrame extends VGroupView {
public static var ID(default, never):String = "result";
@@ -37,11 +36,8 @@ import ru.m.tankz.preset.DotaGame;
}
public function onShow() {
resultView.data = Lambda.array(Lambda.filter(resultState.players, function(player:PlayerState):Bool return switch player.controller {
case HUMAN(_): true;
case _: false;
}));
levelLabel.text = 'Level ${resultState.level}';
resultView.data = Lambda.array(resultState.players);
levelLabel.text = 'Level ${resultState.levelId}';
nextButton.visible = state != null;
}
@@ -54,6 +50,6 @@ import ru.m.tankz.preset.DotaGame;
}
private function close() {
frames.change(StartFrame.ID);
frames.change(LevelFrame.ID);
}
}

View File

@@ -19,7 +19,7 @@ import ru.m.tankz.view.common.LifeView;
private var player2Id:PlayerId = new PlayerId(ClassicGame.HUMAN, 1);
public function onGameStart(state:GameState):Void {
level.text = 'Level ${state.level}';
level.text = 'Level ${state.levelId}';
}
public function onGameChange(state:GameState):Void {

View File

@@ -81,7 +81,7 @@ class GameFrame extends GroupView {
case Some(s):
// ToDo:
var progress = storage.get(game.type);
progress.completeLevel(result.level);
progress.completeLevel(result.levelId, result.presetId);
storage.set(progress);
s;
case None: null;

View File

@@ -14,7 +14,7 @@ import ru.m.tankz.view.common.LifeView;
@:view var players:DataView<PlayerState, LifeView>;
public function onGameStart(state:GameState):Void {
level.text = 'Level ${state.level}';
level.text = 'Level ${state.levelId}';
players.data = Lambda.array(state.players);
}

View File

@@ -14,7 +14,7 @@ import ru.m.tankz.view.common.LifeView;
@:view var level:LabelView;
public function onGameStart(state:GameState):Void {
level.text = 'Level ${state.level}';
level.text = 'Level ${state.levelId}';
}
public function onGameChange(state:GameState):Void {

View File

@@ -1,20 +1,37 @@
package ru.m.tankz.view.popup;
import haxework.view.ButtonView;
import haxework.view.DataView;
import haxework.view.LabelView;
import haxework.view.popup.PopupView;
import ru.m.tankz.config.Config;
import ru.m.tankz.game.GameProgress;
@:template class LevelPopup extends PopupView<LevelConfig> {
@:template class LevelPopup extends PopupView<GamePreset> {
public var level(default, set):LevelConfig;
private var level:LevelConfig;
private var progress:GameProgress;
@:view var name:LabelView;
@:view("presets") var presetsView:DataView<GamePreset, ButtonView>;
private function set_level(value:LevelConfig):LevelConfig {
if (level != value) {
level = value;
name.text = '${level.index}. ${level.name != null ? level.name : "#"}';
public function setData(level:LevelConfig, presets:Array<GamePreset>, progress:GameProgress):Void {
this.level = level;
this.progress = progress;
name.text = '${level.id}. ${level.name != null ? level.name : "#"}';
presetsView.data = presets;
}
private function presetViewFactory(index:Int, value:GamePreset):ButtonView {
var result = new ButtonView();
result.skinId = 'preset.${value.name}${progress.isPresetCompleted(level.id, value.id) ? '.complete' : ''}';
result.disabled = !progress.isPresetAvailable(level.id, value.id);
return result;
}
private function onPresetSelect(value:GamePreset):Void {
if (progress.isPresetAvailable(level.id, value.id)) {
close(value);
}
return level;
}
}

View File

@@ -14,10 +14,12 @@ view:
geometry.padding: [20, 15]
- $type: haxework.view.SpriteView
geometry.size.height: 100%
- $type: haxework.view.HGroupView
layout.hAlign: center
- id: presets
$type: haxework.view.DataView
factory: $this:presetViewFactory
+onDataSelect: $this:onPresetSelect
layout:
$type: haxework.view.layout.HorizontalLayout
hAlign: center
margin: 5
skinId: panel
views:
- $type: haxework.view.ButtonView
skinId: button.start
+onPress: $code:close(level)

View File

@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="frown-open" class="svg-inline--fa fa-frown-open fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM136 208c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm187.3 183.3c-31.2-9.6-59.4-15.3-75.3-15.3s-44.1 5.7-75.3 15.3c-11.5 3.5-22.5-6.3-20.5-18.1 7-40 60.1-61.2 95.8-61.2s88.8 21.3 95.8 61.2c2 11.9-9.1 21.6-20.5 18.1zM328 240c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"></path></svg>

After

Width:  |  Height:  |  Size: 617 B

View File

@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sad-cry" class="svg-inline--fa fa-sad-cry fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111 8 0 119 0 256c0 90.1 48.2 168.7 120 212.1V288c0-8.8 7.2-16 16-16s16 7.2 16 16v196.7c29.5 12.4 62 19.3 96 19.3s66.5-6.9 96-19.3V288c0-8.8 7.2-16 16-16s16 7.2 16 16v180.1C447.8 424.7 496 346 496 256 496 119 385 8 248 8zm-65.5 216.5c-14.8-13.2-46.2-13.2-61 0L112 233c-3.8 3.3-9.3 4-13.7 1.6-4.4-2.4-6.9-7.4-6.1-12.4 4-25.2 34.2-42.1 59.9-42.1S208 197 212 222.2c.8 5-1.7 10-6.1 12.4-5.8 3.1-11.2.7-13.7-1.6l-9.7-8.5zM248 416c-26.5 0-48-28.7-48-64s21.5-64 48-64 48 28.7 48 64-21.5 64-48 64zm149.8-181.5c-5.8 3.1-11.2.7-13.7-1.6l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L304 233c-3.8 3.3-9.3 4-13.7 1.6-4.4-2.4-6.9-7.4-6.1-12.4 4-25.2 34.2-42.1 59.9-42.1S400 197 404 222.2c.6 4.9-1.8 9.9-6.2 12.3z"></path></svg>

After

Width:  |  Height:  |  Size: 929 B

View File

@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="smile" class="svg-inline--fa fa-smile fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm194.8 170.2C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.6-16.3 11-36.7 24.6-20.5 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c13.4-16.2 38.1 4.2 24.6 20.5z"></path></svg>

After

Width:  |  Height:  |  Size: 616 B