diff --git a/WORK.md b/WORK.md index 0384e46..4a7cc72 100644 --- a/WORK.md +++ b/WORK.md @@ -1,12 +1,10 @@ * bonuses * death game bonuses - * boat bonus * tanks and bullets speed balancing * game series * network series * map packs - * create in editor - * import in game + * import in game * save imported in local storage * database * cache diff --git a/src/client/haxe/ru/m/tankz/AppTheme.hx b/src/client/haxe/ru/m/tankz/AppTheme.hx index 1426ee6..c8e0236 100644 --- a/src/client/haxe/ru/m/tankz/AppTheme.hx +++ b/src/client/haxe/ru/m/tankz/AppTheme.hx @@ -146,7 +146,8 @@ class AppTheme extends Theme { registerButton("tablet-android-alt", "tablet-android-alt-light.svg", true); register(new Style("gamepad", [ - "skin.color" => colors.active, + "skin.color" => colors.text, + "skin.activeColor" => colors.active, ])); } diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index 6c361e5..730104f 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -144,6 +144,7 @@ class Render extends SpriteView implements IRender { item.skin = tankConfig.skin; item.hits = info.hits; item.bonus = info.bonus; + item.boat = info.boat; item.name = info.name == null ? "" : info.name; items.set(id, item); entryLayer.addChild(item.view); @@ -180,12 +181,13 @@ class Render extends SpriteView implements IRender { var item = items[id]; cast(item, TankRenderItem).moves = false; } - case CHANGE(TANK(id, type, hits, bonus)): + case CHANGE(TANK(id, type, hits, bonus, boat)): if (items.exists(id)) { var item:TankRenderItem = cast items[id]; item.skin = config.getTank(type).skin; item.hits = hits; item.bonus = bonus; + item.boat = boat; } case CHANGE(TANK_PROTECT(id, state)): if (items.exists(id)) { 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 8eb12b7..1e25b85 100644 --- a/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx @@ -2,6 +2,7 @@ package ru.m.tankz.render.item; import flash.display.BitmapData; import flash.display.DisplayObject; +import flash.display.Shape; import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldAutoSize; @@ -18,6 +19,7 @@ class TankRenderItem extends BitmapRenderItem { public var skin(default, set):String; public var hits(default, set):Int; public var bonus(default, set):Bool; + public var boat(default, set):Bool; public var moves(default, set):Bool; public var protect(default, set):Bool; public var name(default, set):String; @@ -26,6 +28,7 @@ class TankRenderItem extends BitmapRenderItem { private var images:Array; private var frame:Int; private var protectView:Animate; + private var boatView:Shape; private var nameView:TextField; @:provide static var theme:ITheme; @@ -39,6 +42,9 @@ class TankRenderItem extends BitmapRenderItem { container.addChild(protectView); nameView = buildNameView(); container.addChild(nameView); + boatView = buildBoatView(); + boatView.visible = false; + container.addChild(boatView); move(rect.position); } @@ -52,6 +58,13 @@ class TankRenderItem extends BitmapRenderItem { return result; } + private function buildBoatView():Shape { + var result = new Shape(); + result.graphics.lineStyle(4, Color.fromString("green")); + result.graphics.drawRoundRect(0, 0, rect.width, rect.height, 10, 10); + return result; + } + override private function get_view():DisplayObject { return container; } @@ -108,6 +121,14 @@ class TankRenderItem extends BitmapRenderItem { return bonus; } + private function set_boat(value:Bool):Bool { + if (boat != value) { + boat = value; + boatView.visible = boat; + } + return boat; + } + private function set_protect(value:Bool):Bool { if (protect != value) { protect = value; diff --git a/src/client/haxe/ru/m/tankz/view/game/GameViewHelper.hx b/src/client/haxe/ru/m/tankz/view/game/GameViewHelper.hx index 503d2a1..082845c 100644 --- a/src/client/haxe/ru/m/tankz/view/game/GameViewHelper.hx +++ b/src/client/haxe/ru/m/tankz/view/game/GameViewHelper.hx @@ -53,6 +53,7 @@ class GameViewHelper { skin: tank.skin, hits: 0, bonus: false, + boat: false, color: config.getColor(playerView.playerId), }; } diff --git a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx index 4b308d5..b5b0e79 100644 --- a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx +++ b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx @@ -6,21 +6,24 @@ import haxework.view.skin.ISkin; @:style class GamepadSkin implements ISkin { - @:style(0x00ff00) public var color(default, default):Null; + @:style(0xffffff) public var color(default, default):Null; + @:style(0x00ff00) public var activeColor(default, default):Null; public function new(?color:Color) { this.color = color; } public function draw(view:GamepadView):Void { + var actives = [for (item in view.activeAreas.iterator()) item]; var graphics:Graphics = view.content.graphics; graphics.clear(); graphics.beginFill(0, 0.0); graphics.drawRect(0, 0, view.width, view.height); graphics.endFill(); - graphics.lineStyle(2, color); - graphics.beginFill(color, 0.2); for (area in view.areas) { + var color = actives.indexOf(area) > -1 ? activeColor : color; + graphics.lineStyle(2, color); + graphics.beginFill(color, 0.2); area.draw(graphics); } graphics.lineStyle(); diff --git a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx index 9fe5122..132bb3e 100644 --- a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx +++ b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx @@ -16,7 +16,7 @@ class GamepadView extends SpriteView implements IControlDevice { public var signal(default, null):Signal2; public var areas(default, null):Array; - public var currentAreas(default, null):Map; + public var activeAreas(default, null):Map; private var builder:IActionAreaBuilder; private var stage:Stage; @@ -28,7 +28,7 @@ class GamepadView extends SpriteView implements IControlDevice { builder = new SmartActionAreaBuilder(); signal = new Signal2(); areas = []; - currentAreas = new Map(); + activeAreas = new Map(); skin = new GamepadSkin(); content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); content.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); @@ -66,33 +66,37 @@ class GamepadView extends SpriteView implements IControlDevice { private function onTouchEnd(event:TouchEvent):Void { endTouch(event.touchPointID); - if (Lambda.count(currentAreas) == 0) { + if (Lambda.count(activeAreas) == 0) { stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd); } } private function updateTouch(pointID:Int, point:Point):Void { - if (currentAreas.exists(pointID)) { - var area = currentAreas[pointID]; + if (activeAreas.exists(pointID)) { + var area = activeAreas[pointID]; if (!area.contain(point)) { - currentAreas.remove(pointID); + activeAreas.remove(pointID); signal.emit(area.action, false); + toRedraw(); } - } - for (area in areas) { - if (area.contain(point)) { - currentAreas[pointID] = area; - signal.emit(area.action, true); - break; + } else { + for (area in areas) { + if (area.contain(point)) { + activeAreas[pointID] = area; + signal.emit(area.action, true); + toRedraw(); + break; + } } } } private function endTouch(pointID:Int):Void { - if (currentAreas.exists(pointID)) { - signal.emit(currentAreas[pointID].action, false); - currentAreas.remove(pointID); + if (activeAreas.exists(pointID)) { + signal.emit(activeAreas[pointID].action, false); + activeAreas.remove(pointID); + toRedraw(); } } diff --git a/src/client/haxe/ru/m/tankz/view/result/ResultPlayerView.hx b/src/client/haxe/ru/m/tankz/view/result/ResultPlayerView.hx index 037ec72..37f2501 100644 --- a/src/client/haxe/ru/m/tankz/view/result/ResultPlayerView.hx +++ b/src/client/haxe/ru/m/tankz/view/result/ResultPlayerView.hx @@ -24,7 +24,9 @@ import ru.m.tankz.view.common.TankView; var additionalScore = Lambda.fold(data.frags, function(frag:Frag, score:Int) return score + frag.score, 0); scoreView.text = '${data.score}$ (+${additionalScore}$)'; tankView.color = value.color; - fragsView.data = data.frags; + var frags = data.frags.slice(0); + frags.reverse(); + fragsView.data = frags; tankView.tank = value.tank; return data; } diff --git a/src/client/resources/image/bonus/boat.png b/src/client/resources/image/bonus/boat.png new file mode 100644 index 0000000..3474d22 Binary files /dev/null and b/src/client/resources/image/bonus/boat.png differ diff --git a/src/common/haxe/ru/m/tankz/Type.hx b/src/common/haxe/ru/m/tankz/Type.hx index 5da2b6d..97e443d 100644 --- a/src/common/haxe/ru/m/tankz/Type.hx +++ b/src/common/haxe/ru/m/tankz/Type.hx @@ -19,6 +19,7 @@ typedef TankInfo = { var skin:String; var hits:Int; var bonus:Bool; + var boat:Bool; var color:Color; @:optional var name:String; } diff --git a/src/common/haxe/ru/m/tankz/bonus/BoatBonus.hx b/src/common/haxe/ru/m/tankz/bonus/BoatBonus.hx new file mode 100644 index 0000000..4118761 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/bonus/BoatBonus.hx @@ -0,0 +1,19 @@ +package ru.m.tankz.bonus; + +import ru.m.tankz.core.Tank; +import ru.m.tankz.engine.IEngine; +import ru.m.tankz.game.IGame; +import ru.m.tankz.Type; + +using ru.m.tankz.game.GameUtil; + +class BoatBonus extends BaseBonus { + + public static inline var CLASS = "boat"; + + override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void { + var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId); + tank.boat = true; + game.emitTankChange(tank); + } +} diff --git a/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx b/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx index 063b2d6..fcadfee 100644 --- a/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx +++ b/src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx @@ -16,6 +16,7 @@ class BonusFactory { ProtectTankBonus.CLASS => ProtectTankBonus, UpgradeTankBonus.CLASS => UpgradeTankBonus, SuicideTankBonus.CLASS => SuicideTankBonus, + BoatBonus.CLASS => BoatBonus, ]; } diff --git a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx index df6480d..8bcc7b8 100755 --- a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx +++ b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx @@ -8,7 +8,9 @@ class MobileEntity extends Entity { public var mx(default, default):Float; public var my(default, default):Float; - public var layer(default, null):Int; + public var layer(get, null):Int; + private function get_layer():Int return layer; + public var speed(default, null):Float; public function new(id:Int, rect:Rectangle, speed:Float, direction:Direction) { diff --git a/src/common/haxe/ru/m/tankz/core/Tank.hx b/src/common/haxe/ru/m/tankz/core/Tank.hx index 2c28058..6e70cf1 100755 --- a/src/common/haxe/ru/m/tankz/core/Tank.hx +++ b/src/common/haxe/ru/m/tankz/core/Tank.hx @@ -16,11 +16,14 @@ class Tank extends MobileEntity { public var bonus(default, default):Bool; public var protect(default, default):Bool; public var freezing(default, default):Bool; + public var boat(default, default):Bool; public var weapons(default, null):Array; public var weapon(get, null):Weapon; public var info(get, null):TankInfo; + override function get_layer():Int return layer + (boat ? 1 : 0); + public function new(id:Int, rect:Rectangle, playerId:PlayerId, config:TankConfig) { super(id, rect, config.speed, Direction.RIGHT); this.protect = false; @@ -51,6 +54,7 @@ class Tank extends MobileEntity { skin: config.skin, hits: hits, bonus: bonus, + boat: boat, color: color, name: name, } diff --git a/src/common/haxe/ru/m/tankz/game/GameEvent.hx b/src/common/haxe/ru/m/tankz/game/GameEvent.hx index da2a7ad..f7b6dea 100644 --- a/src/common/haxe/ru/m/tankz/game/GameEvent.hx +++ b/src/common/haxe/ru/m/tankz/game/GameEvent.hx @@ -64,7 +64,7 @@ enum StopEvent { } enum ChangeEvent { - TANK(id:Int, type:TankType, hits:Int, bonus:Bool); + TANK(id:Int, type:TankType, hits:Int, bonus:Bool, boat:Bool); TANK_PROTECT(id:Int, state:Bool); TANK_FREEZE(id:Int, state:Bool); EAGLE_PROTECT(id:Int, state:Bool); diff --git a/src/common/haxe/ru/m/tankz/game/GameRunner.hx b/src/common/haxe/ru/m/tankz/game/GameRunner.hx index df5769c..ba6f411 100644 --- a/src/common/haxe/ru/m/tankz/game/GameRunner.hx +++ b/src/common/haxe/ru/m/tankz/game/GameRunner.hx @@ -74,6 +74,7 @@ class GameRunner extends Game implements EngineListener { skin:tank.skin, hits:tank.hits, bonus:bonus, + boat:false, color:player.state.color, name:player.state.name, } @@ -189,7 +190,10 @@ class GameRunner extends Game implements EngineListener { // Nothing } else { if (!tank.protect) { - if (tank.hits > 0) { + if (tank.boat) { + tank.boat = false; + emitTankChange(tank); + } else if (tank.hits > 0) { tank.hits--; if (tank.bonus) { tank.bonus = false; @@ -310,7 +314,7 @@ class GameRunner extends Game implements EngineListener { bullet.weapon.use(); case CHANGE(BRICK(id, type)): engine.map.bricksById[id].config = config.getBrick(type); - case CHANGE(TANK(id, type, hits, bonus)): + case CHANGE(TANK(id, type, hits, bonus, boat)): var tank:Tank = engine.getEntity(id); getPlayer(tank.playerId).state.tank = tank.info; case DESTROY(EAGLE(id, shot)): diff --git a/src/common/haxe/ru/m/tankz/game/GameUtil.hx b/src/common/haxe/ru/m/tankz/game/GameUtil.hx index ed0fdea..2e98917 100644 --- a/src/common/haxe/ru/m/tankz/game/GameUtil.hx +++ b/src/common/haxe/ru/m/tankz/game/GameUtil.hx @@ -27,7 +27,7 @@ class GameUtil { } public static inline function emitTankChange(game:IGame, tank:Tank):Void { - game.gameEventSignal.emit(CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus))); + game.gameEventSignal.emit(CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus, tank.boat))); } public static function protectTank(game:IGame, tank:Tank, duration:Float):Void { diff --git a/src/common/resources/config/classic.yaml b/src/common/resources/config/classic.yaml index 116ded1..521962e 100644 --- a/src/common/resources/config/classic.yaml +++ b/src/common/resources/config/classic.yaml @@ -159,6 +159,7 @@ bonuses: - {score: 500, factory: armor.eagle, type: shovel, duration: 15} - {score: 500, factory: upgrade.tank, type: star, value: 1} - {score: 500, factory: upgrade.tank, type: gun, value: 5} + - {score: 500, factory: boat, type: boat} presets: - id: 0 diff --git a/src/common/resources/config/dota.yaml b/src/common/resources/config/dota.yaml index 90b72e7..8c117cc 100644 --- a/src/common/resources/config/dota.yaml +++ b/src/common/resources/config/dota.yaml @@ -115,3 +115,4 @@ bonuses: - {score: 100, factory: protect.tank, type: helmet, duration: 15} - {score: 100, factory: life, type: life} - {score: 100, factory: protect.eagle, type: shovel, duration: 10} + - {score: 500, factory: boat, type: boat} diff --git a/src/editor/haxe/ru/m/tankz/editor/view/map/MapEditView.hx b/src/editor/haxe/ru/m/tankz/editor/view/map/MapEditView.hx index 7cc38e7..2c8258f 100644 --- a/src/editor/haxe/ru/m/tankz/editor/view/map/MapEditView.hx +++ b/src/editor/haxe/ru/m/tankz/editor/view/map/MapEditView.hx @@ -131,6 +131,7 @@ enum Brush { skin: config.getTank(tankSpawn.type).skin, hits: 0, bonus: false, + boat: false, color: config.getColor(playerId), name: playerId.format(), }