From 0b17fbf804511bd4223941932dfd18803aa5b2e5 Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 21 Mar 2019 17:45:03 +0300 Subject: [PATCH] [common] add hard bot --- src/client/haxe/ru/m/tankz/Style.hx | 7 +- .../m/tankz/control/ClientControlFactory.hx | 26 ++-- .../haxe/ru/m/tankz/frame/ResultFrame.hx | 5 +- .../haxe/ru/m/tankz/frame/StartFrame.yaml | 2 +- .../tankz/frame/classic/ClassicGamePanel.yaml | 3 +- .../ru/m/tankz/frame/common/LevelFrame.hx | 4 +- .../ru/m/tankz/frame/common/PlayerView.hx | 24 ++-- .../ru/m/tankz/frame/dota/DotaGamePanel.yaml | 6 +- .../m/tankz/frame/settings/SettingsEditor.hx | 5 +- .../tankz/frame/settings/SettingsEditor.yaml | 1 + src/common/haxe/ru/m/tankz/Type.hx | 2 - src/common/haxe/ru/m/tankz/bot/BotControl.hx | 120 +++++------------- src/common/haxe/ru/m/tankz/bot/BotHelper.hx | 47 +++++++ .../haxe/ru/m/tankz/bot/HardBotControl.hx | 78 ++++++++++++ .../haxe/ru/m/tankz/bot/StupidBotControl.hx | 54 ++++++++ src/common/haxe/ru/m/tankz/config/Config.hx | 2 +- src/common/haxe/ru/m/tankz/control/Control.hx | 16 ++- .../ru/m/tankz/control/IControlFactory.hx | 3 +- .../ru/m/tankz/control/NoneControlFactory.hx | 3 +- src/common/haxe/ru/m/tankz/game/Game.hx | 10 +- src/common/haxe/ru/m/tankz/game/GameState.hx | 6 +- src/common/resources/classic/config.yaml | 2 +- .../ru/m/tankz/editor/level/MapEditView.hx | 11 +- 23 files changed, 288 insertions(+), 149 deletions(-) create mode 100644 src/common/haxe/ru/m/tankz/bot/BotHelper.hx create mode 100644 src/common/haxe/ru/m/tankz/bot/HardBotControl.hx create mode 100644 src/common/haxe/ru/m/tankz/bot/StupidBotControl.hx diff --git a/src/client/haxe/ru/m/tankz/Style.hx b/src/client/haxe/ru/m/tankz/Style.hx index 7e15200..2e4bc6d 100644 --- a/src/client/haxe/ru/m/tankz/Style.hx +++ b/src/client/haxe/ru/m/tankz/Style.hx @@ -30,7 +30,8 @@ class Style { Skin.text(textColor, 16, fontFamily), ]); resources.skin.put("text.header", [ - Skin.color(lightColor), + Skin.color(0x000000, 0.1), + Skin.border(lightColor, 1, 2), Skin.text(textColor, 22, fontFamily), Skin.size(200, 38), ]); @@ -40,11 +41,13 @@ class Style { Skin.size(250, 50) ]); resources.skin.put("text.box", [ - Skin.color(lightColor), + Skin.color(0x000000, 0.1), + Skin.border(lightColor, 1, 2), Skin.text(textColor, 16, fontFamily), ]); resources.skin.put("text.box.active", [ Skin.color(0x55aa55), + Skin.border(0x88dd88, 1, 2), Skin.text(textColor, 16, fontFamily), ]); resources.skin.put("button.simple", [ diff --git a/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx b/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx index 8011569..cb946d2 100644 --- a/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx +++ b/src/client/haxe/ru/m/tankz/control/ClientControlFactory.hx @@ -1,23 +1,21 @@ package ru.m.tankz.control; +import ru.m.tankz.bot.StupidBotControl; +import ru.m.tankz.bot.HardBotControl; +import ru.m.tankz.control.Control.Controller; import ru.m.tankz.Type; -import ru.m.tankz.bot.BotControl; - class ClientControlFactory implements IControlFactory { - private var humanControlIndex:Int; - - public function new() { - humanControlIndex = 0; - } - - public function build(id:PlayerId, type:ControlType):Control { - return switch (type) { - case Control.HUMAN: new HumanControl(id, humanControlIndex++); - case Control.BOT: new BotControl(id); - case Control.NONE: null; - case _: throw 'Unsupported control type: "${type}"'; + public function build(id:PlayerId, controller:Controller):Control { + return switch controller { + case HUMAN(index): new HumanControl(id, index); + case BOT(type): switch type { + case StupidBotControl.BOT_TYPE: new StupidBotControl(id); + case HardBotControl.BOT_TYPE: new HardBotControl(id); + case _: null; + } + case NONE: null; } } } diff --git a/src/client/haxe/ru/m/tankz/frame/ResultFrame.hx b/src/client/haxe/ru/m/tankz/frame/ResultFrame.hx index 2c2bd83..5a9a469 100644 --- a/src/client/haxe/ru/m/tankz/frame/ResultFrame.hx +++ b/src/client/haxe/ru/m/tankz/frame/ResultFrame.hx @@ -37,7 +37,10 @@ import ru.m.tankz.preset.DotaGame; } public function onShow() { - resultView.data = resultState.players.filter(function(player) return player.control == Control.HUMAN); + resultView.data = resultState.players.filter(function(player) return switch player.controller { + case HUMAN(_): true; + case _: false; + }); levelLabel.text = 'Level: ${resultState.level}'; nextButton.visible = state != null; } diff --git a/src/client/haxe/ru/m/tankz/frame/StartFrame.yaml b/src/client/haxe/ru/m/tankz/frame/StartFrame.yaml index 609cac7..354e1ec 100644 --- a/src/client/haxe/ru/m/tankz/frame/StartFrame.yaml +++ b/src/client/haxe/ru/m/tankz/frame/StartFrame.yaml @@ -2,7 +2,7 @@ views: - $type: haxework.gui.VGroupView skinId: container - layout.margin: 3 + layout.margin: 5 views: - $type: haxework.gui.ImageView image: $asset:image:resources/image/ui/logo.png diff --git a/src/client/haxe/ru/m/tankz/frame/classic/ClassicGamePanel.yaml b/src/client/haxe/ru/m/tankz/frame/classic/ClassicGamePanel.yaml index 5e6b213..fdd97cc 100644 --- a/src/client/haxe/ru/m/tankz/frame/classic/ClassicGamePanel.yaml +++ b/src/client/haxe/ru/m/tankz/frame/classic/ClassicGamePanel.yaml @@ -8,8 +8,7 @@ views: $type: haxework.gui.LabelView skinId: text.box geometry.size.height: 38 - geometry.padding: [20, 0] - geometry.hAlign: center + geometry.size.width: 100% - $type: haxework.gui.SpriteView geometry.size.height: 50% - id: bot diff --git a/src/client/haxe/ru/m/tankz/frame/common/LevelFrame.hx b/src/client/haxe/ru/m/tankz/frame/common/LevelFrame.hx index 044b18c..f35b1ce 100644 --- a/src/client/haxe/ru/m/tankz/frame/common/LevelFrame.hx +++ b/src/client/haxe/ru/m/tankz/frame/common/LevelFrame.hx @@ -5,6 +5,7 @@ import haxework.gui.GroupView; import haxework.resources.IResources; import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.config.Config; +import ru.m.tankz.control.Control.Controller; import ru.m.tankz.game.GameState; import ru.m.tankz.Type; @@ -35,7 +36,8 @@ class LevelFrame extends GroupView { for (team in value.teams) { for (player in team.players) { var playerId = new PlayerId(team.id, player.index); - state.players.push(new PlayerState(playerId, player.control, player.life)); + var controller = player.human ? HUMAN(player.index) : NONE; + state.players.push(new PlayerState(playerId, controller, player.life)); } } } diff --git a/src/client/haxe/ru/m/tankz/frame/common/PlayerView.hx b/src/client/haxe/ru/m/tankz/frame/common/PlayerView.hx index 1de351f..224c320 100644 --- a/src/client/haxe/ru/m/tankz/frame/common/PlayerView.hx +++ b/src/client/haxe/ru/m/tankz/frame/common/PlayerView.hx @@ -1,12 +1,12 @@ package ru.m.tankz.frame.common; import haxework.color.ColorUtil; -import ru.m.tankz.control.Control; import haxework.gui.DataView; import haxework.gui.HGroupView; import haxework.gui.LabelView; import haxework.gui.skin.ISkin; import haxework.gui.ToggleButtonView; +import ru.m.tankz.control.Control; import ru.m.tankz.game.GameState; import ru.m.tankz.Type.TeamId; @@ -42,7 +42,7 @@ class TeamSkin implements ISkin { } @:template class PlayerView extends HGroupView { - private static inline var NONE:TeamId = "none"; + private static inline var TEAM_NONE:TeamId = "none"; public var item_index(default, set):Int; public var data(default, set):Array; @@ -59,13 +59,13 @@ class TeamSkin implements ISkin { view.skin = [new TeamSkin(getTeamColor(team))]; view.geometry.padding = [10, 5]; view.team = team; - view.on = team == NONE; + view.on = team == TEAM_NONE; return view; } private function set_data(value:Array):Array { data = value; - teams.data = [NONE].concat([for (team in state.preset.teams) team.id]); + teams.data = [TEAM_NONE].concat([for (team in state.preset.teams) team.id]); return data; } @@ -88,16 +88,20 @@ class TeamSkin implements ISkin { private function onTeamSelect(team:TeamId) { if (player != null) { - player.control = Control.BOT; + player.controller = NONE; player.color = 0; player = null; } for (p in data) { - if (p.id.team == team && p.control != Control.HUMAN) { - player = p; - player.control = Control.HUMAN; - player.color = ColorUtil.multiply(state.config.getTeam(team).color, 1.7); - break; + if (p.id.team == team) { + switch (p.controller) { + case NONE: + player = p; + player.controller = HUMAN(item_index); + player.color = ColorUtil.multiply(state.config.getTeam(team).color, 1.7); + break; + case _: + } } } for (view in teams.views) { diff --git a/src/client/haxe/ru/m/tankz/frame/dota/DotaGamePanel.yaml b/src/client/haxe/ru/m/tankz/frame/dota/DotaGamePanel.yaml index 743949b..46c6ccc 100644 --- a/src/client/haxe/ru/m/tankz/frame/dota/DotaGamePanel.yaml +++ b/src/client/haxe/ru/m/tankz/frame/dota/DotaGamePanel.yaml @@ -7,14 +7,14 @@ views: tank: bc color: 0xff4422 - $type: haxework.gui.SpriteView - geometry.size.width: 50% + geometry.size.width: 25% - id: level $type: haxework.gui.LabelView skinId: text.box geometry.size.height: 38 - geometry.padding: [20, 0] - - $type: haxework.gui.SpriteView geometry.size.width: 50% + - $type: haxework.gui.SpriteView + geometry.size.width: 25% - id: dire $type: ru.m.tankz.frame.common.LifeView tank: bc diff --git a/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.hx b/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.hx index 80e9b7d..21715d2 100644 --- a/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.hx +++ b/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.hx @@ -44,11 +44,14 @@ import ru.m.tankz.storage.SettingsStorage; } } + private function onItemSelect(index:Int, value:ActionItem, view:ActionView):Void { + view.edit(); + } + private function _change():Void { var p: Promise = Promise.promise(0); for (view in list.views) { var v: ActionView = cast view; - if (v.data == null) break; p = p.pipe(function(_):Promise return v.edit()); } p.then(function(_) _save()); diff --git a/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.yaml b/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.yaml index fdd764f..357f508 100644 --- a/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.yaml +++ b/src/client/haxe/ru/m/tankz/frame/settings/SettingsEditor.yaml @@ -27,3 +27,4 @@ views: layout: $type: haxework.gui.layout.VerticalLayout factory: $this:viewFactory + +onItemSelect: $this:onItemSelect diff --git a/src/common/haxe/ru/m/tankz/Type.hx b/src/common/haxe/ru/m/tankz/Type.hx index 1f0a60d..eba4b60 100644 --- a/src/common/haxe/ru/m/tankz/Type.hx +++ b/src/common/haxe/ru/m/tankz/Type.hx @@ -6,8 +6,6 @@ typedef GameType = String; typedef TeamId = String; -typedef ControlType = String; - typedef BrickType = String; typedef TankType = String; diff --git a/src/common/haxe/ru/m/tankz/bot/BotControl.hx b/src/common/haxe/ru/m/tankz/bot/BotControl.hx index 7f9d864..8460eef 100644 --- a/src/common/haxe/ru/m/tankz/bot/BotControl.hx +++ b/src/common/haxe/ru/m/tankz/bot/BotControl.hx @@ -3,117 +3,55 @@ package ru.m.tankz.bot; import haxe.Timer; import ru.m.geom.Direction; import ru.m.tankz.control.Control; -import ru.m.tankz.core.Eagle; -import ru.m.tankz.core.Entity; -import ru.m.tankz.core.EntityType; import ru.m.tankz.core.Tank; -import ru.m.tankz.Type; - - -class BotHelper { - - public static function findEagle(team:TeamId, handler:ControlHandler):Null { - for (entity in handler.entities) { - switch (EntityTypeResolver.of(entity)) { - case EntityType.EAGLE(eagle): - if (eagle.team != team) { - return eagle; - } - case x: - } - } - return null; - } - - public static function getDirectionTo(entity:Entity, target:Entity):Direction { - var x:Float = target.rect.x - entity.rect.x; - var y:Float = target.rect.y - entity.rect.y; - var xD:Direction = Direction.from(Std.int(x / Math.abs(x)), 0); - var yD:Direction = Direction.from(0, Std.int(y / Math.abs(y))); - if (entity.rect.direction == xD) return yD; - if (entity.rect.direction == yD) return xD; - return Math.abs(x) > Math.abs(y) ? xD : yD; - } - - public static function randomDirection():Direction { - return [ - Direction.TOP, - Direction.BOTTOM, - Direction.LEFT, - Direction.RIGHT, - ][Math.floor(Math.random() * 4)]; - } -} class BotControl extends Control { - private var shotTimer:Timer; - private var turnRandomTimer:Timer; private var turnTimer:Timer; + private var tank(get, null):Tank; - public function new(playerId:PlayerId) { - super(playerId); - } - - override public function onCollision(with:EntityType):Void { - switch (with) { - case EntityType.TANK(_): turnAfter(300); - case EntityType.CELL(_): turnAfter(300); - case _: - } - } - - override public function start():Void { - if (handler == null) return; - action(TankAction.MOVE(tank.rect.direction)); - if (shotTimer == null) { - shotTimer = new Timer(1000); - shotTimer.run = shot; - } - if (turnRandomTimer == null) { - turnRandomTimer = new Timer(2000); - turnRandomTimer.run = turn; - } + private inline function get_tank():Tank { + return cast handler.entities[tankId]; } override public function stop():Void { + super.stop(); if (shotTimer != null) { shotTimer.stop(); shotTimer = null; } - if (turnRandomTimer != null) { - turnRandomTimer.stop(); - turnRandomTimer = null; - } - } - - public function shot():Void { - action(TankAction.SHOT); - } - - public function turnAfter(delay:Int):Void { - if (turnTimer == null) { - turnTimer = Timer.delay(turn, delay); - } - } - - public function turn():Void { if (turnTimer != null) { turnTimer.stop(); turnTimer = null; } - // ToDo: - if (handler == null || tank == null) return; - var eagle:Eagle = BotHelper.findEagle(playerId.team, handler); - if (eagle != null && Math.random() > 0.5) { - action(TankAction.MOVE(BotHelper.getDirectionTo(tank, eagle))); - } else { - action(TankAction.MOVE(BotHelper.randomDirection())); + } + + private function _shot():Void { + if (shotTimer != null) { + shotTimer.stop(); + shotTimer = null; + } + action(SHOT); + } + + public function shot(delay:Int = 100):Void { + if (shotTimer == null) { + shotTimer = Timer.delay(function() _shot(), delay); } } - private function get_tank():Tank { - return cast handler.entities[tankId]; + private function _turn(direction:Direction):Void { + if (turnTimer != null) { + turnTimer.stop(); + turnTimer = null; + } + action(MOVE(direction)); + } + + public function turn(direction:Direction, delay:Int = 300):Void { + if (turnTimer == null) { + turnTimer = Timer.delay(function() _turn(direction), delay); + } } } diff --git a/src/common/haxe/ru/m/tankz/bot/BotHelper.hx b/src/common/haxe/ru/m/tankz/bot/BotHelper.hx new file mode 100644 index 0000000..5b319db --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bot/BotHelper.hx @@ -0,0 +1,47 @@ +package ru.m.tankz.bot; + +import ru.m.geom.Direction; +import ru.m.tankz.core.Entity; +import ru.m.tankz.core.EntityType; +import ru.m.tankz.core.Eagle; +import ru.m.tankz.control.Control.ControlHandler; +import ru.m.tankz.Type; + +class BotHelper { + + public static function findEagle(team:TeamId, handler:ControlHandler):Null { + for (entity in handler.entities) { + switch (EntityTypeResolver.of(entity)) { + case EntityType.EAGLE(eagle): + if (eagle.team != team) { + return eagle; + } + case _: + } + } + return null; + } + + public static function getDirectionTo(entity:Entity, target:Entity):Direction { + var x:Float = target.rect.center.x - entity.rect.center.x; + var y:Float = target.rect.center.y - entity.rect.center.y; + var xD:Direction = Direction.from(Std.int(x / Math.abs(x)), 0); + var yD:Direction = Direction.from(0, Std.int(y / Math.abs(y))); + return Math.abs(x) > Math.abs(y) ? xD : yD; + } + + public static function randomDirection():Direction { + return [ + Direction.TOP, + Direction.BOTTOM, + Direction.LEFT, + Direction.RIGHT, + ][Math.floor(Math.random() * 4)]; + } + + public static function getDistance(entity:Entity, target:Entity):Float { + var x:Float = target.rect.center.x - entity.rect.center.x; + var y:Float = target.rect.center.y - entity.rect.center.y; + return Math.abs(x) + Math.abs(y); + } +} diff --git a/src/common/haxe/ru/m/tankz/bot/HardBotControl.hx b/src/common/haxe/ru/m/tankz/bot/HardBotControl.hx new file mode 100644 index 0000000..47a9d5f --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bot/HardBotControl.hx @@ -0,0 +1,78 @@ +package ru.m.tankz.bot; + +import haxe.Timer; +import ru.m.tankz.core.EntityType; +import ru.m.tankz.core.Tank; + +class HardBotControl extends BotControl { + public static inline var BOT_TYPE = "hard"; + + private var actionTimer:Timer; + + override public function onCollision(with:EntityType):Void { + switch (with) { + case TANK(t): + if (t.playerId.team != tank.playerId.team) { + shot(); + } + case CELL(cell): + if (cell.layer == 2 && cell.armor <= tank.config.bullet.piercing) { + shot(); + } + case EAGLE(eagle): + if (eagle.team != tank.playerId.team) { + shot(); + } + case _: + } + calcTurn(); + } + + override public function start():Void { + if (handler == null) return; + turn(tank.rect.direction); + if (actionTimer == null) { + actionTimer = new Timer(500); + actionTimer.run = nextAction; + } + } + + override public function stop():Void { + super.stop(); + if (actionTimer != null) { + actionTimer.stop(); + actionTimer = null; + } + } + + private function nextAction():Void { + var enemy:Tank = null; + var distance:Float = Math.POSITIVE_INFINITY; + for (entity in handler.entities.iterator()) { + switch EntityTypeResolver.of(entity) { + case TANK(t): + if (t.playerId.team != tank.playerId.team) { + var d = BotHelper.getDistance(tank, t); + if (d < distance && (Math.abs(t.rect.x - tank.rect.x) < tank.rect.width / 2 || Math.abs(t.rect.y - tank.rect.y) < tank.rect.height / 2)) { + enemy = t; + distance = d; + } + } + case _: + } + } + if (enemy != null) { + var d = BotHelper.getDirectionTo(tank, enemy); + if (d != tank.rect.direction) { + turn(BotHelper.getDirectionTo(tank, enemy), 1); + } + shot(); + } else if (Math.random() > 0.8) { + calcTurn(); + } + } + + private function calcTurn():Void { + turn(BotHelper.randomDirection()); + } +} diff --git a/src/common/haxe/ru/m/tankz/bot/StupidBotControl.hx b/src/common/haxe/ru/m/tankz/bot/StupidBotControl.hx new file mode 100644 index 0000000..1fc0744 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bot/StupidBotControl.hx @@ -0,0 +1,54 @@ +package ru.m.tankz.bot; + +import haxe.Timer; +import ru.m.tankz.control.Control; +import ru.m.tankz.core.Eagle; +import ru.m.tankz.core.EntityType; + +class StupidBotControl extends BotControl { + public static inline var BOT_TYPE = "stupid"; + + private var turnRandomTimer:Timer; + + override public function onCollision(with:EntityType):Void { + switch (with) { + case TANK(_): calcTurn(); + case CELL(_): calcTurn(); + case EAGLE(_): calcTurn(); + case _: + } + } + + override public function start():Void { + super.start(); + if (handler == null) return; + action(MOVE(tank.rect.direction)); + if (turnRandomTimer == null) { + turnRandomTimer = new Timer(2000); + turnRandomTimer.run = calcTurn; + } + } + + override public function stop():Void { + super.stop(); + if (turnRandomTimer != null) { + turnRandomTimer.stop(); + turnRandomTimer = null; + } + } + + private function calcTurn():Void { + if (turnTimer != null) { + turnTimer.stop(); + turnTimer = null; + } + // ToDo: + if (handler == null || tank == null) return; + var eagle:Eagle = BotHelper.findEagle(playerId.team, handler); + if (eagle != null && Math.random() > 0.5) { + turn(BotHelper.getDirectionTo(tank, eagle)); + } else { + turn(BotHelper.randomDirection()); + } + } +} diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 098e431..cb2dc78 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -75,7 +75,7 @@ typedef PlayerConfig = { @:optional var protect:Float; @:optional var life:Int; @:optional var color:Color; - @:optional var control:ControlType; + @:optional var human:Bool; } typedef EagleConfig = { diff --git a/src/common/haxe/ru/m/tankz/control/Control.hx b/src/common/haxe/ru/m/tankz/control/Control.hx index 1152e15..65ff842 100644 --- a/src/common/haxe/ru/m/tankz/control/Control.hx +++ b/src/common/haxe/ru/m/tankz/control/Control.hx @@ -3,6 +3,7 @@ package ru.m.tankz.control; import ru.m.geom.Direction; import ru.m.tankz.core.Entity; import ru.m.tankz.core.EntityType; +import ru.m.tankz.map.LevelMap; import ru.m.tankz.Type; enum TankAction { @@ -12,11 +13,13 @@ enum TankAction { SHOT; } -class Control { - public static var NONE(default, never):ControlType = 'none'; - public static var HUMAN(default, never):ControlType = 'human'; - public static var BOT(default, never):ControlType = 'bot'; +enum Controller { + NONE; + HUMAN(index:Int); + BOT(type:String); +} +class Control { public var playerId(default, null):PlayerId; public var tankId(default, default):Int; private var handler:ControlHandler; @@ -35,9 +38,7 @@ class Control { } } - public function onCollision(with:EntityType):Void { - - } + public function onCollision(with:EntityType):Void {} public function start():Void {} @@ -50,6 +51,7 @@ class Control { } interface ControlHandler { + public var map(default, null):LevelMap; public var entities(default, null):Map; public function action(tankId:Int, action:TankAction):Void; } diff --git a/src/common/haxe/ru/m/tankz/control/IControlFactory.hx b/src/common/haxe/ru/m/tankz/control/IControlFactory.hx index 7be2192..a2c94a6 100644 --- a/src/common/haxe/ru/m/tankz/control/IControlFactory.hx +++ b/src/common/haxe/ru/m/tankz/control/IControlFactory.hx @@ -1,8 +1,9 @@ package ru.m.tankz.control; +import ru.m.tankz.control.Control; import ru.m.tankz.Type; interface IControlFactory { - public function build(id:PlayerId, type:ControlType):Control; + public function build(id:PlayerId, controller:Controller):Control; } diff --git a/src/common/haxe/ru/m/tankz/control/NoneControlFactory.hx b/src/common/haxe/ru/m/tankz/control/NoneControlFactory.hx index 23c9657..7b95ca4 100644 --- a/src/common/haxe/ru/m/tankz/control/NoneControlFactory.hx +++ b/src/common/haxe/ru/m/tankz/control/NoneControlFactory.hx @@ -1,5 +1,6 @@ package ru.m.tankz.control; +import ru.m.tankz.control.Control; import ru.m.tankz.Type; @@ -7,7 +8,7 @@ class NoneControlFactory implements IControlFactory { public function new() {} - public function build(id:PlayerId, type:ControlType):Control { + public function build(id:PlayerId, controller:Controller):Control { return null; } } diff --git a/src/common/haxe/ru/m/tankz/game/Game.hx b/src/common/haxe/ru/m/tankz/game/Game.hx index c93ab90..a5a9e1c 100644 --- a/src/common/haxe/ru/m/tankz/game/Game.hx +++ b/src/common/haxe/ru/m/tankz/game/Game.hx @@ -109,14 +109,18 @@ class Game { var team:Team = new Team(teamConfig, teamPoints); teams[team.id] = team; for (player in team.players.iterator()) { - var controlType:ControlType = Control.BOT; + var controller:Controller = Controller.BOT("hard"); var nextPlayer:PlayerState = Lambda.find(players, function(p) return p.id == player.id); if (nextPlayer != null) { player.state = nextPlayer; players.remove(nextPlayer); - controlType = nextPlayer.control; + switch (nextPlayer.controller) { + case HUMAN(_): + controller = nextPlayer.controller; + case _: + } } - var control = controlFactory.build(player.id, controlType); + var control = controlFactory.build(player.id, controller); L.d(TAG, 'control(${player.id} - ${control})'); if (control != null) { player.control = control; diff --git a/src/common/haxe/ru/m/tankz/game/GameState.hx b/src/common/haxe/ru/m/tankz/game/GameState.hx index 5b30579..addd8d2 100644 --- a/src/common/haxe/ru/m/tankz/game/GameState.hx +++ b/src/common/haxe/ru/m/tankz/game/GameState.hx @@ -9,7 +9,7 @@ import ru.m.tankz.Type; class PlayerState { public var id:PlayerId; public var tank:TankType; - public var control:ControlType; + public var controller:Controller; public var color:Color; public var life:Int; public var score:Int; @@ -17,10 +17,10 @@ class PlayerState { public var shots:Int; public var hits:Int; - public function new(id:PlayerId, control:ControlType = null, life:Int = 0) { + public function new(id:PlayerId, controller:Controller = null, life:Int = 0) { this.id = id; this.tank = null; - this.control = control == null ? Control.BOT : control; + this.controller = controller == null ? Controller.NONE : controller; this.life = life; this.score = 0; this.frags = 0; diff --git a/src/common/resources/classic/config.yaml b/src/common/resources/classic/config.yaml index a8e337d..c2d301e 100644 --- a/src/common/resources/classic/config.yaml +++ b/src/common/resources/classic/config.yaml @@ -23,7 +23,7 @@ player: human: &human life: 3 protect: 5 - control: human + human: true tanks: - {type: human0, rate: 1} bot: &bot diff --git a/src/editor/haxe/ru/m/tankz/editor/level/MapEditView.hx b/src/editor/haxe/ru/m/tankz/editor/level/MapEditView.hx index c5da9fa..d9dcff2 100644 --- a/src/editor/haxe/ru/m/tankz/editor/level/MapEditView.hx +++ b/src/editor/haxe/ru/m/tankz/editor/level/MapEditView.hx @@ -1,5 +1,6 @@ package ru.m.tankz.editor.level; +import openfl.Assets; import flash.display.DisplayObjectContainer; import flash.display.Graphics; import flash.display.Sprite; @@ -25,8 +26,8 @@ class SpawnPointEntity extends Entity { class SpawnPointItem extends BitmapItem { - private var cellX:Int; - private var cellY:Int; + private var cellX:Int = -1; + private var cellY:Int = -1; private var src:String; public function new(value:SpawnPoint, config:Config) { @@ -62,11 +63,12 @@ class SpawnPointItem extends BitmapItem { override public function update():Void { super.update(); + var image = Assets.getBitmapData(getImage()); if (cellX != value.point.x || cellY != value.point.y) { cellX = value.point.x; cellY = value.point.y; - value.rect.x = cellX * (value.rect.width / 2); - value.rect.y = cellY * (value.rect.height / 2); + value.rect.x = cellX * (value.rect.width / 2) + (value.rect.width - image.width) / 2; + value.rect.y = cellY * (value.rect.height / 2) + (value.rect.height - image.height) / 2; redraw(); } } @@ -133,6 +135,7 @@ class MapEditView extends SpriteView { p.x = b.cellX; p.y = b.cellY; drawMap(); + drawMap(); break; } }