[common] add boat bonus

[client] add active style to gamepad buttons
This commit is contained in:
2019-09-16 14:41:12 +03:00
parent bddb590d30
commit 30325f6d16
20 changed files with 95 additions and 29 deletions

View File

@@ -1,12 +1,10 @@
* bonuses * bonuses
* death game bonuses * death game bonuses
* boat bonus
* tanks and bullets speed balancing * tanks and bullets speed balancing
* game series * game series
* network series * network series
* map packs * map packs
* create in editor * import in game
* import in game
* save imported in local storage * save imported in local storage
* database * database
* cache * cache

View File

@@ -146,7 +146,8 @@ class AppTheme extends Theme {
registerButton("tablet-android-alt", "tablet-android-alt-light.svg", true); registerButton("tablet-android-alt", "tablet-android-alt-light.svg", true);
register(new Style("gamepad", [ register(new Style("gamepad", [
"skin.color" => colors.active, "skin.color" => colors.text,
"skin.activeColor" => colors.active,
])); ]));
} }

View File

@@ -144,6 +144,7 @@ class Render extends SpriteView implements IRender {
item.skin = tankConfig.skin; item.skin = tankConfig.skin;
item.hits = info.hits; item.hits = info.hits;
item.bonus = info.bonus; item.bonus = info.bonus;
item.boat = info.boat;
item.name = info.name == null ? "" : info.name; item.name = info.name == null ? "" : info.name;
items.set(id, item); items.set(id, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
@@ -180,12 +181,13 @@ class Render extends SpriteView implements IRender {
var item = items[id]; var item = items[id];
cast(item, TankRenderItem).moves = false; cast(item, TankRenderItem).moves = false;
} }
case CHANGE(TANK(id, type, hits, bonus)): case CHANGE(TANK(id, type, hits, bonus, boat)):
if (items.exists(id)) { if (items.exists(id)) {
var item:TankRenderItem = cast items[id]; var item:TankRenderItem = cast items[id];
item.skin = config.getTank(type).skin; item.skin = config.getTank(type).skin;
item.hits = hits; item.hits = hits;
item.bonus = bonus; item.bonus = bonus;
item.boat = boat;
} }
case CHANGE(TANK_PROTECT(id, state)): case CHANGE(TANK_PROTECT(id, state)):
if (items.exists(id)) { if (items.exists(id)) {

View File

@@ -2,6 +2,7 @@ package ru.m.tankz.render.item;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.DisplayObject; import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite; import flash.display.Sprite;
import flash.text.TextField; import flash.text.TextField;
import flash.text.TextFieldAutoSize; import flash.text.TextFieldAutoSize;
@@ -18,6 +19,7 @@ class TankRenderItem extends BitmapRenderItem {
public var skin(default, set):String; public var skin(default, set):String;
public var hits(default, set):Int; public var hits(default, set):Int;
public var bonus(default, set):Bool; public var bonus(default, set):Bool;
public var boat(default, set):Bool;
public var moves(default, set):Bool; public var moves(default, set):Bool;
public var protect(default, set):Bool; public var protect(default, set):Bool;
public var name(default, set):String; public var name(default, set):String;
@@ -26,6 +28,7 @@ class TankRenderItem extends BitmapRenderItem {
private var images:Array<BitmapData>; private var images:Array<BitmapData>;
private var frame:Int; private var frame:Int;
private var protectView:Animate; private var protectView:Animate;
private var boatView:Shape;
private var nameView:TextField; private var nameView:TextField;
@:provide static var theme:ITheme; @:provide static var theme:ITheme;
@@ -39,6 +42,9 @@ class TankRenderItem extends BitmapRenderItem {
container.addChild(protectView); container.addChild(protectView);
nameView = buildNameView(); nameView = buildNameView();
container.addChild(nameView); container.addChild(nameView);
boatView = buildBoatView();
boatView.visible = false;
container.addChild(boatView);
move(rect.position); move(rect.position);
} }
@@ -52,6 +58,13 @@ class TankRenderItem extends BitmapRenderItem {
return result; 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 { override private function get_view():DisplayObject {
return container; return container;
} }
@@ -108,6 +121,14 @@ class TankRenderItem extends BitmapRenderItem {
return bonus; 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 { private function set_protect(value:Bool):Bool {
if (protect != value) { if (protect != value) {
protect = value; protect = value;

View File

@@ -53,6 +53,7 @@ class GameViewHelper {
skin: tank.skin, skin: tank.skin,
hits: 0, hits: 0,
bonus: false, bonus: false,
boat: false,
color: config.getColor(playerView.playerId), color: config.getColor(playerView.playerId),
}; };
} }

View File

@@ -6,21 +6,24 @@ import haxework.view.skin.ISkin;
@:style class GamepadSkin implements ISkin<GamepadView> { @:style class GamepadSkin implements ISkin<GamepadView> {
@:style(0x00ff00) public var color(default, default):Null<Color>; @:style(0xffffff) public var color(default, default):Null<Color>;
@:style(0x00ff00) public var activeColor(default, default):Null<Color>;
public function new(?color:Color) { public function new(?color:Color) {
this.color = color; this.color = color;
} }
public function draw(view:GamepadView):Void { public function draw(view:GamepadView):Void {
var actives = [for (item in view.activeAreas.iterator()) item];
var graphics:Graphics = view.content.graphics; var graphics:Graphics = view.content.graphics;
graphics.clear(); graphics.clear();
graphics.beginFill(0, 0.0); graphics.beginFill(0, 0.0);
graphics.drawRect(0, 0, view.width, view.height); graphics.drawRect(0, 0, view.width, view.height);
graphics.endFill(); graphics.endFill();
graphics.lineStyle(2, color);
graphics.beginFill(color, 0.2);
for (area in view.areas) { 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); area.draw(graphics);
} }
graphics.lineStyle(); graphics.lineStyle();

View File

@@ -16,7 +16,7 @@ class GamepadView extends SpriteView implements IControlDevice {
public var signal(default, null):Signal2<DeviceAction, Bool>; public var signal(default, null):Signal2<DeviceAction, Bool>;
public var areas(default, null):Array<IActionArea>; public var areas(default, null):Array<IActionArea>;
public var currentAreas(default, null):Map<Int, IActionArea>; public var activeAreas(default, null):Map<Int, IActionArea>;
private var builder:IActionAreaBuilder; private var builder:IActionAreaBuilder;
private var stage:Stage; private var stage:Stage;
@@ -28,7 +28,7 @@ class GamepadView extends SpriteView implements IControlDevice {
builder = new SmartActionAreaBuilder(); builder = new SmartActionAreaBuilder();
signal = new Signal2(); signal = new Signal2();
areas = []; areas = [];
currentAreas = new Map(); activeAreas = new Map();
skin = new GamepadSkin(); skin = new GamepadSkin();
content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
content.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); content.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
@@ -66,33 +66,37 @@ class GamepadView extends SpriteView implements IControlDevice {
private function onTouchEnd(event:TouchEvent):Void { private function onTouchEnd(event:TouchEvent):Void {
endTouch(event.touchPointID); endTouch(event.touchPointID);
if (Lambda.count(currentAreas) == 0) { if (Lambda.count(activeAreas) == 0) {
stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd); stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
} }
} }
private function updateTouch(pointID:Int, point:Point):Void { private function updateTouch(pointID:Int, point:Point):Void {
if (currentAreas.exists(pointID)) { if (activeAreas.exists(pointID)) {
var area = currentAreas[pointID]; var area = activeAreas[pointID];
if (!area.contain(point)) { if (!area.contain(point)) {
currentAreas.remove(pointID); activeAreas.remove(pointID);
signal.emit(area.action, false); signal.emit(area.action, false);
toRedraw();
} }
} } else {
for (area in areas) { for (area in areas) {
if (area.contain(point)) { if (area.contain(point)) {
currentAreas[pointID] = area; activeAreas[pointID] = area;
signal.emit(area.action, true); signal.emit(area.action, true);
break; toRedraw();
break;
}
} }
} }
} }
private function endTouch(pointID:Int):Void { private function endTouch(pointID:Int):Void {
if (currentAreas.exists(pointID)) { if (activeAreas.exists(pointID)) {
signal.emit(currentAreas[pointID].action, false); signal.emit(activeAreas[pointID].action, false);
currentAreas.remove(pointID); activeAreas.remove(pointID);
toRedraw();
} }
} }

View File

@@ -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); var additionalScore = Lambda.fold(data.frags, function(frag:Frag, score:Int) return score + frag.score, 0);
scoreView.text = '${data.score}$ (+${additionalScore}$)'; scoreView.text = '${data.score}$ (+${additionalScore}$)';
tankView.color = value.color; tankView.color = value.color;
fragsView.data = data.frags; var frags = data.frags.slice(0);
frags.reverse();
fragsView.data = frags;
tankView.tank = value.tank; tankView.tank = value.tank;
return data; return data;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -19,6 +19,7 @@ typedef TankInfo = {
var skin:String; var skin:String;
var hits:Int; var hits:Int;
var bonus:Bool; var bonus:Bool;
var boat:Bool;
var color:Color; var color:Color;
@:optional var name:String; @:optional var name:String;
} }

View File

@@ -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);
}
}

View File

@@ -16,6 +16,7 @@ class BonusFactory {
ProtectTankBonus.CLASS => ProtectTankBonus, ProtectTankBonus.CLASS => ProtectTankBonus,
UpgradeTankBonus.CLASS => UpgradeTankBonus, UpgradeTankBonus.CLASS => UpgradeTankBonus,
SuicideTankBonus.CLASS => SuicideTankBonus, SuicideTankBonus.CLASS => SuicideTankBonus,
BoatBonus.CLASS => BoatBonus,
]; ];
} }

View File

@@ -8,7 +8,9 @@ class MobileEntity extends Entity {
public var mx(default, default):Float; public var mx(default, default):Float;
public var my(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 var speed(default, null):Float;
public function new(id:Int, rect:Rectangle, speed:Float, direction:Direction) { public function new(id:Int, rect:Rectangle, speed:Float, direction:Direction) {

View File

@@ -16,11 +16,14 @@ class Tank extends MobileEntity {
public var bonus(default, default):Bool; public var bonus(default, default):Bool;
public var protect(default, default):Bool; public var protect(default, default):Bool;
public var freezing(default, default):Bool; public var freezing(default, default):Bool;
public var boat(default, default):Bool;
public var weapons(default, null):Array<Weapon>; public var weapons(default, null):Array<Weapon>;
public var weapon(get, null):Weapon; public var weapon(get, null):Weapon;
public var info(get, null):TankInfo; 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) { public function new(id:Int, rect:Rectangle, playerId:PlayerId, config:TankConfig) {
super(id, rect, config.speed, Direction.RIGHT); super(id, rect, config.speed, Direction.RIGHT);
this.protect = false; this.protect = false;
@@ -51,6 +54,7 @@ class Tank extends MobileEntity {
skin: config.skin, skin: config.skin,
hits: hits, hits: hits,
bonus: bonus, bonus: bonus,
boat: boat,
color: color, color: color,
name: name, name: name,
} }

View File

@@ -64,7 +64,7 @@ enum StopEvent {
} }
enum ChangeEvent { 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_PROTECT(id:Int, state:Bool);
TANK_FREEZE(id:Int, state:Bool); TANK_FREEZE(id:Int, state:Bool);
EAGLE_PROTECT(id:Int, state:Bool); EAGLE_PROTECT(id:Int, state:Bool);

View File

@@ -74,6 +74,7 @@ class GameRunner extends Game implements EngineListener {
skin:tank.skin, skin:tank.skin,
hits:tank.hits, hits:tank.hits,
bonus:bonus, bonus:bonus,
boat:false,
color:player.state.color, color:player.state.color,
name:player.state.name, name:player.state.name,
} }
@@ -189,7 +190,10 @@ class GameRunner extends Game implements EngineListener {
// Nothing // Nothing
} else { } else {
if (!tank.protect) { if (!tank.protect) {
if (tank.hits > 0) { if (tank.boat) {
tank.boat = false;
emitTankChange(tank);
} else if (tank.hits > 0) {
tank.hits--; tank.hits--;
if (tank.bonus) { if (tank.bonus) {
tank.bonus = false; tank.bonus = false;
@@ -310,7 +314,7 @@ class GameRunner extends Game implements EngineListener {
bullet.weapon.use(); bullet.weapon.use();
case CHANGE(BRICK(id, type)): case CHANGE(BRICK(id, type)):
engine.map.bricksById[id].config = config.getBrick(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); var tank:Tank = engine.getEntity(id);
getPlayer(tank.playerId).state.tank = tank.info; getPlayer(tank.playerId).state.tank = tank.info;
case DESTROY(EAGLE(id, shot)): case DESTROY(EAGLE(id, shot)):

View File

@@ -27,7 +27,7 @@ class GameUtil {
} }
public static inline function emitTankChange(game:IGame, tank:Tank):Void { 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 { public static function protectTank(game:IGame, tank:Tank, duration:Float):Void {

View File

@@ -159,6 +159,7 @@ bonuses:
- {score: 500, factory: armor.eagle, type: shovel, duration: 15} - {score: 500, factory: armor.eagle, type: shovel, duration: 15}
- {score: 500, factory: upgrade.tank, type: star, value: 1} - {score: 500, factory: upgrade.tank, type: star, value: 1}
- {score: 500, factory: upgrade.tank, type: gun, value: 5} - {score: 500, factory: upgrade.tank, type: gun, value: 5}
- {score: 500, factory: boat, type: boat}
presets: presets:
- id: 0 - id: 0

View File

@@ -115,3 +115,4 @@ bonuses:
- {score: 100, factory: protect.tank, type: helmet, duration: 15} - {score: 100, factory: protect.tank, type: helmet, duration: 15}
- {score: 100, factory: life, type: life} - {score: 100, factory: life, type: life}
- {score: 100, factory: protect.eagle, type: shovel, duration: 10} - {score: 100, factory: protect.eagle, type: shovel, duration: 10}
- {score: 500, factory: boat, type: boat}

View File

@@ -131,6 +131,7 @@ enum Brush {
skin: config.getTank(tankSpawn.type).skin, skin: config.getTank(tankSpawn.type).skin,
hits: 0, hits: 0,
bonus: false, bonus: false,
boat: false,
color: config.getColor(playerId), color: config.getColor(playerId),
name: playerId.format(), name: playerId.format(),
} }