From de64e2813e2c854bcda8ddd1b6f67f0fbb1fb09f Mon Sep 17 00:00:00 2001 From: shmyga Date: Tue, 6 Aug 2019 16:19:38 +0300 Subject: [PATCH] [common] add ArmorEagleBonus --- .../haxe/ru/m/tankz/render/RenderUtil.hx | 26 ++++++++++ .../m/tankz/render/item/BitmapRenderItem.hx | 9 ++-- .../ru/m/tankz/render/item/BonusRenderItem.hx | 2 +- .../ru/m/tankz/render/item/BrickRenderItem.hx | 13 +++-- .../m/tankz/render/item/BulletRenderItem.hx | 3 +- .../ru/m/tankz/render/item/EagleRenderItem.hx | 9 ++-- .../ru/m/tankz/render/item/TankRenderItem.hx | 7 ++- .../haxe/ru/m/tankz/view/common/TankView.hx | 4 +- .../haxe/ru/m/tankz/view/result/FragView.hx | 11 +++-- .../haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx | 43 +++++++++++++++++ .../haxe/ru/m/tankz/bonus/BonusFactory.hx | 26 ++++++++++ .../haxe/ru/m/tankz/bonus/DestroyTeamBonus.hx | 2 + .../haxe/ru/m/tankz/bonus/FreezeTeamBonus.hx | 2 + src/common/haxe/ru/m/tankz/bonus/LifeBonus.hx | 2 + .../ru/m/tankz/bonus/ProtectEagleBonus.hx | 2 + .../haxe/ru/m/tankz/bonus/ProtectTankBonus.hx | 2 + .../haxe/ru/m/tankz/bonus/SuicideTankBonus.hx | 21 ++++++++ .../haxe/ru/m/tankz/bonus/UpgradeTankBonus.hx | 2 + src/common/haxe/ru/m/tankz/config/Config.hx | 1 + src/common/haxe/ru/m/tankz/engine/ITicker.hx | 3 +- src/common/haxe/ru/m/tankz/engine/Ticker.hx | 15 +++++- src/common/haxe/ru/m/tankz/game/GameRunner.hx | 48 +++++++------------ src/common/haxe/ru/m/tankz/game/GameState.hx | 1 + src/common/haxe/ru/m/tankz/game/GameUtil.hx | 8 ++-- src/common/haxe/ru/m/tankz/map/Brick.hx | 20 ++++++-- src/common/haxe/ru/m/tankz/map/LevelMap.hx | 7 +++ src/common/resources/config/classic.yaml | 14 +++--- src/common/resources/config/dota.yaml | 11 ++--- 28 files changed, 230 insertions(+), 84 deletions(-) create mode 100644 src/client/haxe/ru/m/tankz/render/RenderUtil.hx create mode 100644 src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx create mode 100644 src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx create mode 100644 src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx diff --git a/src/client/haxe/ru/m/tankz/render/RenderUtil.hx b/src/client/haxe/ru/m/tankz/render/RenderUtil.hx new file mode 100644 index 0000000..8966fbb --- /dev/null +++ b/src/client/haxe/ru/m/tankz/render/RenderUtil.hx @@ -0,0 +1,26 @@ +package ru.m.tankz.render; + +import flash.display.BitmapData; +import openfl.Assets; +import ru.m.tankz.Type; + +class RenderUtil { + + public static function eagleImage(death:Bool = false):BitmapData { + var suffix = death ? '-death' : ''; + return Assets.getBitmapData('resources/image/eagle/eagle${suffix}.png'); + } + + public static function tankImage(skin:String, frame:Int = 0):BitmapData { + return Assets.getBitmapData('resources/image/tank/${skin}-${frame}.png'); + } + + public static function bonusImage(type:BonusType):BitmapData { + return Assets.getBitmapData('resources/image/bonus/${type}.png'); + } + + public static function bulletImage(piercing:Int = 0):BitmapData { + var type = piercing > 0 ? 'piercing' : 'normal'; + return Assets.getBitmapData('resources/image/bullet/${type}.png'); + } +} diff --git a/src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx index ce990f8..fc69e40 100644 --- a/src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx @@ -4,13 +4,11 @@ import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.DisplayObject; import flash.display.PixelSnapping; -import openfl.Assets; import ru.m.geom.Rectangle; class BitmapRenderItem extends RenderItem { - public var image(default, set):String; + public var image(default, set):BitmapData; - private var bitmapData:BitmapData; private var bitmap:Bitmap; public function new(rect:Rectangle) { @@ -22,11 +20,10 @@ class BitmapRenderItem extends RenderItem { return bitmap; } - private function set_image(value:String):String { + private function set_image(value:BitmapData):BitmapData { if (image != value) { image = value; - bitmapData = Assets.getBitmapData(image); - bitmap.bitmapData = bitmapData; + bitmap.bitmapData = image; } return image; } diff --git a/src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx index c2def45..96581b4 100644 --- a/src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx @@ -18,7 +18,7 @@ class BonusRenderItem extends BitmapRenderItem { private function set_type(value:BonusType):BonusType { if (type != value) { type = value; - image = 'resources/image/bonus/${type}.png'; + image = RenderUtil.bonusImage(type); } return type; } diff --git a/src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx index 0dac5ce..df3d0e7 100644 --- a/src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx @@ -23,15 +23,19 @@ class BrickRenderItem extends RenderItem { private var shape:Shape; private var cells:Array; - public function new(rect:Rectangle, type:BrickType) { - super(rect); - this.shape = new Shape(); - cells = [ + private static function buildCells():Array { + return [ new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1), ]; + } + + public function new(rect:Rectangle, type:BrickType) { + super(rect); + this.shape = new Shape(); + cells = buildCells(); this.type = type; move(rect.position); } @@ -51,6 +55,7 @@ class BrickRenderItem extends RenderItem { private function set_type(value:BrickType):BrickType { if (type != value) { type = value; + cells = buildCells(); image = Assets.getBitmapData('resources/image/map/${type}.png'); redraw(); } diff --git a/src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx index de47df1..311b6ad 100644 --- a/src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx @@ -14,8 +14,7 @@ class BulletRenderItem extends BitmapRenderItem { private function set_piercing(value:Int):Int { if (piercing != value) { piercing = value; - var type = piercing > 0 ? 'piercing' : 'normal'; - image = 'resources/image/bullet/${type}.png'; + image = RenderUtil.bulletImage(piercing); } return piercing; } diff --git a/src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx index f15cd52..5e6cdf7 100644 --- a/src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx @@ -35,8 +35,8 @@ class EagleRenderItem extends BitmapRenderItem { if (protect != value) { protect = value; if (protect) { - protectView.x = (bitmapData.width - protectView.frames[0].image.width) / 2; - protectView.y = (bitmapData.height - protectView.frames[0].image.height) / 2; + protectView.x = (image.width - protectView.frames[0].image.width) / 2; + protectView.y = (image.height - protectView.frames[0].image.height) / 2; } protectView.visible = protect; protectView.playing = protect; @@ -47,10 +47,9 @@ class EagleRenderItem extends BitmapRenderItem { private function set_death(value:Bool):Bool { if (death != value) { death = value; - var suffix = death ? '-death' : ''; - image = 'resources/image/eagle/eagle${suffix}.png'; + image = RenderUtil.eagleImage(death); if (!color.zero) { - bitmap.bitmapData = bitmapData = BitmapUtil.colorize(bitmapData, color); + bitmap.bitmapData = image = BitmapUtil.colorize(image, color); } } return death; diff --git a/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx b/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx index c496c5f..8eb12b7 100644 --- a/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx @@ -1,6 +1,5 @@ package ru.m.tankz.render.item; -import haxework.view.theme.ITheme; import flash.display.BitmapData; import flash.display.DisplayObject; import flash.display.Sprite; @@ -9,8 +8,8 @@ import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import haxework.color.Color; import haxework.text.BitmapTextField; +import haxework.view.theme.ITheme; import haxework.view.utils.BitmapUtil; -import openfl.Assets; import ru.m.animate.Animate; import ru.m.geom.Rectangle; @@ -62,8 +61,8 @@ class TankRenderItem extends BitmapRenderItem { } private function redraw():Void { - var image1 = Assets.getBitmapData('resources/image/tank/${skin}-0.png'); - var image2 = Assets.getBitmapData('resources/image/tank/${skin}-1.png'); + var image1 = RenderUtil.tankImage(skin, 0); + var image2 = RenderUtil.tankImage(skin, 1); var color1:Color = switch hits { case 1: 0x869C43; case 2: 0xDEAF80; diff --git a/src/client/haxe/ru/m/tankz/view/common/TankView.hx b/src/client/haxe/ru/m/tankz/view/common/TankView.hx index 0b6075a..b9d3497 100644 --- a/src/client/haxe/ru/m/tankz/view/common/TankView.hx +++ b/src/client/haxe/ru/m/tankz/view/common/TankView.hx @@ -1,8 +1,8 @@ package ru.m.tankz.view.common; import haxework.view.ImageView; -import openfl.Assets; import ru.m.tankz.game.GameEvent; +import ru.m.tankz.render.RenderUtil; class TankView extends ImageView { @@ -16,7 +16,7 @@ class TankView extends ImageView { private function set_tank(value:TankInfo):TankInfo { if (value != null) { color = value.color; - image = Assets.getBitmapData('resources/image/tank/${value.skin}-0.png'); + image = RenderUtil.tankImage(value.skin); } return value; } diff --git a/src/client/haxe/ru/m/tankz/view/result/FragView.hx b/src/client/haxe/ru/m/tankz/view/result/FragView.hx index 8e36307..a7546ed 100644 --- a/src/client/haxe/ru/m/tankz/view/result/FragView.hx +++ b/src/client/haxe/ru/m/tankz/view/result/FragView.hx @@ -1,9 +1,9 @@ package ru.m.tankz.view.result; -import openfl.utils.Assets; import haxework.view.form.LabelView; import haxework.view.group.HGroupView; import ru.m.tankz.game.GameState; +import ru.m.tankz.render.RenderUtil; import ru.m.tankz.view.common.TankView; @:template class FragView extends HGroupView { @@ -16,15 +16,18 @@ import ru.m.tankz.view.common.TankView; private function set_data(value:Frag):Frag { data = value; + titleView.text = data.playerId.format(); + scoreView.text = data.score.format(); switch data.target { case TANK(tank): tankView.tank = tank; case EAGLE(color): - tankView.image = Assets.getBitmapData('resources/image/eagle/eagle.png'); + tankView.image = RenderUtil.eagleImage(); tankView.color = color; + case BONUS(type): + tankView.image = RenderUtil.bonusImage(type); + titleView.text = type; } - titleView.text = data.playerId.format(); - scoreView.text = data.score.format(); return data; } diff --git a/src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx b/src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx new file mode 100644 index 0000000..852ef01 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx @@ -0,0 +1,43 @@ +package ru.m.tankz.bonus; + +import ru.m.geom.Point; +import ru.m.tankz.core.Eagle; +import ru.m.tankz.engine.IEngine; +import ru.m.tankz.game.GameEvent; +import ru.m.tankz.game.IGame; +import ru.m.tankz.game.Team; +import ru.m.tankz.Type; + +using ru.m.tankz.game.GameUtil; + +class ArmorEagleBonus extends BaseBonus { + + public static inline var CLASS = "armor.eagle"; + + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { + var team:Team = game.getTeam(playerId.team); + if (team.eagleId > 0) { + var eagle:Eagle = cast(engine.entities[team.eagleId], Eagle); + var center = eagle.rect.center; + var cx:Int = Math.round(center.x / engine.map.cellWidth); + var cy:Int = Math.round(center.y / engine.map.cellHeight); + var bricks:Array = []; + for (x in cx - 2...cx + 2) { + for (y in cy - 2...cy + 2) { + var brick = engine.map.getBrick(new Point(x, y)); + if (brick != null && brick.config.type != "none") { + bricks.push(brick.id); + } + } + } + for (brickId in bricks) { + game.gameEventSignal.emit(CHANGE(BRICK(brickId, "armor"))); + } + game.ticker.emit(function() { + for (brickId in bricks) { + game.gameEventSignal.emit(CHANGE(BRICK(brickId, "brick"))); + } + }, Std.int(config.duration * 1000), '$CLASS.${eagle.id}'); + } + } +} diff --git a/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx b/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx new file mode 100644 index 0000000..063b2d6 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx @@ -0,0 +1,26 @@ +package ru.m.tankz.bonus; + +import ru.m.tankz.config.Config.BonusConfig; + +class BonusFactory { + + private var classes:Map>; + + public function new() { + classes = [ + DestroyTeamBonus.CLASS => DestroyTeamBonus, + FreezeTeamBonus.CLASS => FreezeTeamBonus, + LifeBonus.CLASS => LifeBonus, + ArmorEagleBonus.CLASS => ArmorEagleBonus, + ProtectEagleBonus.CLASS => ProtectEagleBonus, + ProtectTankBonus.CLASS => ProtectTankBonus, + UpgradeTankBonus.CLASS => UpgradeTankBonus, + SuicideTankBonus.CLASS => SuicideTankBonus, + ]; + } + + public function build(config:BonusConfig):IBonus { + var bonusClass = classes.exists(config.factory) ? classes[config.factory] : classes[SuicideTankBonus.CLASS]; + return Type.createInstance(bonusClass, [config]); + } +} diff --git a/src/common/haxe/ru/m/tankz/bonus/DestroyTeamBonus.hx b/src/common/haxe/ru/m/tankz/bonus/DestroyTeamBonus.hx index 6a3b7c6..4854479 100644 --- a/src/common/haxe/ru/m/tankz/bonus/DestroyTeamBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/DestroyTeamBonus.hx @@ -10,6 +10,8 @@ using ru.m.tankz.game.GameUtil; class DestroyTeamBonus extends BaseBonus { + public static inline var CLASS = "destroy.team"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId); if (tank != null) { diff --git a/src/common/haxe/ru/m/tankz/bonus/FreezeTeamBonus.hx b/src/common/haxe/ru/m/tankz/bonus/FreezeTeamBonus.hx index afecac0..a37388e 100644 --- a/src/common/haxe/ru/m/tankz/bonus/FreezeTeamBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/FreezeTeamBonus.hx @@ -8,6 +8,8 @@ using ru.m.tankz.game.GameUtil; class FreezeTeamBonus extends BaseBonus { + public static inline var CLASS = "freeze.team"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { for (team in game.teams) { if (team.id != playerId.team) { diff --git a/src/common/haxe/ru/m/tankz/bonus/LifeBonus.hx b/src/common/haxe/ru/m/tankz/bonus/LifeBonus.hx index 4b0d7e4..00ce2cb 100644 --- a/src/common/haxe/ru/m/tankz/bonus/LifeBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/LifeBonus.hx @@ -8,6 +8,8 @@ using ru.m.tankz.game.GameUtil; class LifeBonus extends BaseBonus { + public static inline var CLASS = "life"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { game.changeLife(playerId, 1); } diff --git a/src/common/haxe/ru/m/tankz/bonus/ProtectEagleBonus.hx b/src/common/haxe/ru/m/tankz/bonus/ProtectEagleBonus.hx index 07c7c43..8acf558 100644 --- a/src/common/haxe/ru/m/tankz/bonus/ProtectEagleBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/ProtectEagleBonus.hx @@ -10,6 +10,8 @@ using ru.m.tankz.game.GameUtil; class ProtectEagleBonus extends BaseBonus { + public static inline var CLASS = "protect.eagle"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { var team:Team = game.getTeam(playerId.team); if (team.eagleId > 0) { diff --git a/src/common/haxe/ru/m/tankz/bonus/ProtectTankBonus.hx b/src/common/haxe/ru/m/tankz/bonus/ProtectTankBonus.hx index b265735..41d9549 100644 --- a/src/common/haxe/ru/m/tankz/bonus/ProtectTankBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/ProtectTankBonus.hx @@ -9,6 +9,8 @@ using ru.m.tankz.game.GameUtil; class ProtectTankBonus extends BaseBonus { + public static inline var CLASS = "protect.tank"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId); if (tank != null) { diff --git a/src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx b/src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx new file mode 100644 index 0000000..f3d4d0e --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx @@ -0,0 +1,21 @@ +package ru.m.tankz.bonus; + +import ru.m.tankz.core.Tank; +import ru.m.tankz.engine.IEngine; +import ru.m.tankz.game.GameEvent; +import ru.m.tankz.game.IGame; +import ru.m.tankz.Type; + +using ru.m.tankz.game.GameUtil; + +class SuicideTankBonus extends BaseBonus { + + public static inline var CLASS = "suicide.tank"; + + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { + var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId); + if (tank != null) { + game.gameEventSignal.emit(DESTROY(TANK(tank.id, {tankId: tank.id}))); + } + } +} diff --git a/src/common/haxe/ru/m/tankz/bonus/UpgradeTankBonus.hx b/src/common/haxe/ru/m/tankz/bonus/UpgradeTankBonus.hx index f71a494..6094bc6 100644 --- a/src/common/haxe/ru/m/tankz/bonus/UpgradeTankBonus.hx +++ b/src/common/haxe/ru/m/tankz/bonus/UpgradeTankBonus.hx @@ -9,6 +9,8 @@ using ru.m.tankz.game.GameUtil; class UpgradeTankBonus extends BaseBonus { + public static inline var CLASS = "upgrade.tank"; + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId); if (tank != null) { diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 6f75d6d..e670dbb 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -63,6 +63,7 @@ typedef TankConfig = { typedef BonusConfig = { var type:BonusType; + var factory:String; @:optional var duration:Null; @:optional var value:Null; @:optinal var score:Null; diff --git a/src/common/haxe/ru/m/tankz/engine/ITicker.hx b/src/common/haxe/ru/m/tankz/engine/ITicker.hx index 2dcaf2c..d62927d 100644 --- a/src/common/haxe/ru/m/tankz/engine/ITicker.hx +++ b/src/common/haxe/ru/m/tankz/engine/ITicker.hx @@ -7,5 +7,6 @@ interface ITicker { public function start():Void; public function stop():Void; public function tick():Int; - public function emit(f:Void->Void, delay:Int):Void; + public function emit(f:Void->Void, delay:Int, ?key:String):Void; + public function cancel(key:String):Void; } diff --git a/src/common/haxe/ru/m/tankz/engine/Ticker.hx b/src/common/haxe/ru/m/tankz/engine/Ticker.hx index aaf60f4..1a25aea 100644 --- a/src/common/haxe/ru/m/tankz/engine/Ticker.hx +++ b/src/common/haxe/ru/m/tankz/engine/Ticker.hx @@ -13,6 +13,7 @@ class Ticker implements ITicker { private var passed:Int; private var last_tick:Int; private var actions:Array; + private var actionsByKey:Map; private var actionId = 0; private static var TIME = Timer.stamp(); @@ -26,6 +27,7 @@ class Ticker implements ITicker { last_tick = 0; running = false; actions = []; + actionsByKey = new Map(); } private function get_time():Int { @@ -73,10 +75,21 @@ class Ticker implements ITicker { } } - public function emit(fun:Void->Void, delay:Int):Void { + public function emit(fun:Void->Void, delay:Int, ?key:String):Void { var action:Action = {action:fun, time:time+delay, id:++actionId}; //L.d("Ticker", 'emit: ${action.id} ${action.time}'); + if (key != null) { + cancel(key); + actionsByKey[key] = action; + } actions.push(action); actions.sort(function(a, b) return a.time - b.time); } + + public function cancel(key:String):Void { + if (actionsByKey.exists(key)) { + actions.remove(actionsByKey[key]); + actionsByKey.remove(key); + } + } } diff --git a/src/common/haxe/ru/m/tankz/game/GameRunner.hx b/src/common/haxe/ru/m/tankz/game/GameRunner.hx index 6a5f037..d800060 100644 --- a/src/common/haxe/ru/m/tankz/game/GameRunner.hx +++ b/src/common/haxe/ru/m/tankz/game/GameRunner.hx @@ -2,13 +2,7 @@ package ru.m.tankz.game; import ru.m.geom.Line; import ru.m.geom.Point; -import ru.m.tankz.bonus.DestroyTeamBonus; -import ru.m.tankz.bonus.FreezeTeamBonus; -import ru.m.tankz.bonus.IBonus; -import ru.m.tankz.bonus.LifeBonus; -import ru.m.tankz.bonus.ProtectEagleBonus; -import ru.m.tankz.bonus.ProtectTankBonus; -import ru.m.tankz.bonus.UpgradeTankBonus; +import ru.m.tankz.bonus.BonusFactory; import ru.m.tankz.control.Control; import ru.m.tankz.core.Bonus; import ru.m.tankz.core.Bullet; @@ -18,7 +12,7 @@ import ru.m.tankz.core.Tank; import ru.m.tankz.engine.Engine; import ru.m.tankz.engine.IEngine; import ru.m.tankz.game.GameEvent; -import ru.m.tankz.game.GameState.FragTarget; +import ru.m.tankz.game.GameState; import ru.m.tankz.game.Spawner; import ru.m.tankz.Type; import ru.m.Timer; @@ -28,34 +22,19 @@ using ru.m.tankz.game.GameUtil; class GameRunner extends Game implements EngineListener { private var timer:Timer; private var builder:EntityBuilder; - private var bonuses:Map; + private var bonuses:BonusFactory; public function new(start:Start) { super(start.state.type); this.level = start.level; this.state = start.state; builder = new EntityBuilder(config); - bonuses = new Map(); - for (bonus in buildBonuses()) { - bonuses[bonus.type] = bonus; - } + bonuses = new BonusFactory(); engine = new Engine(config, level.size); ticker = engine.ticker; engine.connect(this); } - private function buildBonuses():Array { - return [ - new ProtectEagleBonus(config.getBonus("shovel")), - new ProtectTankBonus(config.getBonus("helmet")), - new LifeBonus(config.getBonus("life")), - new UpgradeTankBonus(config.getBonus("star")), - new UpgradeTankBonus(config.getBonus("gun")), - new DestroyTeamBonus(config.getBonus("grenade")), - new FreezeTeamBonus(config.getBonus("clock")), - ]; - } - override function changePause(value:Bool):Void { if (engine != null) { if (value) { @@ -254,11 +233,8 @@ class GameRunner extends Game implements EngineListener { } private function applyBonus(tank:Tank, bonus:Bonus):Void { - if (bonuses.exists(bonus.config.type)) { - bonuses[bonus.config.type].apply(tank.playerId, this, engine); - } else { - gameEventSignal.emit(DESTROY(TANK(tank.id, {tankId: tank.id}))); // :-D - } + var bonus = bonuses.build(bonus.config); + bonus.apply(tank.playerId, this, engine); } override public function onGameEvent(event:GameEvent):Void { @@ -306,6 +282,8 @@ class GameRunner extends Game implements EngineListener { player.state.tank = info; case SPAWN(BULLET(_, _, playerId, _)): getPlayer(playerId).bullets++; + case CHANGE(BRICK(id, type)): + engine.map.bricksById[id].config = config.getBrick(type); case DESTROY(EAGLE(id, shot)): var eagle:Eagle = engine.getEntity(id); eagle.death = true; @@ -355,6 +333,12 @@ class GameRunner extends Game implements EngineListener { var bonus:Bonus = engine.getEntity(id); var tank:Tank = engine.getEntity(shot.tankId); applyBonus(tank, bonus); + var shooter = getPlayer(tank.playerId); + shooter.state.frags.push({ + playerId: shooter.id, + target: BONUS(bonus.config.type), + score: shot.score, + }); if (shot.score != null) { changeScore(tank.playerId, shot.score); } @@ -373,10 +357,10 @@ class GameRunner extends Game implements EngineListener { var shot = buildShot(bullet); if (cell.armor == bullet.config.piercing) { engine.destroyCell(cell.cellX, cell.cellY); - var brick = engine.map.getBrick(cell.position); + var brick = engine.map.getCellBrick(cell.position); gameEventSignal.emit(DESTROY(CELL(brick.id, cell.cellX - brick.cellX * 2, cell.cellY - brick.cellY * 2, shot))); } else if (cell.armor < bullet.config.piercing) { - var brick = engine.map.getBrick(cell.position); + var brick = engine.map.getCellBrick(cell.position); for (cell in brick.cells) { engine.destroyCell(cell.cellX, cell.cellY); } diff --git a/src/common/haxe/ru/m/tankz/game/GameState.hx b/src/common/haxe/ru/m/tankz/game/GameState.hx index 167106b..273f671 100644 --- a/src/common/haxe/ru/m/tankz/game/GameState.hx +++ b/src/common/haxe/ru/m/tankz/game/GameState.hx @@ -11,6 +11,7 @@ import ru.m.tankz.Type; enum FragTarget { TANK(tank:TankInfo); EAGLE(color:Color); + BONUS(type:BonusType); } typedef Frag = { diff --git a/src/common/haxe/ru/m/tankz/game/GameUtil.hx b/src/common/haxe/ru/m/tankz/game/GameUtil.hx index 4ceca65..9d3501b 100644 --- a/src/common/haxe/ru/m/tankz/game/GameUtil.hx +++ b/src/common/haxe/ru/m/tankz/game/GameUtil.hx @@ -33,7 +33,7 @@ class GameUtil { game.ticker.emit(function() { tank.protect = false; game.gameEventSignal.emit(CHANGE(TANK_PROTECT(tank.id, tank.protect))); - }, Std.int(duration * 1000)); + }, Std.int(duration * 1000), 'protect.tank.${tank.id}'); } public static function protectEagle(game:IGame, eagle:Eagle, duration:Float):Void { @@ -42,7 +42,7 @@ class GameUtil { game.ticker.emit(function() { eagle.protect = false; game.gameEventSignal.emit(CHANGE(EAGLE_PROTECT(eagle.id, eagle.protect))); - }, Std.int(duration * 1000)); + }, Std.int(duration * 1000), 'protect.eagle.${eagle.id}'); } public static function freezeTank(game:IGame, tank:Tank, duration:Float):Void { @@ -53,7 +53,7 @@ class GameUtil { game.ticker.emit(function() { tank.freezing = false; game.gameEventSignal.emit(CHANGE(TANK_FREEZE(tank.id, tank.freezing))); - }, Std.int(duration * 1000)); + }, Std.int(duration * 1000), 'freeze.tank.${tank.id}'); } public static function freezeTeam(game:IGame, engine:IEngine, teamId:TeamId, duration:Float):Void { @@ -70,7 +70,7 @@ class GameUtil { tank.freezing = false; game.gameEventSignal.emit(CHANGE(TANK_FREEZE(tank.id, tank.freezing))); } - }, Std.int(duration * 1000)); + }, Std.int(duration * 1000), 'freeze.team.${teamId}'); } public static function changeLife(game:IGame, playerId:PlayerId, life:Int):Void { diff --git a/src/common/haxe/ru/m/tankz/map/Brick.hx b/src/common/haxe/ru/m/tankz/map/Brick.hx index 1eaad21..1b878a2 100644 --- a/src/common/haxe/ru/m/tankz/map/Brick.hx +++ b/src/common/haxe/ru/m/tankz/map/Brick.hx @@ -13,7 +13,7 @@ class Brick { public var cellY(default, null):Int; public var mapConfig(default, null):MapConfig; - public var config(default, default):BrickConfig; + public var config(default, set):BrickConfig; public var rect(default, null):Rectangle; public var cells(default, null):HashMap; @@ -34,7 +34,17 @@ class Brick { ); } - public function get_broken():Int { + private function set_config(value:BrickConfig):BrickConfig { + config = value; + for (cell in cells) { + cell.layer = config.layer; + cell.armor = config.armor; + cell.destroyed = false; + } + return config; + } + + private function get_broken():Int { var i:Int = 0; for (c in cells.iterator()) { if (c.destroyed) { @@ -44,7 +54,7 @@ class Brick { return i; } - public function get_destroyed():Bool { + private function get_destroyed():Bool { var i = 0; var result:Bool = false; for (c in cells.iterator()) { @@ -57,7 +67,7 @@ class Brick { return result; } - public function set_destroyed(value:Bool):Bool { + private function set_destroyed(value:Bool):Bool { if (value) { for (c in cells.iterator()) { c.destroyed = true; @@ -66,7 +76,7 @@ class Brick { return value; } - public function get_id():Int { + private function get_id():Int { return -((cellX * 1000) + cellY); } diff --git a/src/common/haxe/ru/m/tankz/map/LevelMap.hx b/src/common/haxe/ru/m/tankz/map/LevelMap.hx index cd03a05..68a6a66 100755 --- a/src/common/haxe/ru/m/tankz/map/LevelMap.hx +++ b/src/common/haxe/ru/m/tankz/map/LevelMap.hx @@ -18,6 +18,7 @@ class LevelMap { public var height(get, null):Float; public var bricks(default, null):Array; + public var bricksById(default, null):Map; public var grid(default, null):Grid; @@ -31,6 +32,7 @@ class LevelMap { gridHeight = size != null ? size.height : config.grid.height; bricksMap = new HashMap(); bricks = []; + bricksById = new Map(); grid = new Grid( Std.int(cellWidth / 2), Std.int(cellHeight / 2), @@ -57,11 +59,16 @@ class LevelMap { for (cell in brick.cells.iterator()) { bricksMap.set(cell.position, brick); } + bricksById.set(brick.id, brick); return brick; })); } public function getBrick(position:Point):Brick { + return bricks[Std.int(position.x + position.y * gridWidth)]; + } + + public function getCellBrick(position:Point):Brick { return bricksMap.get(position); } diff --git a/src/common/resources/config/classic.yaml b/src/common/resources/config/classic.yaml index 4f1bf6d..ce28b78 100644 --- a/src/common/resources/config/classic.yaml +++ b/src/common/resources/config/classic.yaml @@ -147,13 +147,13 @@ tanks: skin: bd bonuses: - - {score: 500, type: clock, duration: 10} - - {score: 500, type: grenade} - - {score: 500, type: helmet, duration: 20} - - {score: 500, type: life} - - {score: 500, type: shovel, duration: 10} - - {score: 500, type: star, value: 1} - - {score: 500, type: gun, value: 5} + - {score: 500, factory: freeze.team, type: clock, duration: 10} + - {score: 500, factory: destroy.team, type: grenade} + - {score: 500, factory: protect.tank, type: helmet, duration: 15} + - {score: 500, factory: life, type: life} + - {score: 500, factory: armor.eagle, type: shovel, duration: 10} + - {score: 500, factory: upgrade.tank, type: star, value: 1} + - {score: 500, factory: upgrade.tank, type: gun, value: 5} presets: - id: 0 diff --git a/src/common/resources/config/dota.yaml b/src/common/resources/config/dota.yaml index b2e3da2..fd6bfb6 100644 --- a/src/common/resources/config/dota.yaml +++ b/src/common/resources/config/dota.yaml @@ -107,9 +107,8 @@ tanks: skin: bb bonuses: - - {type: clock, duration: 10} - - {type: grenade} - - {type: helmet, duration: 20} - - {type: life} - - {type: shovel, duration: 10} - - {type: star} + - {score: 100, factory: freeze.team, type: clock, duration: 10} + - {score: 100, factory: destroy.team, type: grenade} + - {score: 100, factory: protect.tank, type: helmet, duration: 15} + - {score: 100, factory: life, type: life} + - {score: 100, factory: protect.eagle, type: shovel, duration: 10}