From b9e3eba1fd3009766c8792f18857f86b721c2782 Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 18 Jan 2018 15:58:18 +0300 Subject: [PATCH] [bot] added --- .../haxe/ru/m/tankz/core/PlayerControl.hx | 14 ++--- .../haxe/ru/m/tankz/view/frames/GameFrame.hx | 2 +- src/common/haxe/ru/m/tankz/bot/Bot.hx | 54 +++++++++++++++++++ src/common/haxe/ru/m/tankz/engine/Engine.hx | 40 +++++++++++--- 4 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 src/common/haxe/ru/m/tankz/bot/Bot.hx diff --git a/src/client/haxe/ru/m/tankz/core/PlayerControl.hx b/src/client/haxe/ru/m/tankz/core/PlayerControl.hx index cb5be6d..8630501 100644 --- a/src/client/haxe/ru/m/tankz/core/PlayerControl.hx +++ b/src/client/haxe/ru/m/tankz/core/PlayerControl.hx @@ -12,14 +12,14 @@ import flash.Lib; class PlayerControl { private var engine:Engine; - private var id:Int; + private var tankId:Int; private var keyBinding:Map; private var moveQueue:Array; private var shotTimer:Timer; - public function new(id:Int, engine:Engine, keyBinding:Map) { - this.id = id; + public function new(tankId:Int, engine:Engine, keyBinding:Map) { + this.tankId = tankId; this.engine = engine; this.keyBinding = keyBinding; moveQueue = new Array(); @@ -44,7 +44,7 @@ class PlayerControl { case _: } if (event.keyCode == Keyboard.U) { - engine.action(id, TankAction.LEVEL_UP(1)); + engine.action(tankId, TankAction.LEVEL_UP(1)); } } @@ -69,18 +69,18 @@ class PlayerControl { private function updateMove():Void { if (moveQueue.length == 0) { - engine.action(id, TankAction.STOP); + engine.action(tankId, TankAction.STOP); } else { switch (keyBinding.get(moveQueue[0])) { case TankAction.MOVE(direction): - engine.action(id, TankAction.MOVE(direction)); + engine.action(tankId, TankAction.MOVE(direction)); case _: } } } private function shot():Void { - engine.action(id, TankAction.SHOT); + engine.action(tankId, TankAction.SHOT); } public static function forPlayer(index:Int, tankId:Int, engine:Engine):PlayerControl { diff --git a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx index 943483d..b086fc6 100755 --- a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx @@ -38,7 +38,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand content.addEventListener(Event.ENTER_FRAME, redraw); for (index in 0...game.players.length) { var playerId:Int = game.players[index].id; - controls.set(playerId, PlayerControl.forPlayer(index, playerId, engine)); + controls.set(engine.playerTanks.get(playerId).id, PlayerControl.forPlayer(index, playerId, engine)); } Provider.get(IConnection).packetHandler.addListener(this); render.draw(engine); diff --git a/src/common/haxe/ru/m/tankz/bot/Bot.hx b/src/common/haxe/ru/m/tankz/bot/Bot.hx new file mode 100644 index 0000000..736e700 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bot/Bot.hx @@ -0,0 +1,54 @@ +package ru.m.tankz.bot; + +import ru.m.geom.Direction; +import haxe.Timer; +import ru.m.tankz.map.Grid.GridCell; +import ru.m.tankz.core.Tank; +import Type.ValueType; +import ru.m.tankz.core.Entity; +import ru.m.tankz.engine.Engine; + +class Bot implements EngineListener { + + public var tankId(default, null):Int; + private var engine:Engine; + + private var shotTimer:Timer; + + public function new(engine:Engine, tankId:Int) { + this.engine = engine; + this.tankId = tankId; + } + + public function onCollision(entity:Entity, with:Dynamic):Void { + if (entity.id == tankId) { + switch (Type.typeof(with)) { + case ValueType.TClass(Tank): turn(); + case ValueType.TClass(GridCell): turn(); + case _: + } + } + } + + public function start():Void { + engine.action(tankId, TankAction.MOVE(Direction.BOTTOM)); + shotTimer = new Timer(1000); + shotTimer.run = shot; + } + + public function shot():Void { + engine.action(tankId, TankAction.SHOT); + } + + public function turn():Void { + engine.action(tankId, TankAction.MOVE(Direction.TOP)); + } + + public function dispose():Void { + if (shotTimer != null) { + shotTimer.stop(); + shotTimer = null; + } + engine = null; + } +} diff --git a/src/common/haxe/ru/m/tankz/engine/Engine.hx b/src/common/haxe/ru/m/tankz/engine/Engine.hx index 35471e5..9c88737 100755 --- a/src/common/haxe/ru/m/tankz/engine/Engine.hx +++ b/src/common/haxe/ru/m/tankz/engine/Engine.hx @@ -1,8 +1,7 @@ package ru.m.tankz.engine; -import haxe.macro.Type.Ref; +import ru.m.tankz.bot.Bot; import haxe.Constraints.Function; -import ru.m.geom.Rectangle; import ru.m.geom.Line; import ru.m.tankz.core.MobileEntity; import ru.m.tankz.core.Entity; @@ -27,13 +26,20 @@ class Engine { public var entities(default, null):Map; public var removedEntities(default, null):Array; - private var playerTanks(default, null):Map; + public var playerTanks(default, null):Map; private var time:Float; - public function new() {} + public var listeners(default, null):Array; + + private var bots:Map; + + public function new() { + listeners = []; + } public function clear():Void { playerTanks = new Map(); + bots = new Map(); } private function buildTank(index:Int, config:TankConfig, point:SpawnPoint):Tank { @@ -47,6 +53,7 @@ class Engine { this.config = config; map = new LevelMap(config.map); playerTanks = new Map(); + bots = new Map(); entities = new Map(); removedEntities = new Array(); time = Date.now().getTime(); @@ -75,12 +82,16 @@ class Engine { var point:SpawnPoint = config.getSpawnPoint(EntityType.BOT, index); var tank = buildTank(0, config.getTank('bot', 0), point); entities.set(tank.id, tank); + var bot = new Bot(this, tank.id); + bots.set(tank.id, bot); + listeners.push(bot); + bot.start(); } return changes; } - public function action(playerId:Int, action:TankAction):Void { - var tank:Tank = playerTanks.get(playerId); + public function action(tankId:Int, action:TankAction):Void { + var tank:Tank = cast entities.get(tankId); switch (action) { case TankAction.MOVE(direction): tank.move(direction); @@ -176,6 +187,12 @@ class Engine { tank.onDestroyBullet(); } } + if (bots.exists(entity.id)) { + var bot:Bot = bots.get(entity.id); + bot.dispose(); + listeners.remove(bot); + bots.remove(entity.id); + } } public function update():Array { @@ -209,6 +226,7 @@ class Engine { if (cell.layer >= entity.layer && cell.layer < 3) { entity.rect.lean(cell.rect); collision = true; + for (listener in listeners) listener.onCollision(ent, cell); break; } } @@ -220,7 +238,11 @@ class Engine { var funName = 'collision${ent.type}${other.type}'; var fun:Function = Reflect.field(this, funName); if (fun != null) { - collision = Reflect.callMethod(this, fun, [ent, other]) || collision; + var c = Reflect.callMethod(this, fun, [ent, other]); + if (c) { + for (listener in listeners) listener.onCollision(ent, other); + } + collision = c || collision; } } } @@ -256,3 +278,7 @@ class Engine { return changes; } } + +interface EngineListener { + public function onCollision(entity:Entity, with:Dynamic):Void; +} \ No newline at end of file