[common] update GameEvent

This commit is contained in:
2019-04-25 17:21:03 +03:00
parent 5ff7b19475
commit e9de677ceb
10 changed files with 96 additions and 75 deletions

View File

@@ -136,7 +136,7 @@ class Render extends SpriteView implements EngineListener {
} }
} }
public function onDestroy(entity:EntityType, ?playerId:PlayerId):Void { public function onDestroy(entity:EntityType):Void {
switch entity { switch entity {
case TANK(tank): case TANK(tank):
if (items.exists(tank.key)) { if (items.exists(tank.key)) {

View File

@@ -87,7 +87,8 @@ class SoundManager implements GameListener {
} }
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
switch event { // ToDo:
/*switch event {
case SPAWN_BULLET(player): case SPAWN_BULLET(player):
// ToDo: // ToDo:
if (Std.is(player.control, HumanControl)) { if (Std.is(player.control, HumanControl)) {
@@ -113,6 +114,6 @@ class SoundManager implements GameListener {
play('bonus_get'); play('bonus_get');
} }
case _: case _:
} }*/
} }
} }

View File

@@ -12,7 +12,7 @@ class BotControl extends Control {
private var tank(get, null):Tank; private var tank(get, null):Tank;
private inline function get_tank():Tank { private inline function get_tank():Tank {
return handler == null ? null : cast handler.entities[tankId]; return handler == null ? null : cast handler.engine.entities[tankId];
} }
override public function stop():Void { override public function stop():Void {

View File

@@ -1,16 +1,16 @@
package ru.m.tankz.bot; package ru.m.tankz.bot;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Entity; import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Eagle; import ru.m.tankz.game.IGame;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class BotHelper { class BotHelper {
public static function findEagle(team:TeamId, handler:ControlHandler):Null<Eagle> { public static function findEagle(team:TeamId, handler:IGame):Null<Eagle> {
for (entity in handler.entities) { for (entity in handler.engine.entities) {
switch (EntityTypeResolver.of(entity)) { switch (EntityTypeResolver.of(entity)) {
case EntityType.EAGLE(eagle): case EntityType.EAGLE(eagle):
if (eagle.team != team) { if (eagle.team != team) {

View File

@@ -1,7 +1,7 @@
package ru.m.tankz.bot; package ru.m.tankz.bot;
import ru.m.tankz.core.Eagle;
import haxe.Timer; import haxe.Timer;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
@@ -56,7 +56,7 @@ class HardBotControl extends BotControl {
} }
var enemy:Tank = null; var enemy:Tank = null;
var distance:Float = Math.POSITIVE_INFINITY; var distance:Float = Math.POSITIVE_INFINITY;
for (entity in handler.entities.iterator()) { for (entity in handler.engine.entities.iterator()) {
switch EntityTypeResolver.of(entity) { switch EntityTypeResolver.of(entity) {
case TANK(t): case TANK(t):
if (t.playerId.team != tank.playerId.team) { if (t.playerId.team != tank.playerId.team) {

View File

@@ -1,9 +1,8 @@
package ru.m.tankz.control; package ru.m.tankz.control;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.map.LevelMap; import ru.m.tankz.game.IGame;
import ru.m.tankz.Type; import ru.m.tankz.Type;
enum TankAction { enum TankAction {
@@ -16,13 +15,13 @@ class Control {
public var type:String; public var type:String;
public var playerId(default, null):PlayerId; public var playerId(default, null):PlayerId;
public var tankId(default, default):Int; public var tankId(default, default):Int;
private var handler:ControlHandler; private var handler:IGame;
public function new(playerId:PlayerId) { public function new(playerId:PlayerId) {
this.playerId = playerId; this.playerId = playerId;
} }
public function bind(handler:ControlHandler):Void { public function bind(handler:IGame):Void {
this.handler = handler; this.handler = handler;
} }
@@ -43,9 +42,3 @@ class Control {
handler = null; handler = null;
} }
} }
interface ControlHandler {
public var map(default, null):LevelMap;
public var entities(default, null):Map<Int, Entity>;
public function action(tankId:Int, action:TankAction):Void;
}

View File

@@ -3,7 +3,6 @@ package ru.m.tankz.engine;
import ru.m.geom.Line; import ru.m.geom.Line;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
import ru.m.tankz.core.Bullet; import ru.m.tankz.core.Bullet;
import ru.m.tankz.core.Entity; import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
@@ -11,15 +10,14 @@ import ru.m.tankz.core.MobileEntity;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
import ru.m.tankz.map.Grid; import ru.m.tankz.map.Grid;
import ru.m.tankz.map.LevelMap; import ru.m.tankz.map.LevelMap;
import ru.m.tankz.Type;
interface EngineListener { interface EngineListener {
public function onSpawn(entity:EntityType):Void; public function onSpawn(entity:EntityType):Void;
public function onCollision(entity:EntityType, with:EntityType):Void; public function onCollision(entity:EntityType, with:EntityType):Void;
public function onDestroy(entity:EntityType, ?playerId:PlayerId):Void; public function onDestroy(entity:EntityType):Void;
} }
@:yield @:dispatcher(EngineListener) class Engine implements ControlHandler { @:yield @:dispatcher(EngineListener) class Engine {
public var config(default, default):Config; public var config(default, default):Config;
public var map(default, null):LevelMap; public var map(default, null):LevelMap;
@@ -41,36 +39,14 @@ interface EngineListener {
spawnSignal.emit(type); spawnSignal.emit(type);
} }
public function destroy(entity:Entity, ?playerId:PlayerId):Void { public function destroy(entity:Entity):Void {
if (entities.exists(entity.id)) { if (entities.exists(entity.id)) {
var type = EntityTypeResolver.of(entity); var type = EntityTypeResolver.of(entity);
switch (type) { destroySignal.emit(type);
case BULLET(bullet):
var tank:Tank = cast entities.get(bullet.tankId);
if (tank != null) tank.onDestroyBullet();
case _:
}
destroySignal.emit(type, playerId);
entities.remove(entity.id); entities.remove(entity.id);
} }
} }
public function action(tankId:Int, action:TankAction):Void {
if (!entities.exists(tankId)) return;
var tank:Tank = cast entities.get(tankId);
switch (action) {
case MOVE(direction):
tank.move(direction);
case STOP:
tank.stop();
case SHOT:
var bullet = tank.shot();
if (bullet != null) {
spawn(bullet);
}
}
}
public function update():Void { public function update():Void {
var newTime:Float = Date.now().getTime(); var newTime:Float = Date.now().getTime();
var d:Float = newTime - time; var d:Float = newTime - time;

View File

@@ -25,7 +25,7 @@ interface GameListener {
public function onGameEvent(event:GameEvent):Void; public function onGameEvent(event:GameEvent):Void;
} }
@:dispatcher(GameListener) class Game implements EngineListener { @:dispatcher(GameListener) class Game implements IGame implements EngineListener {
private static var TAG(default, never):String = "Game"; private static var TAG(default, never):String = "Game";
@@ -49,6 +49,22 @@ interface GameListener {
engine.connect(this); engine.connect(this);
} }
public function action(tankId:Int, action:TankAction):Void {
if (!engine.entities.exists(tankId)) return;
var tank:Tank = cast engine.entities.get(tankId);
switch (action) {
case MOVE(direction):
tank.move(direction);
case STOP:
tank.stop();
case SHOT:
var bullet = tank.shot();
if (bullet != null) {
engine.spawn(bullet);
}
}
}
public function getTeam(teamId:TeamId):Team { public function getTeam(teamId:TeamId):Team {
return teams[teamId]; return teams[teamId];
} }
@@ -98,7 +114,7 @@ interface GameListener {
L.d(TAG, 'control(${player.id} - ${control})'); L.d(TAG, 'control(${player.id} - ${control})');
if (control != null) { if (control != null) {
player.control = control; player.control = control;
player.control.bind(engine); player.control.bind(this);
} }
} }
team.spawner.runner = spawn; team.spawner.runner = spawn;
@@ -175,7 +191,7 @@ interface GameListener {
getPlayer(tank.playerId).control.start(); getPlayer(tank.playerId).control.start();
case BULLET(bullet): case BULLET(bullet):
getPlayer(bullet.playerId).state.shots++; getPlayer(bullet.playerId).state.shots++;
gameEventSignal.emit(GameEvent.SPAWN_BULLET(getPlayer(bullet.playerId))); gameEventSignal.emit(GameEvent.SPAWN(BULLET(bullet)));
case _: case _:
} }
} }
@@ -197,11 +213,11 @@ interface GameListener {
engine.destroy(other_bullet); engine.destroy(other_bullet);
case [BULLET(bullet), CELL(cell)]: case [BULLET(bullet), CELL(cell)]:
engine.destroy(bullet); engine.destroy(bullet);
gameEventSignal.emit(GameEvent.HIT_CELL(getPlayer(bullet.playerId), cell)); gameEventSignal.emit(GameEvent.HIT(CELL(cell, bullet.tank, bullet)));
case [TANK(tank), BONUS(bonus)]: case [TANK(tank), BONUS(bonus)]:
applyBonus(tank, bonus); applyBonus(tank, bonus);
engine.destroy(bonus, tank.playerId); engine.destroy(bonus);
gameEventSignal.emit(GameEvent.TAKE_BONUS(getPlayer(tank.playerId), bonus.config)); gameEventSignal.emit(GameEvent.DESTROY(BONUS(bonus, tank, bonus.config.score)));
case [BULLET(bullet), TANK(tank)]/* | [TANK(tank), BULLET(bullet)]*/: case [BULLET(bullet), TANK(tank)]/* | [TANK(tank), BULLET(bullet)]*/:
if (bullet.tankId == tank.id || (!engine.config.game.friendlyFire && tank.playerId.team == bullet.playerId.team)) { if (bullet.tankId == tank.id || (!engine.config.game.friendlyFire && tank.playerId.team == bullet.playerId.team)) {
// Nothing // Nothing
@@ -213,13 +229,13 @@ interface GameListener {
tank.bonus = false; tank.bonus = false;
spawnBonus(); spawnBonus();
} }
gameEventSignal.emit(GameEvent.HIT_TANK(getPlayer(bullet.playerId), getPlayer(tank.playerId))); gameEventSignal.emit(GameEvent.HIT(TANK(tank, bullet.tank, bullet)));
} else if (tank.config.downgrade != null) { } else if (tank.config.downgrade != null) {
tank.config = engine.config.getTank(tank.config.downgrade); tank.config = engine.config.getTank(tank.config.downgrade);
gameEventSignal.emit(GameEvent.HIT_TANK(getPlayer(bullet.playerId), getPlayer(tank.playerId))); gameEventSignal.emit(GameEvent.HIT(TANK(tank, bullet.tank, bullet)));
} else { } else {
engine.destroy(tank, bullet.tank.playerId); engine.destroy(tank);
gameEventSignal.emit(GameEvent.DESTROY_TANK(getPlayer(bullet.playerId), getPlayer(tank.playerId))); gameEventSignal.emit(GameEvent.DESTROY(TANK(tank, bullet.tank, bullet, tank.config.score)));
} }
} }
engine.destroy(bullet); engine.destroy(bullet);
@@ -233,14 +249,17 @@ interface GameListener {
} }
checkComplete(); checkComplete();
gameChangeSignal.emit(state); gameChangeSignal.emit(state);
gameEventSignal.emit(GameEvent.DESTROY_EAGLE(getPlayer(bullet.tank.playerId), eagle.team)); gameEventSignal.emit(GameEvent.DESTROY(EAGLE(eagle, bullet.tank, bullet, eagle.config.score)));
} }
case _: case _:
} }
} }
public function onDestroy(entity:EntityType, ?playerId:PlayerId):Void { public function onDestroy(entity:EntityType):Void {
switch (entity) { switch (entity) {
case BULLET(bullet):
var tank:Tank = bullet.tank;
if (tank != null) tank.onDestroyBullet();
case TANK(tank): case TANK(tank):
var team = getTeam(tank.playerId.team); var team = getTeam(tank.playerId.team);
var player = getPlayer(tank.playerId); var player = getPlayer(tank.playerId);
@@ -257,10 +276,11 @@ interface GameListener {
if (tank.bonus) { if (tank.bonus) {
spawnBonus(); spawnBonus();
} }
if (playerId != null) { // ToDo:
/*if (playerId != null) {
getPlayer(playerId).state.frags++; getPlayer(playerId).state.frags++;
getPlayer(playerId).state.score += tank.config.score * (tank.playerId.team == playerId.team ? 0 : 1); getPlayer(playerId).state.score += tank.config.score * (tank.playerId.team == playerId.team ? 0 : 1);
} }*/
gameChangeSignal.emit(state); gameChangeSignal.emit(state);
case _: case _:
} }
@@ -272,7 +292,7 @@ interface GameListener {
} }
public function onAction(tankId:Int, action:TankAction):Void { public function onAction(tankId:Int, action:TankAction):Void {
engine.action(tankId, action); this.action(tankId, action);
} }
public function next():Option<GameState> { public function next():Option<GameState> {
@@ -300,7 +320,7 @@ interface GameListener {
bonus.rect.x = Math.round(Math.random() * engine.map.width / engine.map.cellWidth) * engine.map.cellWidth; bonus.rect.x = Math.round(Math.random() * engine.map.width / engine.map.cellWidth) * engine.map.cellWidth;
bonus.rect.y = Math.round(Math.random() * engine.map.height/ engine.map.cellHeight) * engine.map.cellHeight; bonus.rect.y = Math.round(Math.random() * engine.map.height/ engine.map.cellHeight) * engine.map.cellHeight;
engine.spawn(bonus); engine.spawn(bonus);
gameEventSignal.emit(GameEvent.SPAWN_BONUS(bonus.config)); gameEventSignal.emit(GameEvent.SPAWN(BONUS(bonus)));
} }
inline private function alienTank(team:TeamId):Tank->Bool { inline private function alienTank(team:TeamId):Tank->Bool {

View File

@@ -1,17 +1,39 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.core.Bonus;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Tank;
import ru.m.tankz.core.Bullet;
import ru.m.tankz.map.Grid; import ru.m.tankz.map.Grid;
import ru.m.tankz.config.Config;
import ru.m.tankz.Type; enum SpawnEvent {
EAGLE(eagle:Eagle);
TANK(tank:Tank);
BULLET(bullet:Bullet);
BONUS(bonus:Bonus);
}
enum HitEvent {
TANK(tank:Tank, who:Tank, wherewith:Bullet);
CELL(cell:GridCell, who:Tank, wherewith:Bullet);
}
enum DestroyEvent {
EAGLE(eagle:Eagle, who:Tank, wherewith:Bullet, score:Int);
TANK(tank:Tank, who:Tank, wherewith:Bullet, score:Int);
CELL(cell:GridCell, who:Tank, wherewith:Bullet);
BONUS(bonus:Bonus, who:Tank, score:Int);
}
enum ChangeEvent {
SCORE(player:Player, value:Int);
PLAYER_LIFE(player:Player, value:Int);
TEAM_LIFE(team:Team, value:Int);
}
enum GameEvent { enum GameEvent {
SPAWN_BULLET(player:Player); SPAWN(event:SpawnEvent);
HIT_TANK(player:Player, target:Player); HIT(event:HitEvent);
DESTROY_TANK(player:Player, target:Player); DESTROY(event:DestroyEvent);
DESTROY_EAGLE(player:Player, eagleTeamId:TeamId); CHANGE(event:ChangeEvent);
HIT_CELL(player:Player, cell:GridCell);
DESTROY_CELL(player:Player, cell:GridCell);
SPAWN_BONUS(bonus:BonusConfig);
TAKE_BONUS(player:Player, bonus:BonusConfig);
ADD_SCORE(player:Player, score:Int);
} }

View File

@@ -0,0 +1,9 @@
package ru.m.tankz.game;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.control.Control.TankAction;
interface IGame {
public var engine(default, null):Engine;
public function action(tankId:Int, action:TankAction):Void;
}