[client] update ResultFrame

This commit is contained in:
2019-08-01 17:15:16 +03:00
parent b9b5453f89
commit 43a34cce39
18 changed files with 196 additions and 73 deletions

View File

@@ -96,7 +96,8 @@ class AppTheme extends Theme {
], ["dark", "border"])); ], ["dark", "border"]));
register(new Style("line", [ register(new Style("line", [
"_" => null, "geometry.width" => SizeValue.fromString("100%"),
"geometry.height" => SizeValue.fromInt(2),
], ["border"])); ], ["border"]));
register(new Style("window.close", [ register(new Style("window.close", [

View File

@@ -37,7 +37,7 @@ using ru.m.tankz.view.ViewUtil;
players.sort(function(a, b) return a.id.compare(b.id)); players.sort(function(a, b) return a.id.compare(b.id));
resultView.data = players; resultView.data = players;
for (view in resultView.dataViews) { for (view in resultView.dataViews) {
view.tank = result.state.config.getPlayerTank(view.data.id).skin; view.winner = view.data.id.team == data.winner;
} }
levelLabel.text = data.level.toLevelLabel(); levelLabel.text = data.level.toLevelLabel();
nextButton.disabled = !gameStorage.get(result.level.packId).isPresetAvailable(result.level.id + 1, result.state.presetId); nextButton.disabled = !gameStorage.get(result.level.packId).isPresetAvailable(result.level.id + 1, result.state.presetId);

View File

@@ -89,7 +89,7 @@ using ru.m.tankz.view.ViewUtil;
var result = new SlotView(); var result = new SlotView();
result.select.onSelect.connect(function(controller:Controller) setController(value, controller)); result.select.onSelect.connect(function(controller:Controller) setController(value, controller));
result.control = value; result.control = value;
result.tank = start.state.config.getTank(start.state.config.getPlayer(value.playerId).tanks[0].type).skin; result.tank = start.state.config.getPlayerTank(value.playerId).skin;
return result; return result;
} }

View File

@@ -0,0 +1,23 @@
package ru.m.tankz.view.common;
import haxework.view.ImageView;
import openfl.Assets;
import ru.m.tankz.game.GameEvent;
class TankView extends ImageView {
public var tank(null, set):TankInfo;
public function new() {
super();
style = "icon.tank";
}
private function set_tank(value:TankInfo):TankInfo {
if (value != null) {
color = value.color;
image = Assets.getBitmapData('resources/image/tank/${value.skin}-0.png');
}
return value;
}
}

View File

@@ -44,10 +44,17 @@ class GamePanelHelper {
case START(start): case START(start):
panel.level.text = start.level.toLevelLabel(onelinelevel); panel.level.text = start.level.toLevelLabel(onelinelevel);
panel.teams.data = [for (team in start.state.teams) team]; panel.teams.data = [for (team in start.state.teams) team];
// ToDo: PlayerState default tank?
for (teamView in panel.teams.dataViews) { for (teamView in panel.teams.dataViews) {
for (playerView in teamView.dataViews) { for (playerView in teamView.dataViews) {
playerView.tank = config.getPlayerTank(playerView.playerId).skin; var tank = config.getPlayerTank(playerView.playerId);
playerView.color = config.getColor(playerView.playerId); playerView.tank = {
type: tank.type,
skin: tank.skin,
hits: 0,
bonus: false,
color: config.getColor(playerView.playerId),
};
} }
} }
case CHANGE(TEAM_LIFE(teamId, life)): case CHANGE(TEAM_LIFE(teamId, life)):

View File

@@ -1,61 +1,51 @@
package ru.m.tankz.view.game; package ru.m.tankz.view.game;
import haxework.color.Color;
import haxework.view.form.LabelView; import haxework.view.form.LabelView;
import haxework.view.group.VGroupView; import haxework.view.group.VGroupView;
import haxework.view.ImageView; import ru.m.tankz.game.GameEvent.TankInfo;
import openfl.Assets;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.view.common.TankView;
@:template class PlayerView extends VGroupView { @:template class PlayerView extends VGroupView {
@:view("title") public var titleView:LabelView; @:view("title") public var titleView:LabelView;
@:view("tank") public var tankImage:ImageView; @:view("tank") public var tankView:TankView;
@:view("life") public var lifeLabel:LabelView; @:view("life") public var lifeLabel:LabelView;
@:view("score") public var scoreLabel:LabelView; @:view("score") public var scoreLabel:LabelView;
public var playerId(default, default):PlayerId; public var playerId(default, default):PlayerId;
public var state(null, set):PlayerState; public var state(null, set):PlayerState;
public var tank(null, set):String; public var tank(null, set):TankInfo;
public var color(null, set):Color;
public var life(null, set):Int; public var life(null, set):Int;
public var score(null, set):Int; public var score(null, set):Int;
private inline function set_state(value:PlayerState):PlayerState { private function set_state(value:PlayerState):PlayerState {
playerId = value.id; playerId = value.id;
titleView.text = value.name != null ? value.name : playerId.index > -1 ? '${playerId.team} #${playerId.index}' : playerId.team; titleView.text = value.name != null ? value.name : playerId.format();
tank = value.tank;
color = value.color;
life = value.life; life = value.life;
score = value.score; score = value.score;
tank = value.tank;
return state; return state;
} }
private inline function set_tank(value:String):String { private function set_tank(value:TankInfo):TankInfo {
if (value != null && value != tank) {
tank = value; tank = value;
tankImage.image = Assets.getBitmapData('resources/image/tank/${tank}-0.png'); tankView.tank = tank;
}
return tank; return tank;
} }
private inline function set_color(value:Color):Color { private function set_life(value:Int):Int {
tankImage.color = value;
return value;
}
private inline function set_life(value:Int):Int {
lifeLabel.text = '${value}'; lifeLabel.text = '${value}';
return value; return value;
} }
private inline function set_score(value:Int):Int { private function set_score(value:Int):Int {
scoreLabel.text = '${value}$'; scoreLabel.text = '${value}$';
return value; return value;
} }
public static inline function factory(index:Int, data:PlayerState):PlayerView { public static function factory(index:Int, data:PlayerState):PlayerView {
var result = new PlayerView(); var result = new PlayerView();
result.state = data; result.state = data;
return result; return result;

View File

@@ -8,8 +8,7 @@ views:
layout.vAlign: middle layout.vAlign: middle
views: views:
- id: tank - id: tank
$type: haxework.view.ImageView $type: ru.m.tankz.view.common.TankView
style: icon.tank
- id: life - id: life
$type: haxework.view.form.LabelView $type: haxework.view.form.LabelView
style: text.box style: text.box

View File

@@ -0,0 +1,36 @@
package ru.m.tankz.view.result;
import openfl.utils.Assets;
import haxework.view.form.LabelView;
import haxework.view.group.HGroupView;
import ru.m.tankz.game.GameState;
import ru.m.tankz.view.common.TankView;
@:template class FragView extends HGroupView {
@:view("tank") var tankView:TankView;
@:view("title") var titleView:LabelView;
@:view("score") var scoreView:LabelView;
public var data(default, set):Frag;
private function set_data(value:Frag):Frag {
data = value;
switch data.target {
case TANK(tank):
tankView.tank = tank;
case EAGLE(color):
tankView.image = Assets.getBitmapData('resources/image/eagle/eagle.png');
tankView.color = color;
}
titleView.text = data.playerId.format();
scoreView.text = data.score.format();
return data;
}
public static function factory(index:Int, data:Frag):FragView {
var result = new FragView();
result.data = data;
return result;
}
}

View File

@@ -0,0 +1,14 @@
---
geometry.width: 100%
layout.vAlign: middle
views:
- id: tank
$type: ru.m.tankz.view.common.TankView
- id: title
$type: haxework.view.form.LabelView
- $type: haxework.view.SpriteView
geometry.width: 100%
- id: score
$type: haxework.view.form.LabelView
style: text.box
geometry.width: 100

View File

@@ -1,32 +1,36 @@
package ru.m.tankz.view.result; package ru.m.tankz.view.result;
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 haxework.view.ImageView; import haxework.view.skin.SpriteSkin;
import openfl.Assets;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.view.common.TankView;
@:template class ResultPlayerView extends VGroupView { @:template class ResultPlayerView extends VGroupView {
@:view("tank") var tankView:ImageView; @:view("tank") var tankView:TankView;
@:view("title") var titleView:LabelView; @:view("title") var titleView:LabelView;
@:view("score") var scoreView:LabelView; @:view("score") var scoreView:LabelView;
@:view("frags") var fragsView:DataView<Frag, FragView>;
public var data(default, set):PlayerState; public var data(default, set):PlayerState;
public var tank(default, set):String; public var winner(default, set):Bool;
private function set_data(value:PlayerState):PlayerState { private function set_data(value:PlayerState):PlayerState {
data = value; data = value;
titleView.text = data.name; titleView.text = data.name;
scoreView.text = '${data.score}$'; scoreView.text = '${data.score}$';
tankView.color = value.color; tankView.color = value.color;
fragsView.data = data.frags;
tankView.tank = value.tank;
return data; return data;
} }
public function set_tank(value:String):String { private function set_winner(value:Bool):Bool {
tank = value; winner = value;
tankView.image = Assets.getBitmapData('resources/image/tank/${tank}-0.png'); cast(skin, SpriteSkin).border.color = value ? 0x00ff00 : 0xff0000;
return tank; return winner;
} }
public static function factory(index:Int, data:PlayerState):ResultPlayerView { public static function factory(index:Int, data:PlayerState):ResultPlayerView {

View File

@@ -1,20 +1,29 @@
--- ---
style: light style: light
geometry.margin: 10 geometry.margin: 15
geometry.padding: 10 geometry.padding: 10
geometry.width: 50% geometry.width: 50%
geometry.height: 100% geometry.height: 100%
layout.hAlign: center layout.hAlign: center
views: views:
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
geometry.width: 100%
layout.vAlign: middle
views: views:
- id: tank - id: tank
$type: haxework.view.ImageView $type: ru.m.tankz.view.common.TankView
geometry.width: 42
geometry.height: 42
- id: title - id: title
$type: haxework.view.form.LabelView $type: haxework.view.form.LabelView
- $type: haxework.view.SpriteView
geometry.width: 100%
- id: score - id: score
$type: haxework.view.form.LabelView $type: haxework.view.form.LabelView
style: text.box style: text.box
geometry.width: 100 geometry.width: 100
- $type: haxework.view.SpriteView
style: line
- id: frags
$type: haxework.view.data.DataView
factory: ~ru.m.tankz.view.result.FragView.factory
geometry.stretch: true
overflow.y: scroll

View File

@@ -1,7 +1,5 @@
package ru.m.tankz; package ru.m.tankz;
typedef Type = Dynamic;
typedef GameType = String; typedef GameType = String;
typedef TeamId = String; typedef TeamId = String;
@@ -36,6 +34,10 @@ abstract PlayerId(Array<Dynamic>) {
return index - other.index; return index - other.index;
} }
public function format():String {
return index > -1 ? '${team} #${index}' : team;
}
@:from static public inline function fromArray(value:Array<Dynamic>):PlayerId { @:from static public inline function fromArray(value:Array<Dynamic>):PlayerId {
return new PlayerId(value[0], value[1]); return new PlayerId(value[0], value[1]);
} }
@@ -79,3 +81,10 @@ abstract PackId(Array<Dynamic>) {
typedef LevelId = Int; typedef LevelId = Int;
typedef PresetId = Int; typedef PresetId = Int;
abstract Score(Int) from Int to Int {
public function new(value:Int) this = value;
public inline function format():String return '${this}$';
}

View File

@@ -58,7 +58,7 @@ typedef TankConfig = {
@:optinal var hits:Int; @:optinal var hits:Int;
@:optinal var upgrade:TankType; @:optinal var upgrade:TankType;
@:optinal var downgrade:TankType; @:optinal var downgrade:TankType;
@:optinal var score:Null<Int>; @:optinal var score:Null<Score>;
} }
typedef BonusConfig = { typedef BonusConfig = {
@@ -137,7 +137,7 @@ class Config {
private var brickMap:Map<BrickType, BrickConfig>; private var brickMap:Map<BrickType, BrickConfig>;
private var brickMapByIndex:Map<Int, BrickConfig>; private var brickMapByIndex:Map<Int, BrickConfig>;
private var tankMap:Map<TankType, TankConfig>; private var tankMap:Map<String, TankConfig>;
private var presetsMap:Map<PresetId, GamePreset>; private var presetsMap:Map<PresetId, GamePreset>;
private var bonusMap:Map<BonusType, BonusConfig>; private var bonusMap:Map<BonusType, BonusConfig>;
private var teamsMap:Map<TeamId, TeamConfig>; private var teamsMap:Map<TeamId, TeamConfig>;

View File

@@ -4,6 +4,7 @@ import haxework.color.Color;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class Tank extends MobileEntity { class Tank extends MobileEntity {
@@ -16,6 +17,8 @@ class Tank extends MobileEntity {
public var protect(default, default):Bool; public var protect(default, default):Bool;
public var freezing(default, default):Bool; public var freezing(default, default):Bool;
public var info(get, null):TankInfo;
public function new(id:Int, rect:Rectangle, playerId:PlayerId, config:TankConfig) { public function new(id:Int, rect:Rectangle, playerId:PlayerId, config:TankConfig) {
super(id, rect, config.speed, Direction.RIGHT); super(id, rect, config.speed, Direction.RIGHT);
this.protect = false; this.protect = false;
@@ -35,6 +38,17 @@ class Tank extends MobileEntity {
return value; return value;
} }
private function get_info():TankInfo {
return {
type: config.type,
skin: config.skin,
hits: hits,
bonus: bonus,
color: color,
name: name,
}
}
override public function move(direction:Direction):Void { override public function move(direction:Direction):Void {
if (!freezing) { if (!freezing) {
super.move(direction); super.move(direction);

View File

@@ -42,13 +42,7 @@ class EventUtil {
} }
public static function buildTankSpawn(tank:Tank):GameEvent { public static function buildTankSpawn(tank:Tank):GameEvent {
return SPAWN(TANK(tank.id, tank.rect.clone(), tank.playerId, { return SPAWN(TANK(tank.id, tank.rect.clone(), tank.playerId, tank.info));
type:tank.config.type,
hits:tank.hits,
bonus:tank.bonus,
color:tank.color,
name:tank.name,
}));
} }
public static function buildBonusSpawn(bonus:Bonus):GameEvent { public static function buildBonusSpawn(bonus:Bonus):GameEvent {

View File

@@ -20,6 +20,7 @@ typedef Result = {
typedef TankInfo = { typedef TankInfo = {
var type:TankType; var type:TankType;
var skin:String;
var hits:Int; var hits:Int;
var bonus:Bool; var bonus:Bool;
var color:Color; var color:Color;

View File

@@ -11,6 +11,7 @@ import ru.m.tankz.core.Tank;
import ru.m.tankz.engine.Engine; import ru.m.tankz.engine.Engine;
import ru.m.tankz.engine.IEngine; import ru.m.tankz.engine.IEngine;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.GameState.FragTarget;
import ru.m.tankz.game.Spawner; import ru.m.tankz.game.Spawner;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.Timer; import ru.m.Timer;
@@ -240,7 +241,11 @@ class GameRunner extends Game implements EngineListener {
case [BULLET(bullet), EAGLE(eagle)]: case [BULLET(bullet), EAGLE(eagle)]:
if (!eagle.death) { if (!eagle.death) {
if (!eagle.protect) { if (!eagle.protect) {
gameEventSignal.emit(DESTROY(EAGLE(eagle.id, buildShot(bullet, eagle.score)))); var score = eagle.config.score;
if (score != null && eagle.team == bullet.playerId.team) {
score = Math.round(score * -0.5);
}
gameEventSignal.emit(DESTROY(EAGLE(eagle.id, buildShot(bullet, score))));
} }
gameEventSignal.emit(DESTROY(BULLET(bullet.id))); gameEventSignal.emit(DESTROY(BULLET(bullet.id)));
} }
@@ -388,11 +393,19 @@ class GameRunner extends Game implements EngineListener {
case SPAWN(EAGLE(id, rect, teamId)): case SPAWN(EAGLE(id, rect, teamId)):
var team = getTeam(teamId); var team = getTeam(teamId);
team.eagleId = id; team.eagleId = id;
case SPAWN(TANK(id, rect, playerId, info)):
getPlayer(playerId).state.tank = info;
case SPAWN(BULLET(_, _, playerId, _)): case SPAWN(BULLET(_, _, playerId, _)):
getPlayer(playerId).bullets++; getPlayer(playerId).bullets++;
case DESTROY(EAGLE(id, shot)): case DESTROY(EAGLE(id, shot)):
var eagle:Eagle = engine.getEntity(id); var eagle:Eagle = engine.getEntity(id);
eagle.death = true; eagle.death = true;
var shooter = getPlayer(cast(engine.getEntity(shot.tankId), Tank).playerId);
shooter.state.frags.push({
playerId: new PlayerId(eagle.team, -1),
target: EAGLE(eagle.color),
score: shot.score,
});
if (shot.score != null) { if (shot.score != null) {
var tank:Tank = engine.getEntity(shot.tankId); var tank:Tank = engine.getEntity(shot.tankId);
changeScore(tank.playerId, shot.score); changeScore(tank.playerId, shot.score);
@@ -419,9 +432,14 @@ class GameRunner extends Game implements EngineListener {
if (tank.bonus && shot.bulletId != null) { if (tank.bonus && shot.bulletId != null) {
spawnBonus(); spawnBonus();
} }
var shooter = getPlayer(cast(engine.getEntity(shot.tankId), Tank).playerId);
shooter.state.frags.push({
playerId: player.id,
target: TANK(tank.info),
score: shot.score,
});
if (shot.score != null) { if (shot.score != null) {
var shooterTank:Tank = engine.getEntity(shot.tankId); changeScore(shooter.id, shot.score);
changeScore(shooterTank.playerId, shot.score);
} }
engine.destroy(id); engine.destroy(id);
case DESTROY(BONUS(id, shot)): case DESTROY(BONUS(id, shot)):

View File

@@ -5,39 +5,43 @@ import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Controller; import ru.m.tankz.control.Controller;
import ru.m.tankz.control.PlayerControl; import ru.m.tankz.control.PlayerControl;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.Type; import ru.m.tankz.Type;
enum FragTarget {
TANK(tank:TankInfo);
EAGLE(color:Color);
}
typedef Frag = {
var playerId:PlayerId;
var target:FragTarget;
var score:Score;
}
class State { class State {
public var score:Int; public var score:Int;
public var frags:Int; public var frags:Array<Frag>;
public var shots:Int;
public var hits:Int;
public function new() { public function new() {
score = 0; score = 0;
frags = 0; frags = [];
shots = 0;
hits = 0;
} }
public function add(state:State) { public function add(state:State) {
score += state.score; score += state.score;
frags += state.frags; frags = frags.concat(state.frags);
shots += state.shots;
hits += state.hits;
} }
public function reset() { public function reset() {
score = 0; score = 0;
frags = 0; frags = [];
shots = 0;
hits = 0;
} }
} }
class PlayerState extends State { class PlayerState extends State {
public var id:PlayerId; public var id:PlayerId;
public var tank:TankType; public var tank:TankInfo;
public var color:Color; public var color:Color;
public var name:String; public var name:String;
public var life:Int; public var life:Int;