[common] added game progress
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"pWidth": 100, "pHeight": 100,
|
||||
"views": [
|
||||
{
|
||||
"id": "state", "@type": "haxework.gui.LabelView", "@style": "label",
|
||||
"pWidth": 100, "height": 20
|
||||
},
|
||||
{
|
||||
"id": "render", "@type": "ru.m.tankz.render.Render",
|
||||
"contentSize": true
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
package ru.m.tankz.view.frames;
|
||||
|
||||
import ru.m.tankz.game.GameState;
|
||||
import haxe.ds.Option;
|
||||
import haxe.ds.Option;
|
||||
import flash.events.Event;
|
||||
import haxe.Timer;
|
||||
import haxework.gui.frame.IFrameSwitcher;
|
||||
import haxework.gui.LabelView;
|
||||
import haxework.gui.VGroupView;
|
||||
import haxework.gui.ViewBuilder;
|
||||
import haxework.provider.Provider;
|
||||
import protohx.Message;
|
||||
import ru.m.connect.IConnection;
|
||||
import ru.m.tankz.game.Game;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
||||
import ru.m.tankz.render.Render;
|
||||
|
||||
|
||||
interface GameFrameLayout {
|
||||
var state(default, null):LabelView;
|
||||
var render(default, null):Render;
|
||||
}
|
||||
|
||||
|
||||
@:template("layout/frames/game.json", "layout/styles.json")
|
||||
class GameFrame extends VGroupView implements ViewBuilder implements IPacketHandler {
|
||||
class GameFrame extends VGroupView implements ViewBuilder implements IPacketHandler implements GameFrameLayout {
|
||||
|
||||
private static inline var TAG = "GameFrame";
|
||||
|
||||
@@ -26,18 +37,53 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
||||
}
|
||||
|
||||
public function onShow():Void {
|
||||
var state:GameState = Provider.get(GameState);
|
||||
game = Provider.build(Game, state.type);
|
||||
var s:GameState = Provider.get(GameState);
|
||||
game = Provider.build(Game, s.type);
|
||||
if (game == null) {
|
||||
throw 'Unsupported game type "${state.type}"';
|
||||
throw 'Unsupported game type "${s.type}"';
|
||||
}
|
||||
game.engine.listeners.push(render);
|
||||
game.start(state);
|
||||
game.start(s).then(onGameStateChange).endThen(onGameComplete);
|
||||
content.addEventListener(Event.ENTER_FRAME, redraw);
|
||||
//Provider.get(IConnection).packetHandler.addListener(this);
|
||||
render.draw(game.engine);
|
||||
timer = new Timer(10);
|
||||
timer.run = updateEngine;
|
||||
state.text = stateString(s);
|
||||
}
|
||||
|
||||
private function stateString(state:GameState):String {
|
||||
var result:Array<String> = [];
|
||||
for (teamId in state.teams.keys()) {
|
||||
var ts:TeamState = state.teams[teamId];
|
||||
if (ts.lose) {
|
||||
result.push('${teamId}: LOSE');
|
||||
} else if (ts.life > -1) {
|
||||
result.push('${teamId}: ${ts.life}');
|
||||
} else {
|
||||
for (index in ts.players.keys()) {
|
||||
var ps:PlayerState = ts.players[index];
|
||||
if (ps.life > -1) {
|
||||
result.push('${teamId}${index}: ${ps.life}');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.join(' ');
|
||||
}
|
||||
|
||||
private function onGameStateChange(s:GameState):GameState {
|
||||
state.text = stateString(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private function onGameComplete(result:Option<GameState>):Void {
|
||||
switch (result) {
|
||||
case Option.Some(s):
|
||||
state.text = stateString(s);
|
||||
case Option.None:
|
||||
}
|
||||
Provider.get(IFrameSwitcher).change(StartFrame.ID);
|
||||
}
|
||||
|
||||
public function onHide():Void {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package ru.m.tankz.core;
|
||||
|
||||
import ru.m.tankz.game.Game;
|
||||
import ru.m.geom.Rectangle;
|
||||
|
||||
|
||||
class Eagle extends Entity {
|
||||
|
||||
public function new() {
|
||||
public var team(default, null):TeamId;
|
||||
|
||||
public function new(team:TeamId) {
|
||||
super(new Rectangle(0, 0, 44, 44));
|
||||
this.team = team;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ class ClassicGame extends Game {
|
||||
var state = new GameState();
|
||||
state.type = TYPE;
|
||||
state.level = level;
|
||||
state.players[HUMAN] = new Map();
|
||||
state.players[BOT] = new Map();
|
||||
state.teams[HUMAN] = {life: -1, players: new Map(), lose: false};
|
||||
state.teams[BOT] = {life: 20, players: new Map(), lose: false};
|
||||
for (i in 0...humans) {
|
||||
state.players[HUMAN][i] = {
|
||||
state.teams[HUMAN].players[i] = {
|
||||
index:i,
|
||||
tank:{
|
||||
group: HUMAN,
|
||||
@@ -36,7 +36,7 @@ class ClassicGame extends Game {
|
||||
};
|
||||
}
|
||||
for (i in 0...humans*2+2) {
|
||||
state.players[BOT][i] = {
|
||||
state.teams[BOT].players[i] = {
|
||||
index:i,
|
||||
tank:{
|
||||
group: BOT,
|
||||
|
||||
@@ -21,10 +21,10 @@ class DotaGame extends Game {
|
||||
var state = new GameState();
|
||||
state.type = TYPE;
|
||||
state.level = level;
|
||||
state.players[RADIANT] = new Map();
|
||||
state.players[DIRE] = new Map();
|
||||
state.teams[RADIANT] = {life: 20, players: new Map(), lose: false};
|
||||
state.teams[DIRE] = {life: 20, players: new Map(), lose: false};
|
||||
for (i in 0...TEAM_SIZE) {
|
||||
state.players[RADIANT][i] = {
|
||||
state.teams[RADIANT].players[i] = {
|
||||
index:i,
|
||||
tank:{
|
||||
group: RADIANT,
|
||||
@@ -38,7 +38,7 @@ class DotaGame extends Game {
|
||||
};
|
||||
}
|
||||
for (i in 0...TEAM_SIZE) {
|
||||
state.players[DIRE][i] = {
|
||||
state.teams[DIRE].players[i] = {
|
||||
index:i,
|
||||
tank:{
|
||||
group: DIRE,
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.bot.BotControl;
|
||||
import ru.m.tankz.control.HumanControl;
|
||||
import ru.m.tankz.config.ConfigBundle;
|
||||
import ru.m.tankz.config.LevelBundle;
|
||||
import ru.m.tankz.game.Spawner;
|
||||
import ru.m.tankz.core.Entity;
|
||||
import ru.m.tankz.core.Eagle;
|
||||
import haxe.Timer;
|
||||
import promhx.Deferred;
|
||||
import promhx.Stream;
|
||||
import ru.m.geom.Direction;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.tankz.bot.BotControl;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.config.ConfigBundle;
|
||||
import ru.m.tankz.config.LevelBundle;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.control.HumanControl;
|
||||
import ru.m.tankz.core.Eagle;
|
||||
import ru.m.tankz.core.Entity;
|
||||
import ru.m.tankz.core.EntityType;
|
||||
import ru.m.tankz.core.Tank;
|
||||
import ru.m.tankz.engine.Engine;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.game.Spawner;
|
||||
|
||||
|
||||
typedef GameType = String;
|
||||
@@ -35,6 +39,8 @@ class Game implements EngineListener {
|
||||
public var engine(default, null):Engine;
|
||||
|
||||
private var spawners:Map<TeamId, Spawner>;
|
||||
private var deferred:Deferred<GameState>;
|
||||
private var stream:Stream<GameState>;
|
||||
|
||||
public function new(type:GameType) {
|
||||
this.type = type;
|
||||
@@ -58,7 +64,8 @@ class Game implements EngineListener {
|
||||
entity.rect.direction = Direction.fromString(point.direction);
|
||||
}
|
||||
|
||||
public function start(state:GameState):Void {
|
||||
public function start(state:GameState):Stream<GameState> {
|
||||
this.deferred = new Deferred();
|
||||
this.state = state;
|
||||
var bricks = LevelBundle.get(type, config, state.level);
|
||||
engine.map.setData(bricks);
|
||||
@@ -66,7 +73,7 @@ class Game implements EngineListener {
|
||||
spawners = new Map<TeamId, Spawner>();
|
||||
for (teamConfig in config.teams) {
|
||||
var team = new Team(teamConfig);
|
||||
for (playerState in state.players.get(team.id)) {
|
||||
for (playerState in state.teams.get(team.id).players) {
|
||||
var player = new Player({team:team.id, index:playerState.index});
|
||||
team.players.push(player);
|
||||
teams.set(team.id, team);
|
||||
@@ -92,11 +99,13 @@ class Game implements EngineListener {
|
||||
}
|
||||
var eaglePoint = spawners.get(team.id).getPoint('eagle');
|
||||
if (eaglePoint != null) {
|
||||
var eagle = new Eagle();
|
||||
var eagle = new Eagle(team.id);
|
||||
applyPoint(eagle, eaglePoint);
|
||||
engine.spawn(eagle);
|
||||
}
|
||||
}
|
||||
|
||||
return stream = deferred.stream();
|
||||
}
|
||||
|
||||
private function spawn(task:SpawnTask):Void {
|
||||
@@ -106,6 +115,20 @@ class Game implements EngineListener {
|
||||
player.tankId = tank.id;
|
||||
}
|
||||
|
||||
private function complete():Void {
|
||||
for (team in teams.iterator()) {
|
||||
for (player in team.players) {
|
||||
player.control.dispose();
|
||||
}
|
||||
}
|
||||
var timer = new Timer(5000);
|
||||
timer.run = function() {
|
||||
timer.stop();
|
||||
deferred.resolve(state);
|
||||
stream.end();
|
||||
}
|
||||
}
|
||||
|
||||
public function setControl(playerId:PlayerId, control:Control):Void {
|
||||
for (team in teams.iterator()) {
|
||||
if (team.id == playerId.team) {
|
||||
@@ -134,10 +157,36 @@ class Game implements EngineListener {
|
||||
}
|
||||
}
|
||||
|
||||
private function calcTeamLife(ts:TeamState):Int {
|
||||
return Lambda.fold(ts.players, function(ps, t) return t + ps.life, ts.life);
|
||||
}
|
||||
|
||||
public function onDestroy(entity:EntityType):Void {
|
||||
switch (entity) {
|
||||
case EntityType.TANK(tank):
|
||||
spawners.get(tank.playerId.team).push(tank.playerId);
|
||||
var respawn:Bool = false;
|
||||
var teamState:TeamState = state.teams[tank.playerId.team];
|
||||
if (teamState.life > 0) {
|
||||
teamState.life--;
|
||||
respawn = true;
|
||||
} else {
|
||||
var playerState:PlayerState = teamState.players[tank.playerId.index];
|
||||
if (playerState.life > 0) {
|
||||
playerState.life--;
|
||||
respawn = true;
|
||||
}
|
||||
}
|
||||
if (respawn) {
|
||||
spawners.get(tank.playerId.team).push(tank.playerId);
|
||||
} else if (calcTeamLife(teamState) < 1) {
|
||||
state.teams[tank.playerId.team].lose = true;
|
||||
complete();
|
||||
}
|
||||
deferred.resolve(state);
|
||||
case EntityType.EAGLE(eagle):
|
||||
state.teams[eagle.team].lose = true;
|
||||
complete();
|
||||
deferred.resolve(state);
|
||||
case x:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,21 @@ typedef PlayerState = {
|
||||
}
|
||||
|
||||
|
||||
typedef TeamState = {
|
||||
var players:Map<Int, PlayerState>;
|
||||
var life:Int;
|
||||
var lose:Bool;
|
||||
}
|
||||
|
||||
|
||||
class GameState {
|
||||
public var type:GameType;
|
||||
public var level:Int;
|
||||
public var players:Map<TeamId, Map<Int, PlayerState>>;
|
||||
public var teams:Map<TeamId, TeamState>;
|
||||
|
||||
public function new() {
|
||||
type = null;
|
||||
level = -1;
|
||||
players = new Map();
|
||||
teams = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user