[client] GameView rework

This commit is contained in:
2019-08-27 17:35:22 +03:00
parent 6609756065
commit 9d4558ca47
15 changed files with 122 additions and 167 deletions

View File

@@ -96,7 +96,7 @@ const client = new Project(
], ],
meta: { meta: {
width: 1024, width: 1024,
height: 576, height: 768,
}, },
flags: [ flags: [
//'proto_debug', //'proto_debug',

View File

@@ -8,7 +8,7 @@
"gulp-add": "0.0.2", "gulp-add": "0.0.2",
"gulp-clean": "^0.4.0", "gulp-clean": "^0.4.0",
"gulp-foreach": "^0.1.0", "gulp-foreach": "^0.1.0",
"gulp-haxetool": "0.0.23", "gulp-haxetool": "0.0.24",
"gulp-zip": "^5.0.0", "gulp-zip": "^5.0.0",
"yargs": "^13.2.4" "yargs": "^13.2.4"
}, },

View File

@@ -2,6 +2,7 @@ package ru.m.tankz.view;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import haxework.view.group.GroupView;
import haxework.view.layout.DefaultLayout; import haxework.view.layout.DefaultLayout;
import ru.m.control.DeviceType; import ru.m.control.DeviceType;
import ru.m.control.IControlBus; import ru.m.control.IControlBus;
@@ -13,10 +14,13 @@ import ru.m.tankz.game.record.GamePlayer;
import ru.m.tankz.game.record.GameRecord; import ru.m.tankz.game.record.GameRecord;
import ru.m.tankz.local.LocalGame; import ru.m.tankz.local.LocalGame;
import ru.m.tankz.network.NetworkGame; import ru.m.tankz.network.NetworkGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.sound.SoundManager; import ru.m.tankz.sound.SoundManager;
import ru.m.tankz.storage.GameStorage; import ru.m.tankz.storage.GameStorage;
import ru.m.tankz.storage.SettingsStorage; import ru.m.tankz.storage.SettingsStorage;
import ru.m.tankz.view.game.GameView; import ru.m.tankz.view.game.GameViewA;
import ru.m.tankz.view.game.GameViewB;
import ru.m.tankz.view.game.IGameView;
import ru.m.tankz.view.gamepad.GamepadView; import ru.m.tankz.view.gamepad.GamepadView;
@:template class GameFrame extends FrameView<GameInit> implements GameListener { @:template class GameFrame extends FrameView<GameInit> implements GameListener {
@@ -30,9 +34,11 @@ import ru.m.tankz.view.gamepad.GamepadView;
@:provide static var settings:SettingsStorage; @:provide static var settings:SettingsStorage;
@:provide static var bus:IControlBus; @:provide static var bus:IControlBus;
@:view("game") private var gameView(default, null):GameView; @:view("game") private var gameViewContainer(default, null):GroupView;
@:view private var gamepad(default, null):GamepadView; @:view private var gamepad(default, null):GamepadView;
private var gameView:IGameView;
private var game:IGame; private var game:IGame;
private var recorder:GameRecord; private var recorder:GameRecord;
@@ -51,14 +57,16 @@ import ru.m.tankz.view.gamepad.GamepadView;
case NETWORK(network): new NetworkGame(network); case NETWORK(network): new NetworkGame(network);
case RECORD(record): new GamePlayer(record); case RECORD(record): new GamePlayer(record);
} }
gameView.type = game.type; gameView = switch game.type {
case DotaGame.TYPE: GameViewB.factory(game.config);
case _: GameViewA.factory(game.config);
};
gameViewContainer.addView(gameView);
soundManager.config = game.config; soundManager.config = game.config;
gameView.render.config = game.config; gameView.render.config = game.config;
game.connect(gameView.render); game.connect(gameView.render);
game.connect(soundManager); game.connect(soundManager);
if (gameView.panel != null) { game.connect(gameView);
game.connect(gameView.panel);
}
game.connect(this); game.connect(this);
game.start(); game.start();
// ToDo: // ToDo:
@@ -77,8 +85,10 @@ import ru.m.tankz.view.gamepad.GamepadView;
game.dispose(); game.dispose();
game = null; game = null;
} }
if (gameView != null) {
gameView.render.reset(); gameView.render.reset();
} }
}
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
switch event { switch event {
@@ -92,6 +102,10 @@ import ru.m.tankz.view.gamepad.GamepadView;
override public function onHide():Void { override public function onHide():Void {
stop(); stop();
soundManager.stopAll(); soundManager.stopAll();
if (gameView != null) {
gameViewContainer.removeView(gameView);
gameView = null;
}
} }
public function close():Void { public function close():Void {

View File

@@ -4,7 +4,7 @@ overflow.x: crop
overflow.y: crop overflow.y: crop
views: views:
- id: game - id: game
$type: ru.m.tankz.view.game.GameView $type: ru.m.tankz.view.game.GameViewContainer
- id: gamepad - id: gamepad
$type: ru.m.tankz.view.gamepad.GamepadView $type: ru.m.tankz.view.gamepad.GamepadView
geometry.position: absolute geometry.position: absolute

View File

@@ -1,72 +0,0 @@
package ru.m.tankz.view.game;
import haxework.view.group.IGroupView;
import haxework.view.group.VGroupView;
import ru.m.geom.Direction;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DeathGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.render.IRender;
import ru.m.tankz.Type;
@:template class GameView extends VGroupView {
@:provide static var configBundle:IConfigBundle;
@:view public var render(default, null):IRender;
public var panel(default, null):IGamePanel;
public var type(default, set):GameType;
@:view public var top(default, null):IGroupView;
@:view public var bottom(default, null):IGroupView;
@:view public var left(default, null):IGroupView;
@:view public var right(default, null):IGroupView;
private function set_type(value:GameType):GameType {
if (type != value) {
type = value;
if (panel != null) {
panel.remove();
}
panel = buildPanel(type);
getContainer(panel.position).addView(panel);
}
return type;
}
private function buildPanel(type:GameType):IGamePanel {
return switch type {
case ClassicGame.TYPE | DeathGame.TYPE:
SideGamePanel.factory(configBundle.get(type));
case DotaGame.TYPE:
TopGamePanel.factory(configBundle.get(type));
case _:
throw 'Unsupported type: ${type}';
}
}
private function getContainer(position:Direction):IGroupView {
return switch position.toString() {
case "RIGHT": right;
case "LEFT": left;
case "TOP": top;
case "BOTTOM": bottom;
case _: throw 'Unsupported position: ${position}';
}
}
override public function update():Void {
super.update();
if (parent != null) {
var s = Math.min(parent.width / width, parent.height / height);
if (s < 1) {
content.scaleX = content.scaleY = s;
content.x = (parent.width - width * s) / 2;
content.y = (parent.height - height * s) / 2;
} else {
content.scaleX = content.scaleY = 1;
}
}
}
}

View File

@@ -1,22 +0,0 @@
---
views:
- id: top
$type: haxework.view.group.GroupView
layout.hAlign: center
geometry.width: 100%
- $type: haxework.view.group.HGroupView
views:
- id: left
$type: haxework.view.group.GroupView
layout.vAlign: middle
geometry.height: 100%
- id: render
$type: ru.m.tankz.render.Render
- id: right
$type: haxework.view.group.GroupView
layout.vAlign: middle
geometry.height: 100%
- id: bottom
$type: haxework.view.group.GroupView
layout.hAlign: center
geometry.width: 100%

View File

@@ -3,26 +3,25 @@ package ru.m.tankz.view.game;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.LabelView; import haxework.view.form.LabelView;
import haxework.view.group.HGroupView; import haxework.view.group.HGroupView;
import ru.m.geom.Direction;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.render.IRender;
@:template class TopGamePanel extends HGroupView implements IGamePanel { @:template class GameViewA extends HGroupView implements IGameView {
public var position(default, null):Direction = Direction.TOP; @:view public var render:IRender;
@:view public var teams:DataView<TeamState, TeamView>; @:view public var teams:DataView<TeamState, TeamView>;
@:view public var level:LabelView; @:view public var level:LabelView;
private var helper:GamePanelHelper; private var helper:GameViewHelper;
public static function factory(config:Config):TopGamePanel {
var result = new TopGamePanel();
result.helper = new GamePanelHelper(result, config, true);
return result;
}
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
helper.onGameEvent(event); helper.onGameEvent(event);
} }
public static function factory(config:Config):GameViewA {
var result = new GameViewA();
result.helper = new GameViewHelper(result, config);
return result;
}
} }

View File

@@ -0,0 +1,27 @@
---
views:
- id: left
$type: haxework.view.group.GroupView
layout.vAlign: middle
geometry.height: 100%
geometry.width: 50%
- id: render
$type: ru.m.tankz.render.Render
- id: right
$type: haxework.view.group.VGroupView
geometry.height: 100%
geometry.width: 50%
geometry.padding: 5
layout.vAlign: top
layout.margin: 5
views:
- id: level
$type: haxework.view.form.LabelView
style: text.box
geometry.width: 100%
- $type: haxework.view.SpriteView
geometry.height: 30%
- id: teams
$type: haxework.view.data.DataView
layout.margin: 3
factory: ~TeamView.viewFactory

View File

@@ -3,26 +3,25 @@ package ru.m.tankz.view.game;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.LabelView; import haxework.view.form.LabelView;
import haxework.view.group.VGroupView; import haxework.view.group.VGroupView;
import ru.m.geom.Direction;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.render.IRender;
@:template class SideGamePanel extends VGroupView implements IGamePanel { @:template class GameViewB extends VGroupView implements IGameView {
public var position(default, null):Direction = Direction.RIGHT; @:view public var render:IRender;
@:view public var teams:DataView<TeamState, TeamView>; @:view public var teams:DataView<TeamState, TeamView>;
@:view public var level:LabelView; @:view public var level:LabelView;
private var helper:GamePanelHelper; private var helper:GameViewHelper;
public static function factory(config:Config):SideGamePanel {
var result = new SideGamePanel();
result.helper = new GamePanelHelper(result, config);
return result;
}
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
helper.onGameEvent(event); helper.onGameEvent(event);
} }
public static function factory(config:Config):GameViewB {
var result = new GameViewB();
result.helper = new GameViewHelper(result, config, true);
return result;
}
} }

