[common] add GameState
This commit is contained in:
@@ -17,7 +17,7 @@ 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.GameStart;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.game.Spawner;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
@@ -26,17 +26,16 @@ class Game {
|
||||
private static var TAG(default, never):String = 'Game';
|
||||
|
||||
public var type(default, null):GameType;
|
||||
public var level(default, null):Int;
|
||||
public var players(default, null):Array<PlayerType>;
|
||||
public var preset(default, null):GamePreset;
|
||||
public var teams(default, null):Map<TeamId, Team>;
|
||||
public var config(default, null):Config;
|
||||
public var engine(default, null):Engine;
|
||||
public var loser(default, null):Null<TeamId>;
|
||||
|
||||
public var state(default, null):GameState;
|
||||
|
||||
private var points:Array<SpawnPoint>;
|
||||
private var deferred:Deferred<Dynamic>;
|
||||
private var stream:Stream<Dynamic>;
|
||||
private var deferred:Deferred<GameState>;
|
||||
private var stream:Stream<GameState>;
|
||||
|
||||
@:provide var configBundle:IConfigBundle;
|
||||
@:provide var levelBundle:ILevelBundle;
|
||||
@@ -81,26 +80,25 @@ class Game {
|
||||
entity.rect.direction = point.direction;
|
||||
}
|
||||
|
||||
public function start(start:GameStart):Stream<Dynamic> {
|
||||
this.players = start.players;
|
||||
var players = players.slice(0);
|
||||
public function start(state:GameState):Stream<GameState> {
|
||||
this.state = state;
|
||||
this.loser = null;
|
||||
this.preset = config.getPreset(start.presetId);
|
||||
this.level = start.level;
|
||||
this.deferred = new Deferred();
|
||||
var level:LevelConfig = levelBundle.get(type, config, start.level);
|
||||
var level:LevelConfig = levelBundle.get(type, config, state.level);
|
||||
points = level.points != null ? level.points : config.points;
|
||||
engine.map.setData(level.data);
|
||||
teams = new Map<TeamId, Team>();
|
||||
var controlFactory:IControlFactory = Provider.build(IControlFactory);
|
||||
for (teamConfig in preset.teams) {
|
||||
var players = state.players.slice(0);
|
||||
for (teamConfig in state.preset.teams) {
|
||||
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
|
||||
var team:Team = new Team(teamConfig, teamPoints);
|
||||
teams[team.id] = team;
|
||||
for (player in team.players.iterator()) {
|
||||
var controlType:ControlType = Control.BOT;
|
||||
var nextPlayer = Lambda.find(players, function(p) return p.playerId != null && p.playerId.team == team.id);
|
||||
var nextPlayer:PlayerState = Lambda.find(players, function(p) return p.id != null && p.id.team == team.id);
|
||||
if (nextPlayer != null) {
|
||||
player.state = nextPlayer;
|
||||
players.remove(nextPlayer);
|
||||
controlType = nextPlayer.control;
|
||||
}
|
||||
@@ -116,7 +114,7 @@ class Game {
|
||||
|
||||
for (team in teams.iterator()) {
|
||||
for (player in team.players.iterator()) {
|
||||
if (team.trySpawn(player.id)) {
|
||||
if (team.tryRespawn(player.id)) {
|
||||
team.spawner.push(player.id, player.state.tank);
|
||||
}
|
||||
}
|
||||
@@ -137,15 +135,11 @@ class Game {
|
||||
var team = getTeam(task.playerId.team);
|
||||
var player = getPlayer(task.playerId);
|
||||
player.tankId = 0;
|
||||
if (getTeam(task.playerId.team).trySpawn(task.playerId, true)) {
|
||||
var tank = buildTank(task);
|
||||
player.tankId = tank.id;
|
||||
player.state.tank = tank.config.type;
|
||||
engine.spawn(tank);
|
||||
} else if (!team.isAlive) {
|
||||
lose(team.id);
|
||||
}
|
||||
deferred.resolve(null);
|
||||
var tank = buildTank(task);
|
||||
player.tankId = tank.id;
|
||||
player.state.tank = tank.config.type;
|
||||
engine.spawn(tank);
|
||||
deferred.resolve(state);
|
||||
}
|
||||
|
||||
private function complete():Void {
|
||||
@@ -156,7 +150,7 @@ class Game {
|
||||
}
|
||||
}
|
||||
Timer.delay(function() {
|
||||
deferred.resolve(null);
|
||||
deferred.resolve(state);
|
||||
stream.end();
|
||||
}, 5000);
|
||||
}
|
||||
@@ -176,7 +170,7 @@ class Game {
|
||||
case [EntityType.EAGLE(eagle), EntityChange.DEATH]:
|
||||
if (eagle.death) {
|
||||
lose(eagle.team);
|
||||
deferred.resolve(null);
|
||||
deferred.resolve(state);
|
||||
}
|
||||
case [EntityType.TANK(tank), EntityChange.HIT]:
|
||||
if (tank.bonus) {
|
||||
@@ -212,7 +206,8 @@ class Game {
|
||||
var player = getPlayer(tank.playerId);
|
||||
player.control.stop();
|
||||
player.tankId = 0; //ToDo: ?
|
||||
var respawn:Bool = team.trySpawn(player.id);
|
||||
team.onDestroy(player.id);
|
||||
var respawn:Bool = team.tryRespawn(player.id);
|
||||
if (respawn) {
|
||||
team.spawner.push(player.id);
|
||||
}
|
||||
@@ -226,12 +221,12 @@ class Game {
|
||||
getPlayer(playerId).state.frags++;
|
||||
getPlayer(playerId).state.score += tank.config.score;
|
||||
}
|
||||
deferred.resolve(null);
|
||||
deferred.resolve(state);
|
||||
case EntityType.BONUS(bonus):
|
||||
if (bonus.config.score > 0 && playerId != null) {
|
||||
getPlayer(playerId).state.score += bonus.config.score;
|
||||
}
|
||||
deferred.resolve(null);
|
||||
deferred.resolve(state);
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -245,15 +240,15 @@ class Game {
|
||||
engine.action(tankId, action);
|
||||
}
|
||||
|
||||
public function next():Option<GameStart> {
|
||||
public function next():Option<GameState> {
|
||||
for (rule in config.game.complete) {
|
||||
if (rule.team != null && rule.team == loser) {
|
||||
return Option.None;
|
||||
}
|
||||
}
|
||||
var level = this.level + 1;
|
||||
var level = this.state.level + 1;
|
||||
if (level >= config.game.levels) level = 0;
|
||||
return Option.Some(new GameStart(type, preset.id, level, players));
|
||||
return Option.Some(new GameState(type, state.presetId, level, state.players));
|
||||
}
|
||||
|
||||
public function dispose():Void {
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
typedef PlayerType = {
|
||||
var playerId: PlayerId;
|
||||
var control:ControlType;
|
||||
}
|
||||
|
||||
class GameStart {
|
||||
@:provide private var configBundle:IConfigBundle;
|
||||
|
||||
public var type(default, default):GameType;
|
||||
public var presetId(default, default):PresetId;
|
||||
public var level(default, default):Int;
|
||||
public var players(default, default):Array<PlayerType>;
|
||||
|
||||
public var preset(get, null):GamePreset;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId, level:Int = 0, players:Array<PlayerType> = null) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.level = level;
|
||||
this.players = players == null ? [] : players;
|
||||
}
|
||||
|
||||
private function get_preset():GamePreset {
|
||||
var config = configBundle.get(type);
|
||||
var preset = config.getPreset(presetId);
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
52
src/common/haxe/ru/m/tankz/game/GameState.hx
Normal file
52
src/common/haxe/ru/m/tankz/game/GameState.hx
Normal file
@@ -0,0 +1,52 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
class PlayerState {
|
||||
public var id:PlayerId;
|
||||
public var tank:TankType;
|
||||
public var control:ControlType;
|
||||
public var life:Int;
|
||||
public var score:Int;
|
||||
public var frags:Int;
|
||||
public var shots:Int;
|
||||
public var hits:Int;
|
||||
|
||||
public function new(id:PlayerId, control:ControlType = null, life:Int = 0) {
|
||||
this.id = id;
|
||||
this.tank = null;
|
||||
this.control = control == null ? Control.BOT : control;
|
||||
this.life = life;
|
||||
this.score = 0;
|
||||
this.frags = 0;
|
||||
this.shots = 0;
|
||||
this.hits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class GameState {
|
||||
|
||||
public var type:GameType;
|
||||
public var presetId:PresetId;
|
||||
public var level:Int;
|
||||
public var players:Array<PlayerState>;
|
||||
public var preset(get, null):GamePreset;
|
||||
|
||||
@:provide private var configBundle:IConfigBundle;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId, level:Int = 1, players:Array<PlayerState> = null) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.level = level;
|
||||
this.players = players == null ? [] : players;
|
||||
}
|
||||
|
||||
private function get_preset():GamePreset {
|
||||
var config = configBundle.get(type);
|
||||
var preset = config.getPreset(presetId);
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,10 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
typedef PlayerState = {
|
||||
var tank:TankType;
|
||||
var life:Int;
|
||||
var score:Int;
|
||||
var shots:Int;
|
||||
var hits:Int;
|
||||
var frags:Int;
|
||||
}
|
||||
|
||||
class Player {
|
||||
public var config(default, null):PlayerConfig;
|
||||
public var id(default, null):PlayerId;
|
||||
@@ -21,18 +13,11 @@ class Player {
|
||||
public var isAlive(get, null):Bool;
|
||||
public var state(default, default):PlayerState;
|
||||
|
||||
public function new(teamId:TeamId, config:PlayerConfig) {
|
||||
public function new(teamId:TeamId, config:PlayerConfig, state:PlayerState = null) {
|
||||
this.config = config;
|
||||
this.id = new PlayerId(teamId, config.index);
|
||||
this.control = null;
|
||||
this.state = {
|
||||
life: config.life,
|
||||
tank: null,
|
||||
score: 0,
|
||||
shots: 0,
|
||||
hits: 0,
|
||||
frags: 0,
|
||||
}
|
||||
this.state = state == null ? new PlayerState(id) : state;
|
||||
}
|
||||
|
||||
private function set_tankId(value:Int):Int {
|
||||
|
||||
@@ -69,7 +69,7 @@ class Spawner {
|
||||
|
||||
private function run():Void {
|
||||
if (timer == null) {
|
||||
timer = new Timer(config.spawnInterval == null ? 1 : config.spawnInterval);
|
||||
timer = new Timer(config.spawnInterval == null ? 500 : config.spawnInterval);
|
||||
timer.run = spawn;
|
||||
}
|
||||
}
|
||||
@@ -88,4 +88,4 @@ class Spawner {
|
||||
private function get_active():Bool {
|
||||
return queue.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,11 @@ class Team {
|
||||
public var players(default, null):Map<Int, Player>;
|
||||
public var life(default, default):Int;
|
||||
public var isAlive(get, null):Bool;
|
||||
public var score(get, null):Int;
|
||||
public var eagleId(default, default):Int;
|
||||
|
||||
private var active(default, default):Int;
|
||||
|
||||
public function new(config:TeamConfig, points:Array<SpawnPoint>) {
|
||||
this.id = config.id;
|
||||
this.config = config;
|
||||
@@ -25,19 +28,23 @@ class Team {
|
||||
this.spawner = new Spawner(config, points);
|
||||
}
|
||||
|
||||
public function trySpawn(playerId:PlayerId, spawn:Bool = false):Bool {
|
||||
public function tryRespawn(playerId:PlayerId):Bool {
|
||||
var player:Player = players[playerId.index];
|
||||
var result = false;
|
||||
if (player.state.life > 0) {
|
||||
if (spawn) player.state.life--;
|
||||
result = true;
|
||||
} else if (life > 0) {
|
||||
if (spawn) life--;
|
||||
result = true;
|
||||
}
|
||||
var result = player.state.life > 0 || life > active;
|
||||
active++;
|
||||
return result;
|
||||
}
|
||||
|
||||
public function onDestroy(playerId:PlayerId) {
|
||||
active--;
|
||||
var player:Player = players[playerId.index];
|
||||
if (player.state.life > 0) {
|
||||
player.state.life--;
|
||||
} else {
|
||||
life--;
|
||||
}
|
||||
}
|
||||
|
||||
// ToDo: eagle state?
|
||||
private function get_isAlive():Bool {
|
||||
if (life > 0) {
|
||||
@@ -53,4 +60,8 @@ class Team {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function get_score():Int {
|
||||
return Lambda.fold(players, function(p:Player, s:Int) return s + p.state.score, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user