[common] add GameStart
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
package ru.m.tankz;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.crypto.Crc32;
|
||||
|
||||
typedef Type = Dynamic;
|
||||
|
||||
typedef GameType = String;
|
||||
@@ -17,20 +14,20 @@ typedef TankType = String;
|
||||
|
||||
typedef BonusType = String;
|
||||
|
||||
class PlayerId {
|
||||
public var team(default, null):TeamId;
|
||||
public var index(default, null):Int;
|
||||
|
||||
private var _hashCode(default, null):Int;
|
||||
abstract PlayerId(Array<Dynamic>) {
|
||||
public var team(get, never):TeamId;
|
||||
public var index(get, never):Int;
|
||||
|
||||
public function new(team:TeamId, index:Int) {
|
||||
this.team = team;
|
||||
this.index = index;
|
||||
this._hashCode = Crc32.make(Bytes.ofString('${team}-${index}'));
|
||||
this = [team, index];
|
||||
}
|
||||
|
||||
public function hashCode():Int {
|
||||
return _hashCode;
|
||||
private inline function get_team():TeamId return this[0];
|
||||
|
||||
private inline function get_index():Int return this[1];
|
||||
|
||||
@:to public inline function toString():String {
|
||||
return '${team}:${index}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import haxe.Timer;
|
||||
import haxework.provider.Provider;
|
||||
import promhx.Deferred;
|
||||
import promhx.Stream;
|
||||
import ru.m.geom.Direction;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.bundle.ILevelBundle;
|
||||
@@ -18,17 +17,17 @@ 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.GameStart;
|
||||
import ru.m.tankz.game.Spawner;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
class Game {
|
||||
|
||||
private static var TAG(default, never):String = 'Game';
|
||||
|
||||
public var type(default, null):GameType;
|
||||
public var state(default, null):GameState;
|
||||
public var level(default, null):Int;
|
||||
public var players(default, null):Array<PlayerStart>;
|
||||
public var preset(default, null):GamePreset;
|
||||
public var teams(default, null):Map<TeamId, Team>;
|
||||
public var config(default, null):Config;
|
||||
@@ -36,10 +35,11 @@ class Game {
|
||||
public var loser(default, null):Null<TeamId>;
|
||||
|
||||
private var points:Array<SpawnPoint>;
|
||||
private var deferred:Deferred<GameState>;
|
||||
private var stream:Stream<GameState>;
|
||||
private var deferred:Deferred<Dynamic>;
|
||||
private var stream:Stream<Dynamic>;
|
||||
|
||||
@:provide var configBundle:IConfigBundle;
|
||||
@:provide var levelBundle:ILevelBundle;
|
||||
|
||||
public function new(type:GameType) {
|
||||
this.type = type;
|
||||
@@ -81,29 +81,34 @@ class Game {
|
||||
entity.rect.direction = point.direction;
|
||||
}
|
||||
|
||||
public function start(state:GameState):Stream<GameState> {
|
||||
this.state = state;
|
||||
public function start(start:GameStart):Stream<Dynamic> {
|
||||
this.players = start.players;
|
||||
var players = players.slice(0);
|
||||
this.loser = null;
|
||||
this.preset = config.getPreset(state.presetId);
|
||||
this.preset = config.getPreset(start.presetId);
|
||||
this.level = start.level;
|
||||
this.deferred = new Deferred();
|
||||
var level:LevelConfig = Provider.get(ILevelBundle).get(type, config, state.level);
|
||||
var level:LevelConfig = levelBundle.get(type, config, start.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 teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
|
||||
var team:Team = new Team(teamConfig, teamPoints, state);
|
||||
var team:Team = new Team(teamConfig, teamPoints);
|
||||
teams[team.id] = team;
|
||||
for (player in team.players.iterator()) {
|
||||
var controlType: ControlType = state.control.get(player.id);
|
||||
if (controlType != null) {
|
||||
var control = controlFactory.build(player.id, controlType);
|
||||
L.d(TAG, 'control(${player.id} - ${control})');
|
||||
if (control != null) {
|
||||
player.control = control;
|
||||
player.control.bind(engine);
|
||||
}
|
||||
var controlType:ControlType = Control.BOT;
|
||||
var nextPlayer = Lambda.find(players, function(p) return p.playerId != null && p.playerId.team == team.id);
|
||||
if (nextPlayer != null) {
|
||||
players.remove(nextPlayer);
|
||||
controlType = nextPlayer.control;
|
||||
}
|
||||
var control = controlFactory.build(player.id, controlType);
|
||||
L.d(TAG, 'control(${player.id} - ${control})');
|
||||
if (control != null) {
|
||||
player.control = control;
|
||||
player.control.bind(engine);
|
||||
}
|
||||
}
|
||||
team.spawner.runner = spawn;
|
||||
@@ -140,7 +145,7 @@ class Game {
|
||||
} else if (!team.isAlive) {
|
||||
lose(team.id);
|
||||
}
|
||||
deferred.resolve(state);
|
||||
deferred.resolve(null);
|
||||
}
|
||||
|
||||
private function complete():Void {
|
||||
@@ -151,7 +156,7 @@ class Game {
|
||||
}
|
||||
}
|
||||
Timer.delay(function() {
|
||||
deferred.resolve(state);
|
||||
deferred.resolve(null);
|
||||
stream.end();
|
||||
}, 5000);
|
||||
}
|
||||
@@ -160,6 +165,8 @@ class Game {
|
||||
switch (entity) {
|
||||
case EntityType.TANK(tank):
|
||||
getPlayer(tank.playerId).control.start();
|
||||
case EntityType.BULLET(bullet):
|
||||
getPlayer(bullet.playerId).state.shots++;
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -169,7 +176,7 @@ class Game {
|
||||
case [EntityType.EAGLE(eagle), EntityChange.DEATH]:
|
||||
if (eagle.death) {
|
||||
lose(eagle.team);
|
||||
deferred.resolve(state);
|
||||
deferred.resolve(null);
|
||||
}
|
||||
case [EntityType.TANK(tank), EntityChange.HIT]:
|
||||
if (tank.bonus) {
|
||||
@@ -192,6 +199,8 @@ class Game {
|
||||
switch [entity, with] {
|
||||
case [EntityType.TANK(tank), EntityType.BONUS(bonus)]:
|
||||
applyBonus(tank, bonus);
|
||||
case [EntityType.BULLET(bullet), EntityType.TANK(tank)]:
|
||||
getPlayer(bullet.playerId).state.hits++;
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -214,14 +223,15 @@ class Game {
|
||||
spawnBonus();
|
||||
}
|
||||
if (tank.config.score > 0 && playerId != null) {
|
||||
getPlayer(playerId).state.frags++;
|
||||
getPlayer(playerId).state.score += tank.config.score;
|
||||
}
|
||||
deferred.resolve(state);
|
||||
deferred.resolve(null);
|
||||
case EntityType.BONUS(bonus):
|
||||
if (bonus.config.score > 0 && playerId != null) {
|
||||
getPlayer(playerId).state.score += bonus.config.score;
|
||||
}
|
||||
deferred.resolve(state);
|
||||
deferred.resolve(null);
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -235,15 +245,15 @@ class Game {
|
||||
engine.action(tankId, action);
|
||||
}
|
||||
|
||||
public function next():Option<GameState> {
|
||||
public function next():Option<GameStart> {
|
||||
for (rule in config.game.complete) {
|
||||
if (rule.team != null && rule.team == loser) {
|
||||
return Option.None;
|
||||
}
|
||||
}
|
||||
state.level++;
|
||||
if (state.level >= config.game.levels) state.level = 0;
|
||||
return Option.Some(state);
|
||||
var level = this.level + 1;
|
||||
if (level >= config.game.levels) level = 0;
|
||||
return Option.Some(new GameStart(type, preset.id, level, players));
|
||||
}
|
||||
|
||||
public function dispose():Void {
|
||||
@@ -298,8 +308,4 @@ class Game {
|
||||
engine.destroy(tank); // :-D
|
||||
}
|
||||
}
|
||||
|
||||
public function save():GameState {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
34
src/common/haxe/ru/m/tankz/game/GameStart.hx
Normal file
34
src/common/haxe/ru/m/tankz/game/GameStart.hx
Normal file
@@ -0,0 +1,34 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
typedef PlayerStart = {
|
||||
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<PlayerStart>;
|
||||
|
||||
public var preset(get, null):GamePreset;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId, level:Int = 0, players:Array<PlayerStart> = 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,33 +0,0 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.game.Player.PlayerState;
|
||||
import haxe.ds.HashMap;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
class GameState {
|
||||
public var type(default, null):GameType;
|
||||
public var presetId(default, null):PresetId;
|
||||
public var control(default, null):HashMap<PlayerId, ControlType>;
|
||||
public var players(default, null):HashMap<PlayerId, PlayerState>;
|
||||
public var level(default, default):Int;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.control = new HashMap();
|
||||
this.players = new HashMap();
|
||||
this.level = 0;
|
||||
}
|
||||
|
||||
public function toYaml():String {
|
||||
//return Yaml.render(this, Renderer.options().setFlowLevel(0));
|
||||
return "";
|
||||
}
|
||||
|
||||
public static function fromYaml(value:String):GameState {
|
||||
//var data:Dynamic = Yaml.parse(value, Parser.options().useObjects());
|
||||
//return new GameState();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ 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 {
|
||||
@@ -27,6 +29,9 @@ class Player {
|
||||
life: config.life,
|
||||
tank: null,
|
||||
score: 0,
|
||||
shots: 0,
|
||||
hits: 0,
|
||||
frags: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package ru.m.tankz.game;
|
||||
import ru.m.tankz.Type;
|
||||
import ru.m.tankz.config.Config;
|
||||
|
||||
|
||||
class Team {
|
||||
|
||||
public var id(default, null):TeamId;
|
||||
@@ -14,14 +13,12 @@ class Team {
|
||||
public var isAlive(get, null):Bool;
|
||||
public var eagleId(default, default):Int;
|
||||
|
||||
public function new(config:TeamConfig, points:Array<SpawnPoint>, ?state:GameState) {
|
||||
public function new(config:TeamConfig, points:Array<SpawnPoint>) {
|
||||
this.id = config.id;
|
||||
this.config = config;
|
||||
this.players = new Map();
|
||||
for (playerConfig in config.players) {
|
||||
var player:Player = new Player(id, playerConfig);
|
||||
var state = state.players.get(player.id);
|
||||
if (state != null) player.state = state;
|
||||
this.players[playerConfig.index] = player;
|
||||
}
|
||||
this.life = config.life;
|
||||
|
||||
Reference in New Issue
Block a user