View File

@@ -0,0 +1,20 @@
---
views:
- id: top
$type: haxework.view.group.HGroupView
layout.vAlign: middle
geometry.width: 100%
views:
- id: level
$type: haxework.view.form.LabelView
style: text.box
- $type: haxework.view.SpriteView
geometry.width: 100%
- id: teams
$type: haxework.view.data.DataView
layout:
$type: haxework.view.layout.HorizontalLayout
margin: 5
factory: ~TeamView.viewFactory
- id: render
$type: ru.m.tankz.render.Render

View File

@@ -0,0 +1,20 @@
package ru.m.tankz.view.game;
import haxework.view.group.GroupView;
class GameViewContainer extends GroupView {
override public function update():Void {
super.update();
if (parent != null) {
var s = Math.min(parent.width / width, parent.height / height);
if (s < 1) {
content.scaleX = content.scaleY = s;
content.x = (parent.width - width * s) / 2;
content.y = (parent.height - height * s) / 2;
} else {
content.scaleX = content.scaleY = 1;
}
}
}
}

View File

@@ -6,20 +6,20 @@ import ru.m.tankz.Type;
using ru.m.tankz.view.ViewUtil; using ru.m.tankz.view.ViewUtil;
class GamePanelHelper { class GameViewHelper {
private var panel:IGamePanel; private var view:IGameView;
private var config:Config; private var config:Config;
private var onelinelevel:Bool; private var onelinelevel:Bool;
public function new(panel:IGamePanel, config:Config, onelinelevel:Bool = false) { public function new(view:IGameView, config:Config, onelinelevel:Bool = false) {
this.panel = panel; this.view = view;
this.config = config; this.config = config;
this.onelinelevel = onelinelevel; this.onelinelevel = onelinelevel;
} }
private function findTeamView(id:TeamId):Null<TeamView> { private function findTeamView(id:TeamId):Null<TeamView> {
for (view in panel.teams.dataViews) { for (view in view.teams.dataViews) {
if (view.teamId == id) { if (view.teamId == id) {
return view; return view;
} }
@@ -42,10 +42,10 @@ class GamePanelHelper {
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
switch event { switch event {
case START(start): case START(start):
panel.level.text = start.level.toLevelLabel(onelinelevel); view.level.text = start.level.toLevelLabel(onelinelevel);
panel.teams.data = [for (team in start.state.teams) team]; view.teams.data = [for (team in start.state.teams) team];
// ToDo: PlayerState default tank? // ToDo: PlayerState default tank?
for (teamView in panel.teams.dataViews) { for (teamView in view.teams.dataViews) {
for (playerView in teamView.dataViews) { for (playerView in teamView.dataViews) {
var tank = config.getPlayerTank(playerView.playerId); var tank = config.getPlayerTank(playerView.playerId);
playerView.tank = { playerView.tank = {

View File

@@ -1,14 +1,14 @@
package ru.m.tankz.view.game; package ru.m.tankz.view.game;
import ru.m.tankz.render.IRender;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.LabelView; import haxework.view.form.LabelView;
import haxework.view.IView; import haxework.view.IView;
import ru.m.geom.Direction;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.game.IGame; import ru.m.tankz.game.IGame;
interface IGamePanel extends IView<Dynamic> extends GameListener { interface IGameView extends IView<Dynamic> extends GameListener {
public var position(default, null):Direction; public var render(default, null):IRender;
public var teams(default, null):DataView<TeamState, TeamView>; public var teams(default, null):DataView<TeamState, TeamView>;
public var level(default, null):LabelView; public var level(default, null):LabelView;
} }

View File

@@ -1,15 +0,0 @@
---
geometry.padding: 5
geometry.height: 100%
layout.margin: 5
views:
- id: level
$type: haxework.view.form.LabelView
style: text.box
geometry.width: 100%
- $type: haxework.view.SpriteView
geometry.height: 50%
- id: teams
$type: haxework.view.data.DataView
layout.margin: 3
factory: ~TeamView.viewFactory

View File

@@ -1,15 +0,0 @@
---
geometry.width: 100%
layout.margin: 20
views:
- id: level
$type: haxework.view.form.LabelView
style: text.box
- $type: haxework.view.SpriteView
geometry.width: 100%
- id: teams
$type: haxework.view.data.DataView
layout:
$type: haxework.view.layout.HorizontalLayout
margin: 5
factory: ~TeamView.viewFactory