[common] add ArmorEagleBonus
This commit is contained in:
26
src/client/haxe/ru/m/tankz/render/RenderUtil.hx
Normal file
26
src/client/haxe/ru/m/tankz/render/RenderUtil.hx
Normal file
@@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,13 +4,11 @@ import flash.display.Bitmap;
|
|||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.DisplayObject;
|
import flash.display.DisplayObject;
|
||||||
import flash.display.PixelSnapping;
|
import flash.display.PixelSnapping;
|
||||||
import openfl.Assets;
|
|
||||||
import ru.m.geom.Rectangle;
|
import ru.m.geom.Rectangle;
|
||||||
|
|
||||||
class BitmapRenderItem extends RenderItem {
|
class BitmapRenderItem extends RenderItem {
|
||||||
public var image(default, set):String;
|
public var image(default, set):BitmapData;
|
||||||
|
|
||||||
private var bitmapData:BitmapData;
|
|
||||||
private var bitmap:Bitmap;
|
private var bitmap:Bitmap;
|
||||||
|
|
||||||
public function new(rect:Rectangle) {
|
public function new(rect:Rectangle) {
|
||||||
@@ -22,11 +20,10 @@ class BitmapRenderItem extends RenderItem {
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function set_image(value:String):String {
|
private function set_image(value:BitmapData):BitmapData {
|
||||||
if (image != value) {
|
if (image != value) {
|
||||||
image = value;
|
image = value;
|
||||||
bitmapData = Assets.getBitmapData(image);
|
bitmap.bitmapData = image;
|
||||||
bitmap.bitmapData = bitmapData;
|
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class BonusRenderItem extends BitmapRenderItem {
|
|||||||
private function set_type(value:BonusType):BonusType {
|
private function set_type(value:BonusType):BonusType {
|
||||||
if (type != value) {
|
if (type != value) {
|
||||||
type = value;
|
type = value;
|
||||||
image = 'resources/image/bonus/${type}.png';
|
image = RenderUtil.bonusImage(type);
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,15 +23,19 @@ class BrickRenderItem extends RenderItem {
|
|||||||
private var shape:Shape;
|
private var shape:Shape;
|
||||||
private var cells:Array<Point>;
|
private var cells:Array<Point>;
|
||||||
|
|
||||||
public function new(rect:Rectangle, type:BrickType) {
|
private static function buildCells():Array<Point> {
|
||||||
super(rect);
|
return [
|
||||||
this.shape = new Shape();
|
|
||||||
cells = [
|
|
||||||
new Point(0, 0),
|
new Point(0, 0),
|
||||||
new Point(0, 1),
|
new Point(0, 1),
|
||||||
new Point(1, 0),
|
new Point(1, 0),
|
||||||
new Point(1, 1),
|
new Point(1, 1),
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function new(rect:Rectangle, type:BrickType) {
|
||||||
|
super(rect);
|
||||||
|
this.shape = new Shape();
|
||||||
|
cells = buildCells();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
move(rect.position);
|
move(rect.position);
|
||||||
}
|
}
|
||||||
@@ -51,6 +55,7 @@ class BrickRenderItem extends RenderItem {
|
|||||||
private function set_type(value:BrickType):BrickType {
|
private function set_type(value:BrickType):BrickType {
|
||||||
if (type != value) {
|
if (type != value) {
|
||||||
type = value;
|
type = value;
|
||||||
|
cells = buildCells();
|
||||||
image = Assets.getBitmapData('resources/image/map/${type}.png');
|
image = Assets.getBitmapData('resources/image/map/${type}.png');
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ class BulletRenderItem extends BitmapRenderItem {
|
|||||||
private function set_piercing(value:Int):Int {
|
private function set_piercing(value:Int):Int {
|
||||||
if (piercing != value) {
|
if (piercing != value) {
|
||||||
piercing = value;
|
piercing = value;
|
||||||
var type = piercing > 0 ? 'piercing' : 'normal';
|
image = RenderUtil.bulletImage(piercing);
|
||||||
image = 'resources/image/bullet/${type}.png';
|
|
||||||
}
|
}
|
||||||
return piercing;
|
return piercing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ class EagleRenderItem extends BitmapRenderItem {
|
|||||||
if (protect != value) {
|
if (protect != value) {
|
||||||
protect = value;
|
protect = value;
|
||||||
if (protect) {
|
if (protect) {
|
||||||
protectView.x = (bitmapData.width - protectView.frames[0].image.width) / 2;
|
protectView.x = (image.width - protectView.frames[0].image.width) / 2;
|
||||||
protectView.y = (bitmapData.height - protectView.frames[0].image.height) / 2;
|
protectView.y = (image.height - protectView.frames[0].image.height) / 2;
|
||||||
}
|
}
|
||||||
protectView.visible = protect;
|
protectView.visible = protect;
|
||||||
protectView.playing = protect;
|
protectView.playing = protect;
|
||||||
@@ -47,10 +47,9 @@ class EagleRenderItem extends BitmapRenderItem {
|
|||||||
private function set_death(value:Bool):Bool {
|
private function set_death(value:Bool):Bool {
|
||||||
if (death != value) {
|
if (death != value) {
|
||||||
death = value;
|
death = value;
|
||||||
var suffix = death ? '-death' : '';
|
image = RenderUtil.eagleImage(death);
|
||||||
image = 'resources/image/eagle/eagle${suffix}.png';
|
|
||||||
if (!color.zero) {
|
if (!color.zero) {
|
||||||
bitmap.bitmapData = bitmapData = BitmapUtil.colorize(bitmapData, color);
|
bitmap.bitmapData = image = BitmapUtil.colorize(image, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return death;
|
return death;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package ru.m.tankz.render.item;
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
import haxework.view.theme.ITheme;
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.DisplayObject;
|
import flash.display.DisplayObject;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
@@ -9,8 +8,8 @@ import flash.text.TextFieldAutoSize;
|
|||||||
import flash.text.TextFormat;
|
import flash.text.TextFormat;
|
||||||
import haxework.color.Color;
|
import haxework.color.Color;
|
||||||
import haxework.text.BitmapTextField;
|
import haxework.text.BitmapTextField;
|
||||||
|
import haxework.view.theme.ITheme;
|
||||||
import haxework.view.utils.BitmapUtil;
|
import haxework.view.utils.BitmapUtil;
|
||||||
import openfl.Assets;
|
|
||||||
import ru.m.animate.Animate;
|
import ru.m.animate.Animate;
|
||||||
import ru.m.geom.Rectangle;
|
import ru.m.geom.Rectangle;
|
||||||
|
|
||||||
@@ -62,8 +61,8 @@ class TankRenderItem extends BitmapRenderItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function redraw():Void {
|
private function redraw():Void {
|
||||||
var image1 = Assets.getBitmapData('resources/image/tank/${skin}-0.png');
|
var image1 = RenderUtil.tankImage(skin, 0);
|
||||||
var image2 = Assets.getBitmapData('resources/image/tank/${skin}-1.png');
|
var image2 = RenderUtil.tankImage(skin, 1);
|
||||||
var color1:Color = switch hits {
|
var color1:Color = switch hits {
|
||||||
case 1: 0x869C43;
|
case 1: 0x869C43;
|
||||||
case 2: 0xDEAF80;
|
case 2: 0xDEAF80;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package ru.m.tankz.view.common;
|
package ru.m.tankz.view.common;
|
||||||
|
|
||||||
import haxework.view.ImageView;
|
import haxework.view.ImageView;
|
||||||
import openfl.Assets;
|
|
||||||
import ru.m.tankz.game.GameEvent;
|
import ru.m.tankz.game.GameEvent;
|
||||||
|
import ru.m.tankz.render.RenderUtil;
|
||||||
|
|
||||||
class TankView extends ImageView {
|
class TankView extends ImageView {
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ class TankView extends ImageView {
|
|||||||
private function set_tank(value:TankInfo):TankInfo {
|
private function set_tank(value:TankInfo):TankInfo {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
color = value.color;
|
color = value.color;
|
||||||
image = Assets.getBitmapData('resources/image/tank/${value.skin}-0.png');
|
image = RenderUtil.tankImage(value.skin);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package ru.m.tankz.view.result;
|
package ru.m.tankz.view.result;
|
||||||
|
|
||||||
import openfl.utils.Assets;
|
|
||||||
import haxework.view.form.LabelView;
|
import haxework.view.form.LabelView;
|
||||||
import haxework.view.group.HGroupView;
|
import haxework.view.group.HGroupView;
|
||||||
import ru.m.tankz.game.GameState;
|
import ru.m.tankz.game.GameState;
|
||||||
|
import ru.m.tankz.render.RenderUtil;
|
||||||
import ru.m.tankz.view.common.TankView;
|
import ru.m.tankz.view.common.TankView;
|
||||||
|
|
||||||
@:template class FragView extends HGroupView {
|
@:template class FragView extends HGroupView {
|
||||||
@@ -16,15 +16,18 @@ import ru.m.tankz.view.common.TankView;
|
|||||||
|
|
||||||
private function set_data(value:Frag):Frag {
|
private function set_data(value:Frag):Frag {
|
||||||
data = value;
|
data = value;
|
||||||
|
titleView.text = data.playerId.format();
|
||||||
|
scoreView.text = data.score.format();
|
||||||
switch data.target {
|
switch data.target {
|
||||||
case TANK(tank):
|
case TANK(tank):
|
||||||
tankView.tank = tank;
|
tankView.tank = tank;
|
||||||
case EAGLE(color):
|
case EAGLE(color):
|
||||||
tankView.image = Assets.getBitmapData('resources/image/eagle/eagle.png');
|
tankView.image = RenderUtil.eagleImage();
|
||||||
tankView.color = color;
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
43
src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx
Normal file
43
src/common/haxe/ru/m/tankz/bonus/ArmorEagleBonus.hx
Normal file
@@ -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<Int> = [];
|
||||||
|
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}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx
Normal file
26
src/common/haxe/ru/m/tankz/bonus/BonusFactory.hx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package ru.m.tankz.bonus;
|
||||||
|
|
||||||
|
import ru.m.tankz.config.Config.BonusConfig;
|
||||||
|
|
||||||
|
class BonusFactory {
|
||||||
|
|
||||||
|
private var classes:Map<String, Class<IBonus>>;
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class DestroyTeamBonus extends BaseBonus {
|
class DestroyTeamBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "destroy.team";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
||||||
if (tank != null) {
|
if (tank != null) {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class FreezeTeamBonus extends BaseBonus {
|
class FreezeTeamBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "freeze.team";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
for (team in game.teams) {
|
for (team in game.teams) {
|
||||||
if (team.id != playerId.team) {
|
if (team.id != playerId.team) {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class LifeBonus extends BaseBonus {
|
class LifeBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "life";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
game.changeLife(playerId, 1);
|
game.changeLife(playerId, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class ProtectEagleBonus extends BaseBonus {
|
class ProtectEagleBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "protect.eagle";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
var team:Team = game.getTeam(playerId.team);
|
var team:Team = game.getTeam(playerId.team);
|
||||||
if (team.eagleId > 0) {
|
if (team.eagleId > 0) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class ProtectTankBonus extends BaseBonus {
|
class ProtectTankBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "protect.tank";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
||||||
if (tank != null) {
|
if (tank != null) {
|
||||||
|
|||||||
21
src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx
Normal file
21
src/common/haxe/ru/m/tankz/bonus/SuicideTankBonus.hx
Normal file
@@ -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})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
|
|
||||||
class UpgradeTankBonus extends BaseBonus {
|
class UpgradeTankBonus extends BaseBonus {
|
||||||
|
|
||||||
|
public static inline var CLASS = "upgrade.tank";
|
||||||
|
|
||||||
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
override public function apply(playerId:PlayerId, game:IGame, engine:IEngine):Void {
|
||||||
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
var tank:Tank = engine.getEntity(game.getPlayer(playerId).tankId);
|
||||||
if (tank != null) {
|
if (tank != null) {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ typedef TankConfig = {
|
|||||||
|
|
||||||
typedef BonusConfig = {
|
typedef BonusConfig = {
|
||||||
var type:BonusType;
|
var type:BonusType;
|
||||||
|
var factory:String;
|
||||||
@:optional var duration:Null<Int>;
|
@:optional var duration:Null<Int>;
|
||||||
@:optional var value:Null<Int>;
|
@:optional var value:Null<Int>;
|
||||||
@:optinal var score:Null<Int>;
|
@:optinal var score:Null<Int>;
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ interface ITicker {
|
|||||||
public function start():Void;
|
public function start():Void;
|
||||||
public function stop():Void;
|
public function stop():Void;
|
||||||
public function tick():Int;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Ticker implements ITicker {
|
|||||||
private var passed:Int;
|
private var passed:Int;
|
||||||
private var last_tick:Int;
|
private var last_tick:Int;
|
||||||
private var actions:Array<Action>;
|
private var actions:Array<Action>;
|
||||||
|
private var actionsByKey:Map<String, Action>;
|
||||||
private var actionId = 0;
|
private var actionId = 0;
|
||||||
|
|
||||||
private static var TIME = Timer.stamp();
|
private static var TIME = Timer.stamp();
|
||||||
@@ -26,6 +27,7 @@ class Ticker implements ITicker {
|
|||||||
last_tick = 0;
|
last_tick = 0;
|
||||||
running = false;
|
running = false;
|
||||||
actions = [];
|
actions = [];
|
||||||
|
actionsByKey = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function get_time():Int {
|
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};
|
var action:Action = {action:fun, time:time+delay, id:++actionId};
|
||||||
//L.d("Ticker", 'emit: ${action.id} ${action.time}');
|
//L.d("Ticker", 'emit: ${action.id} ${action.time}');
|
||||||
|
if (key != null) {
|
||||||
|
cancel(key);
|
||||||
|
actionsByKey[key] = action;
|
||||||
|
}
|
||||||
actions.push(action);
|
actions.push(action);
|
||||||
actions.sort(function(a, b) return a.time - b.time);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,7 @@ package ru.m.tankz.game;
|
|||||||
|
|
||||||
import ru.m.geom.Line;
|
import ru.m.geom.Line;
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
import ru.m.tankz.bonus.DestroyTeamBonus;
|
import ru.m.tankz.bonus.BonusFactory;
|
||||||
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.control.Control;
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.tankz.core.Bonus;
|
import ru.m.tankz.core.Bonus;
|
||||||
import ru.m.tankz.core.Bullet;
|
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.Engine;
|
||||||
import ru.m.tankz.engine.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
import ru.m.tankz.game.GameEvent;
|
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.game.Spawner;
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
import ru.m.Timer;
|
import ru.m.Timer;
|
||||||
@@ -28,34 +22,19 @@ using ru.m.tankz.game.GameUtil;
|
|||||||
class GameRunner extends Game implements EngineListener {
|
class GameRunner extends Game implements EngineListener {
|
||||||
private var timer:Timer;
|
private var timer:Timer;
|
||||||
private var builder:EntityBuilder;
|
private var builder:EntityBuilder;
|
||||||
private var bonuses:Map<String, IBonus>;
|
private var bonuses:BonusFactory;
|
||||||
|
|
||||||
public function new(start:Start) {
|
public function new(start:Start) {
|
||||||
super(start.state.type);
|
super(start.state.type);
|
||||||
this.level = start.level;
|
this.level = start.level;
|
||||||
this.state = start.state;
|
this.state = start.state;
|
||||||
builder = new EntityBuilder(config);
|
builder = new EntityBuilder(config);
|
||||||
bonuses = new Map();
|
bonuses = new BonusFactory();
|
||||||
for (bonus in buildBonuses()) {
|
|
||||||
bonuses[bonus.type] = bonus;
|
|
||||||
}
|
|
||||||
engine = new Engine(config, level.size);
|
engine = new Engine(config, level.size);
|
||||||
ticker = engine.ticker;
|
ticker = engine.ticker;
|
||||||
engine.connect(this);
|
engine.connect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildBonuses():Array<IBonus> {
|
|
||||||
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 {
|
override function changePause(value:Bool):Void {
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
if (value) {
|
if (value) {
|
||||||
@@ -254,11 +233,8 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function applyBonus(tank:Tank, bonus:Bonus):Void {
|
private function applyBonus(tank:Tank, bonus:Bonus):Void {
|
||||||
if (bonuses.exists(bonus.config.type)) {
|
var bonus = bonuses.build(bonus.config);
|
||||||
bonuses[bonus.config.type].apply(tank.playerId, this, engine);
|
bonus.apply(tank.playerId, this, engine);
|
||||||
} else {
|
|
||||||
gameEventSignal.emit(DESTROY(TANK(tank.id, {tankId: tank.id}))); // :-D
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function onGameEvent(event:GameEvent):Void {
|
override public function onGameEvent(event:GameEvent):Void {
|
||||||
@@ -306,6 +282,8 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
player.state.tank = info;
|
player.state.tank = info;
|
||||||
case SPAWN(BULLET(_, _, playerId, _)):
|
case SPAWN(BULLET(_, _, playerId, _)):
|
||||||
getPlayer(playerId).bullets++;
|
getPlayer(playerId).bullets++;
|
||||||
|
case CHANGE(BRICK(id, type)):
|
||||||
|
engine.map.bricksById[id].config = config.getBrick(type);
|
||||||
case DESTROY(EAGLE(id, shot)):
|
case DESTROY(EAGLE(id, shot)):
|
||||||
var eagle:Eagle = engine.getEntity(id);
|
var eagle:Eagle = engine.getEntity(id);
|
||||||
eagle.death = true;
|
eagle.death = true;
|
||||||
@@ -355,6 +333,12 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
var bonus:Bonus = engine.getEntity(id);
|
var bonus:Bonus = engine.getEntity(id);
|
||||||
var tank:Tank = engine.getEntity(shot.tankId);
|
var tank:Tank = engine.getEntity(shot.tankId);
|
||||||
applyBonus(tank, bonus);
|
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) {
|
if (shot.score != null) {
|
||||||
changeScore(tank.playerId, shot.score);
|
changeScore(tank.playerId, shot.score);
|
||||||
}
|
}
|
||||||
@@ -373,10 +357,10 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
var shot = buildShot(bullet);
|
var shot = buildShot(bullet);
|
||||||
if (cell.armor == bullet.config.piercing) {
|
if (cell.armor == bullet.config.piercing) {
|
||||||
engine.destroyCell(cell.cellX, cell.cellY);
|
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)));
|
gameEventSignal.emit(DESTROY(CELL(brick.id, cell.cellX - brick.cellX * 2, cell.cellY - brick.cellY * 2, shot)));
|
||||||
} else if (cell.armor < bullet.config.piercing) {
|
} 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) {
|
for (cell in brick.cells) {
|
||||||
engine.destroyCell(cell.cellX, cell.cellY);
|
engine.destroyCell(cell.cellX, cell.cellY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import ru.m.tankz.Type;
|
|||||||
enum FragTarget {
|
enum FragTarget {
|
||||||
TANK(tank:TankInfo);
|
TANK(tank:TankInfo);
|
||||||
EAGLE(color:Color);
|
EAGLE(color:Color);
|
||||||
|
BONUS(type:BonusType);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Frag = {
|
typedef Frag = {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class GameUtil {
|
|||||||
game.ticker.emit(function() {
|
game.ticker.emit(function() {
|
||||||
tank.protect = false;
|
tank.protect = false;
|
||||||
game.gameEventSignal.emit(CHANGE(TANK_PROTECT(tank.id, tank.protect)));
|
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 {
|
public static function protectEagle(game:IGame, eagle:Eagle, duration:Float):Void {
|
||||||
@@ -42,7 +42,7 @@ class GameUtil {
|
|||||||
game.ticker.emit(function() {
|
game.ticker.emit(function() {
|
||||||
eagle.protect = false;
|
eagle.protect = false;
|
||||||
game.gameEventSignal.emit(CHANGE(EAGLE_PROTECT(eagle.id, eagle.protect)));
|
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 {
|
public static function freezeTank(game:IGame, tank:Tank, duration:Float):Void {
|
||||||
@@ -53,7 +53,7 @@ class GameUtil {
|
|||||||
game.ticker.emit(function() {
|
game.ticker.emit(function() {
|
||||||
tank.freezing = false;
|
tank.freezing = false;
|
||||||
game.gameEventSignal.emit(CHANGE(TANK_FREEZE(tank.id, tank.freezing)));
|
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 {
|
public static function freezeTeam(game:IGame, engine:IEngine, teamId:TeamId, duration:Float):Void {
|
||||||
@@ -70,7 +70,7 @@ class GameUtil {
|
|||||||
tank.freezing = false;
|
tank.freezing = false;
|
||||||
game.gameEventSignal.emit(CHANGE(TANK_FREEZE(tank.id, tank.freezing)));
|
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 {
|
public static function changeLife(game:IGame, playerId:PlayerId, life:Int):Void {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class Brick {
|
|||||||
public var cellY(default, null):Int;
|
public var cellY(default, null):Int;
|
||||||
|
|
||||||
public var mapConfig(default, null):MapConfig;
|
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 rect(default, null):Rectangle;
|
||||||
public var cells(default, null):HashMap<Point, GridCell>;
|
public var cells(default, null):HashMap<Point, GridCell>;
|
||||||
@@ -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;
|
var i:Int = 0;
|
||||||
for (c in cells.iterator()) {
|
for (c in cells.iterator()) {
|
||||||
if (c.destroyed) {
|
if (c.destroyed) {
|
||||||
@@ -44,7 +54,7 @@ class Brick {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_destroyed():Bool {
|
private function get_destroyed():Bool {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var result:Bool = false;
|
var result:Bool = false;
|
||||||
for (c in cells.iterator()) {
|
for (c in cells.iterator()) {
|
||||||
@@ -57,7 +67,7 @@ class Brick {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set_destroyed(value:Bool):Bool {
|
private function set_destroyed(value:Bool):Bool {
|
||||||
if (value) {
|
if (value) {
|
||||||
for (c in cells.iterator()) {
|
for (c in cells.iterator()) {
|
||||||
c.destroyed = true;
|
c.destroyed = true;
|
||||||
@@ -66,7 +76,7 @@ class Brick {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_id():Int {
|
private function get_id():Int {
|
||||||
return -((cellX * 1000) + cellY);
|
return -((cellX * 1000) + cellY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class LevelMap {
|
|||||||
public var height(get, null):Float;
|
public var height(get, null):Float;
|
||||||
|
|
||||||
public var bricks(default, null):Array<Brick>;
|
public var bricks(default, null):Array<Brick>;
|
||||||
|
public var bricksById(default, null):Map<Int, Brick>;
|
||||||
|
|
||||||
public var grid(default, null):Grid;
|
public var grid(default, null):Grid;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ class LevelMap {
|
|||||||
gridHeight = size != null ? size.height : config.grid.height;
|
gridHeight = size != null ? size.height : config.grid.height;
|
||||||
bricksMap = new HashMap();
|
bricksMap = new HashMap();
|
||||||
bricks = [];
|
bricks = [];
|
||||||
|
bricksById = new Map();
|
||||||
grid = new Grid(
|
grid = new Grid(
|
||||||
Std.int(cellWidth / 2),
|
Std.int(cellWidth / 2),
|
||||||
Std.int(cellHeight / 2),
|
Std.int(cellHeight / 2),
|
||||||
@@ -57,11 +59,16 @@ class LevelMap {
|
|||||||
for (cell in brick.cells.iterator()) {
|
for (cell in brick.cells.iterator()) {
|
||||||
bricksMap.set(cell.position, brick);
|
bricksMap.set(cell.position, brick);
|
||||||
}
|
}
|
||||||
|
bricksById.set(brick.id, brick);
|
||||||
return brick;
|
return brick;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBrick(position:Point):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);
|
return bricksMap.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,13 +147,13 @@ tanks:
|
|||||||
skin: bd
|
skin: bd
|
||||||
|
|
||||||
bonuses:
|
bonuses:
|
||||||
- {score: 500, type: clock, duration: 10}
|
- {score: 500, factory: freeze.team, type: clock, duration: 10}
|
||||||
- {score: 500, type: grenade}
|
- {score: 500, factory: destroy.team, type: grenade}
|
||||||
- {score: 500, type: helmet, duration: 20}
|
- {score: 500, factory: protect.tank, type: helmet, duration: 15}
|
||||||
- {score: 500, type: life}
|
- {score: 500, factory: life, type: life}
|
||||||
- {score: 500, type: shovel, duration: 10}
|
- {score: 500, factory: armor.eagle, type: shovel, duration: 10}
|
||||||
- {score: 500, type: star, value: 1}
|
- {score: 500, factory: upgrade.tank, type: star, value: 1}
|
||||||
- {score: 500, type: gun, value: 5}
|
- {score: 500, factory: upgrade.tank, type: gun, value: 5}
|
||||||
|
|
||||||
presets:
|
presets:
|
||||||
- id: 0
|
- id: 0
|
||||||
|
|||||||
@@ -107,9 +107,8 @@ tanks:
|
|||||||
skin: bb
|
skin: bb
|
||||||
|
|
||||||
bonuses:
|
bonuses:
|
||||||
- {type: clock, duration: 10}
|
- {score: 100, factory: freeze.team, type: clock, duration: 10}
|
||||||
- {type: grenade}
|
- {score: 100, factory: destroy.team, type: grenade}
|
||||||
- {type: helmet, duration: 20}
|
- {score: 100, factory: protect.tank, type: helmet, duration: 15}
|
||||||
- {type: life}
|
- {score: 100, factory: life, type: life}
|
||||||
- {type: shovel, duration: 10}
|
- {score: 100, factory: protect.eagle, type: shovel, duration: 10}
|
||||||
- {type: star}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user