[client] level frames update

This commit is contained in:
2019-03-04 18:00:44 +03:00
parent a6323edb36
commit 74322ca6a4
27 changed files with 372 additions and 163 deletions

View File

@@ -13,10 +13,16 @@ views:
views: views:
- id: start - id: start
$type: ru.m.tankz.frame.StartFrame $type: ru.m.tankz.frame.StartFrame
- id: level # classic
$type: ru.m.tankz.frame.StartGameFrame - id: classic.level
- id: game $type: ru.m.tankz.frame.classic.ClassicLevelFrame
$type: ru.m.tankz.frame.GameFrame - id: classic.game
$type: ru.m.tankz.frame.classic.ClassicGameFrame
# dota
- id: dota.level
$type: ru.m.tankz.frame.dota.DotaLevelFrame
- id: dota.game
$type: ru.m.tankz.frame.dota.DotaGameFrame
# - id: network # - id: network
# $type: ru.m.tankz.frame.NetworkFrame # $type: ru.m.tankz.frame.NetworkFrame
- id: settings - id: settings

View File

@@ -36,7 +36,7 @@ class Style {
Skin.text(textColor, 16, fontFamily), Skin.text(textColor, 16, fontFamily),
Skin.size(100, 36), Skin.size(100, 36),
]); ]);
resources.skin.put("button.toggle", [ resources.skin.put("button.tab", [
Skin.tabColor(lightColor), Skin.tabColor(lightColor),
Skin.text(textColor, 16, fontFamily), Skin.text(textColor, 16, fontFamily),
Skin.size(200, 36), Skin.size(200, 36),

View File

@@ -1,42 +1,29 @@
package ru.m.tankz.frame; package ru.m.tankz.frame;
import ru.m.tankz.frame.classic.ClassicLevelFrame;
import ru.m.tankz.frame.dota.DotaLevelFrame;
import haxework.gui.ButtonView; import haxework.gui.ButtonView;
import haxework.gui.frame.IFrameSwitcher; import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import ru.m.tankz.game.GameState;
import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.storage.SaveStorage; import ru.m.tankz.storage.SaveStorage;
import ru.m.tankz.Type;
@:template class StartFrame extends VGroupView { @:template class StartFrame extends VGroupView {
public static var ID(default, never):String = "start"; public static var ID(default, never):String = "start";
@:view var classic(default, null):ButtonView;
@:view var dota(default, null):ButtonView;
@:view var network(default, null):ButtonView;
@:view var settings(default, null):ButtonView;
@:provide var frameSwitcher:IFrameSwitcher; @:provide var frameSwitcher:IFrameSwitcher;
@:provide var state:GameState;
@:provide var storage:SaveStorage; @:provide var storage:SaveStorage;
public function onPress(view:ButtonView):Void { public function onPress(view:ButtonView):Void {
switch (view.id) { switch (view.id) {
case 'classic': case 'classic':
startGame(ClassicGame.TYPE, ClassicGame.PLAYER1); frameSwitcher.change(ClassicLevelFrame.ID);
case 'dota': case 'dota':
startGame(DotaGame.TYPE, DotaGame.PLAYER1); frameSwitcher.change(DotaLevelFrame.ID);
case 'network': case 'network':
//frameSwitcher.change(NetworkFrame.ID); //frameSwitcher.change(NetworkFrame.ID);
case 'settings': case 'settings':
frameSwitcher.change(SettingsFrame.ID); frameSwitcher.change(SettingsFrame.ID);
} }
} }
private function startGame(type:GameType, presetId:PresetId):Void {
state = new GameState(type, presetId);
frameSwitcher.change(StartGameFrame.ID);
}
} }

View File

@@ -1,88 +0,0 @@
package ru.m.tankz.frame;
import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.list.ListView;
import haxework.gui.VGroupView;
import haxework.provider.Provider;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
import ru.m.tankz.frame.start.PresetsView;
import ru.m.tankz.game.GameState;
import ru.m.tankz.storage.SaveStorage;
import ru.m.tankz.Type;
@:template class StartGameFrame extends VGroupView {
public static inline var ID = "level";
@:view var presets(default, null):PresetsView;
@:view var players(default, null):ListView<PlayerId>;
@:view var levels(default, null):ListView<Int>;
@:provide var state:GameState;
@:provide var storage:SaveStorage;
public var gameType(default, set):GameType;
public var presetId(default, set):PresetId;
private var config:Config;
private var preset:GamePreset;
public function init():Void {
presets.change.connect(function(presetId) this.presetId = presetId);
}
private function set_gameType(value:GameType):GameType {
if (gameType != value) {
gameType = value;
config = Provider.get(IConfigBundle).get(gameType);
presets.data = config.presets;
levels.data = [for (i in 0...config.game.levels) i];
presetId = null;
presetId = config.presets[0].id;
var save:GameState = storage.read(gameType);
// ToDo: start save button
}
return gameType;
}
private function set_presetId(value:PresetId):PresetId {
if (presetId != value) {
presetId = value;
presets.selected = presetId;
state = new GameState(gameType, presetId);
if (presetId != null) {
preset = config.getPreset(presetId);
var players:Array<PlayerId> = [];
var human = true;
for (team in preset.teams) {
for (player in team.players) {
var playerId = new PlayerId(team.id, player.index);
state.control.set(playerId, human ? Control.HUMAN : Control.BOT);
human = false;
players.push(playerId);
}
}
this.players.data = players;
} else {
this.players.data = [];
}
}
toUpdate();
return presetId;
}
public function onShow():Void {
gameType = state.type;
if (state.presetId != null) {
presetId = state.presetId;
}
}
public function onListItemClick(item:IListItemView<Int>):Void {
state.level = item.data;
Provider.get(IFrameSwitcher).change(GameFrame.ID);
}
}

View File

@@ -1,36 +0,0 @@
---
geometry.size.stretch: true
views:
- id: presets
$type: ru.m.tankz.frame.start.PresetsView
geometry.size.width: 100%
geometry.margin.top: 10
geometry.margin.bottom: -3
layout.hAlign: center
- $type: haxework.gui.HGroupView
skin: $r:skin:border
geometry.size.stretch: true
views:
- id: players
$type: haxework.gui.list.VListView<PlayerId>
factory: { $class: ru.m.tankz.frame.start.PlayerView }
geometry.size.percent: [50, 100]
geometry.padding: 10
scroll:
$type: haxework.gui.list.VScrollBarView
geometry.size.width: 10
geometry.size.height: 100%
skin:
- $type: [haxework.gui.list.ScrollBarSkin.vertical]
- id: levels
$type: haxework.gui.list.VListView<Int>
factory: { $class: ru.m.tankz.frame.start.LevelView }
+onItemSelect: $this:onListItemClick
geometry.size.percent: [50, 100]
geometry.padding: 10
scroll:
$type: haxework.gui.list.VScrollBarView
geometry.size.width: 10
geometry.size.height: 100%
skin:
- $type: [haxework.gui.list.ScrollBarSkin.vertical]

View File

@@ -0,0 +1,20 @@
package ru.m.tankz.frame.classic;
import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.render.Render;
import ru.m.tankz.frame.common.GameFrame;
@:template class ClassicGameFrame extends GameFrame {
public static inline var ID = "classic.game";
@:view("render") private var renderView(default, null):Render;
@:view("panel") private var panelView(default, null):IGamePanel;
override private function get_render():Render {
return renderView;
}
override private function get_panel():IGamePanel {
return panelView;
}
}

View File

@@ -0,0 +1,13 @@
---
layout:
$type: haxework.gui.layout.HorizontalLayout
hAlign: center
vAlign: middle
geometry.size.stretch: true
views:
- id: render
$type: ru.m.tankz.render.Render
- id: panel
$type: ru.m.tankz.frame.classic.ClassicGamePanel
geometry.size.width: 200
geometry.size.height: 100%

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.frame.game; package ru.m.tankz.frame.classic;
import ru.m.tankz.frame.common.IGamePanel;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;

View File

@@ -0,0 +1,51 @@
package ru.m.tankz.frame.classic;
import haxework.gui.DataView;
import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.ToggleButtonView;
import ru.m.tankz.config.Config;
import ru.m.tankz.frame.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<GamePreset>;
@:view var levels(default, null):DataView<Int>;
@:provide var frames:IFrameSwitcher;
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;
}
}

View File

@@ -0,0 +1,25 @@
---
geometry.size.stretch: true
layout:
$type: haxework.gui.layout.VerticalLayout
hAlign: center
views:
- id: presets
$type: haxework.gui.DataView<GamePreset>
layout:
$type: haxework.gui.layout.HorizontalLayout
hAlign: center
margin: 2
factory: $this:presetViewFactory
+onDataSelect: $code:function(value) preset = value
geometry.size.width: 100%
geometry.padding: 10
- id: levels
$type: haxework.gui.DataView<Int>
layout:
$type: haxework.gui.layout.TailLayout
margin: 2
factory: $this:levelViewFactory
+onDataSelect: $code:function(value) level = value
geometry.size.stretch: true
geometry.padding: 10

View File

@@ -0,0 +1,105 @@
package ru.m.tankz.frame.common;
import flash.events.Event;
import haxe.ds.Option;
import haxe.Timer;
import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.GroupView;
import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
import ru.m.tankz.network.NetworkGame;
import ru.m.tankz.network.NetworkManager;
import ru.m.tankz.render.Render;
import ru.m.tankz.sound.SoundManager;
import ru.m.tankz.storage.SaveStorage;
class GameFrame extends GroupView {
private static inline var TAG = "GameFrame";
private var render(get, null):Render;
private var panel(get, null):IGamePanel;
@:provide var network:NetworkManager;
@:provide var sound:SoundManager;
@:provide var state:GameState;
@:provide var storage:SaveStorage;
@:provide var switcher:IFrameSwitcher;
private var game:Game;
private var timer:Timer;
private function get_render():Render {
throw "Not implemented";
}
private function get_panel():IGamePanel {
throw "Not implemented";
}
public function onShow():Void {
start(state);
}
private function start(state:GameState):Void {
game = new Game(state.type);
game.engine.connect(render);
game.engine.connect(sound);
game.start(state).then(onGameStateChange).endThen(onGameComplete);
timer = new Timer(10);
timer.run = updateEngine;
panel.game = game;
content.addEventListener(Event.ENTER_FRAME, _redraw);
render.draw(game.engine);
sound.play('start');
}
private function stop():Void {
if (timer != null) {
timer.stop();
timer = null;
}
content.removeEventListener(Event.ENTER_FRAME, _redraw);
if (game != null) {
game.dispose();
game = null;
}
render.reset();
}
private function onGameStateChange(s:GameState):GameState {
panel.toUpdate();
return s;
}
private function onGameComplete(result:Option<GameState>):Void {
switch (result) {
case Option.Some(s):
panel.toUpdate();
case Option.None:
}
switch (game.next()) {
case Option.Some(s):
var state = game.save();
this.state = state;
storage.write(state);
stop();
start(state);
case Option.None:
switcher.change(StartFrame.ID);
}
}
public function onHide():Void {
stop();
}
private function updateEngine():Void {
game.engine.update();
}
private function _redraw(_):Void {
render.draw(game.engine);
}
}

View File

@@ -1,4 +1,4 @@
package ru.m.tankz.frame.game; package ru.m.tankz.frame.common;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import haxework.gui.IView; import haxework.gui.IView;

View File

@@ -0,0 +1,59 @@
package ru.m.tankz.frame.common;
import haxework.gui.ButtonView;
import haxework.gui.GroupView;
import haxework.resources.IResources;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.GameState;
import ru.m.tankz.storage.SaveStorage;
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 storage:SaveStorage;
@:provide var resources:IResources;
private function set_gameType(value:GameType):GameType {
if (gameType != value) {
gameType = value;
config = configBundle.get(gameType);
preset = config.presets[0];
}
return gameType;
}
private function set_preset(value:GamePreset):GamePreset {
if (preset != value) {
preset = value;
state = new GameState(gameType, preset.id);
for (team in value.teams) {
for (player in team.players) {
var playerId = new PlayerId(team.id, player.index);
state.control.set(playerId, player.control != null ? player.control : Control.BOT);
}
}
}
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.simple", view, "skin");
return view;
}
}

View File

@@ -1,4 +1,4 @@
package ru.m.tankz.frame.start; package ru.m.tankz.frame.common;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
import haxework.gui.LabelView; import haxework.gui.LabelView;

View File

@@ -1,4 +1,4 @@
package ru.m.tankz.frame.start; package ru.m.tankz.frame.common;
import ru.m.draw.Color; import ru.m.draw.Color;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;

View File

@@ -1,4 +1,4 @@
package ru.m.tankz.frame.start; package ru.m.tankz.frame.common;
import haxework.resources.IResources; import haxework.resources.IResources;
import haxework.gui.ButtonView; import haxework.gui.ButtonView;
@@ -28,7 +28,7 @@ class PresetsView extends HGroupView {
removeAllViews(); removeAllViews();
for (item in data) { for (item in data) {
var view = new ToggleButtonView(); var view = new ToggleButtonView();
view.skin = resources.skin.get("button.toggle"); view.skin = resources.skin.get("button.tab");
view.text = item.id; view.text = item.id;
view.fontFamily = "Courirer New"; view.fontFamily = "Courirer New";
view.fontColor = 0xffffff; view.fontColor = 0xffffff;

View File

@@ -1,14 +1,13 @@
package ru.m.tankz.frame; package ru.m.tankz.frame.dota;
import haxework.gui.core.Geometry.Position; import ru.m.tankz.frame.classic.ClassicGamePanel;
import ru.m.tankz.frame.common.IGamePanel;
import flash.events.Event; import flash.events.Event;
import haxe.ds.Option; import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
import haxework.gui.core.Geometry.Position;
import haxework.gui.frame.IFrameSwitcher; import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import ru.m.tankz.frame.game.ClassicGamePanel;
import ru.m.tankz.frame.game.DotaGamePanel;
import ru.m.tankz.frame.game.IGamePanel;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.network.NetworkGame; import ru.m.tankz.network.NetworkGame;
@@ -20,11 +19,11 @@ import ru.m.tankz.sound.SoundManager;
import ru.m.tankz.storage.SaveStorage; import ru.m.tankz.storage.SaveStorage;
import ru.m.tankz.Type.GameType; import ru.m.tankz.Type.GameType;
@:template class GameFrame extends VGroupView { @:template class DotaGameFrame extends VGroupView {
private static inline var TAG = "GameFrame"; private static inline var TAG = "GameFrame";
public static inline var ID = "game"; public static inline var ID = "dota.game";
@:view var render(default, null):Render; @:view var render(default, null):Render;

View File

@@ -4,7 +4,7 @@ layout.hAlign: center
layout.vAlign: middle layout.vAlign: middle
views: views:
- id: dotaPanel - id: dotaPanel
$type: ru.m.tankz.frame.game.DotaGamePanel $type: ru.m.tankz.frame.dota.DotaGamePanel
geometry.size.width: 100% geometry.size.width: 100%
geometry.size.height: 20 geometry.size.height: 20
geometry.position: absolute geometry.position: absolute
@@ -17,7 +17,7 @@ views:
- id: render - id: render
$type: ru.m.tankz.render.Render $type: ru.m.tankz.render.Render
- id: classicPanel - id: classicPanel
$type: ru.m.tankz.frame.game.ClassicGamePanel $type: ru.m.tankz.frame.classic.ClassicGamePanel
geometry.size.width: 200 geometry.size.width: 200
geometry.size.height: 100% geometry.size.height: 100%
geometry.position: absolute geometry.position: absolute

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.frame.game; package ru.m.tankz.frame.dota;
import ru.m.tankz.frame.common.IGamePanel;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;

View File

@@ -0,0 +1,42 @@
package ru.m.tankz.frame.dota;
import haxework.gui.DataView;
import haxework.gui.frame.IFrameSwitcher;
import ru.m.tankz.frame.common.LevelFrame;
import ru.m.tankz.frame.common.PlayerView;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.Type;
@:template class DotaLevelFrame extends LevelFrame {
public static inline var ID = "dota.level";
@:view var levels(default, null):DataView<Int>;
@:view var players(default, null):DataView<PlayerId>;
@:provide var frames:IFrameSwitcher;
private function onShow():Void {
gameType = DotaGame.TYPE;
levels.data = [for (i in 0...config.game.levels) i];
var data = [];
for (team in preset.teams) {
for (p in team.players) {
data.push(new PlayerId(team.id, p.index));
}
}
players.data = data;
}
private function playerViewFactory(index:Int, player:PlayerId):PlayerView {
var view = new PlayerView();
view.item_index = index;
view.data = player;
return view;
}
override private function set_level(value:Int):Int {
var result = super.set_level(value);
frames.change(DotaGameFrame.ID);
return result;
}
}

View File

@@ -0,0 +1,22 @@
---
geometry.size.stretch: true
layout:
$type: haxework.gui.layout.HorizontalLayout
views:
- id: players
$type: haxework.gui.DataView<PlayerId>
layout:
$type: haxework.gui.layout.VerticalLayout
hAlign: center
factory: $this:playerViewFactory
geometry.size.percent: [50, 100]
geometry.padding: 10
- id: levels
$type: haxework.gui.DataView<Int>
layout:
$type: haxework.gui.layout.TailLayout
margin: 2
factory: $this:levelViewFactory
+onDataSelect: $code:function(value) level = value
geometry.size.percent: [50, 100]
geometry.padding: 10

View File

@@ -76,6 +76,7 @@ typedef PlayerConfig = {
@:optional var protect:Float; @:optional var protect:Float;
@:optional var life:Int; @:optional var life:Int;
@:optional var color:Color; @:optional var color:Color;
@:optional var control:ControlType;
} }
typedef TeamConfig = { typedef TeamConfig = {

View File

@@ -23,6 +23,7 @@ player:
human: &human human: &human
life: 3 life: 3
protect: 5 protect: 5
control: human
tanks: tanks:
- {type: human0, rate: 1} - {type: human0, rate: 1}
bot: &bot bot: &bot