Files
tankz/src/common/haxe/ru/m/tankz/game/Game.hx
2019-05-07 17:21:01 +03:00

125 lines
4.7 KiB
Haxe

package ru.m.tankz.game;
import ru.m.geom.Point;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
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.engine.IEngine;
import ru.m.tankz.game.GameState;
import ru.m.tankz.game.IGame;
import ru.m.tankz.Type;
@:dispatcher(GameListener) class Game implements IGame implements GameListener {
private static var TAG(default, never):String = "Game";
public var type(default, null):GameType;
public var teams(default, null):Map<TeamId, Team>;
public var config(default, null):Config;
public var engine(default, null):IEngine;
public var winner(default, null):Null<TeamId>;
public var state(default, null):GameState;
private var builder:EntityBuilder;
@:provide var configBundle:IConfigBundle;
public function new(state:GameState) {
this.type = state.type;
this.teams = new Map();
this.config = configBundle.get(type);
this.engine = new Engine(config);
this.builder = new EntityBuilder(config);
connect(this);
prepare(state);
}
private function prepare(state:GameState):Void {
var level:LevelConfig = state.level;
var points:Array<SpawnPoint> = level.points != null ? level.points : config.points;
engine.map.setData(level.data);
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, state.teams[teamConfig.id]);
teams[team.id] = team;
}
}
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
entity.rect.center = new Point((point.x + 1) * config.map.cellWidth, (point.y + 1) * config.map.cellHeight);
entity.rect.direction = point.direction;
}
public inline function getTeam(teamId:TeamId):Team {
return teams[teamId];
}
public inline function getPlayer(playerId:PlayerId):Player {
return teams[playerId.team].players[playerId.index];
}
public function onGameEvent(event:GameEvent):Void {
switch event {
case GameEvent.START(state):
this.state = state;
case GameEvent.COMPLETE(state, team):
this.state = state;
this.winner = team.id;
case GameEvent.SPAWN(EAGLE(teamId, point)):
var eagle = builder.buildEagle(teamId);
applyPoint(eagle, point);
var team = getTeam(teamId);
team.eagleId = eagle.id;
engine.spawn(eagle);
case GameEvent.SPAWN(TANK(playerId, type, point)):
var tank = builder.buildTank(playerId, type);
applyPoint(tank, point);
var player = getPlayer(playerId);
player.tankId = tank.id;
player.state.tank = tank.config.type;
// ToDo: in GameRunner?
if (player.config.protect > 0) {
tank.protect.on(player.config.protect);
}
tank.bonus = Math.random() < player.config.bonus;
//
engine.spawn(tank);
case GameEvent.SPAWN(BULLET(playerId)):
var player = getPlayer(playerId);
var tank:Tank = cast engine.entities.get(player.tankId);
var bullet = builder.buildBullet(playerId, tank.config.type);
bullet.tank = tank;
var rect = tank.rect;
bullet.rect.center = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y));
bullet.move(rect.direction);
engine.spawn(bullet);
case GameEvent.SPAWN(BONUS(type, point)):
var bonus = builder.buildBonus(type);
bonus.rect.x = point.x * config.map.cellWidth;
bonus.rect.y = point.y * config.map.cellHeight;
engine.spawn(bonus);
case GameEvent.DESTROY(TANK(tank, who, wherewith, score)):
engine.destroy(tank.id);
case GameEvent.DESTROY(BONUS(bonus, who, score)):
engine.destroy(bonus.id);
case GameEvent.DESTROY(BULLET(bullet)):
engine.destroy(bullet.id);
case GameEvent.ACTION(tankId, MOVE(direction)):
engine.move(tankId, direction);
case GameEvent.ACTION(tankId, STOP):
engine.stop(tankId);
case _:
}
}
public function dispose():Void {
gameEventSignal.dispose();
engine.dispose();
}
}