[client] update render
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
package ru.m.tankz.render;
|
package ru.m.tankz.render;
|
||||||
|
|
||||||
import haxework.view.IView;
|
import haxework.view.IView;
|
||||||
import ru.m.tankz.engine.IEngine;
|
|
||||||
import ru.m.tankz.game.IGame;
|
import ru.m.tankz.game.IGame;
|
||||||
|
|
||||||
interface IRender extends IView<Dynamic> extends GameListener extends EngineListener {
|
interface IRender extends IView<Dynamic> {
|
||||||
public function draw(game:IEngine):Void;
|
public var game(default, set):IGame;
|
||||||
|
public function draw():Void;
|
||||||
public function reset():Void;
|
public function reset():Void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package ru.m.tankz.render;
|
package ru.m.tankz.render;
|
||||||
|
|
||||||
import ru.m.geom.Rectangle;
|
|
||||||
import flash.display.DisplayObjectContainer;
|
import flash.display.DisplayObjectContainer;
|
||||||
import flash.display.Graphics;
|
import flash.display.Graphics;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
|
import flash.events.Event;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
import haxework.view.LabelView;
|
import haxework.view.LabelView;
|
||||||
import haxework.view.SpriteView;
|
import haxework.view.SpriteView;
|
||||||
@@ -14,9 +14,17 @@ import ru.m.geom.Point;
|
|||||||
import ru.m.tankz.core.EntityType;
|
import ru.m.tankz.core.EntityType;
|
||||||
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.render.RenderItem;
|
import ru.m.tankz.game.IGame;
|
||||||
|
import ru.m.tankz.render.item.BonusRenderItem;
|
||||||
|
import ru.m.tankz.render.item.BrickRenderItem;
|
||||||
|
import ru.m.tankz.render.item.BulletRenderItem;
|
||||||
|
import ru.m.tankz.render.item.EagleRenderItem;
|
||||||
|
import ru.m.tankz.render.item.IRenderItem;
|
||||||
|
import ru.m.tankz.render.item.TankRenderItem;
|
||||||
|
|
||||||
class Render extends SpriteView implements IRender {
|
class Render extends SpriteView implements IRender implements GameListener {
|
||||||
|
|
||||||
|
public var game(default, set):IGame;
|
||||||
|
|
||||||
private var backgroundLayer:Sprite;
|
private var backgroundLayer:Sprite;
|
||||||
private var groundLayer:Sprite;
|
private var groundLayer:Sprite;
|
||||||
@@ -25,7 +33,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
private var upperLayer:Sprite;
|
private var upperLayer:Sprite;
|
||||||
|
|
||||||
private var background:Sprite;
|
private var background:Sprite;
|
||||||
private var items:Map<Int, RenderItem<Dynamic, Dynamic>>;
|
private var items:Map<Int, IRenderItem>;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
@@ -43,6 +51,13 @@ class Render extends SpriteView implements IRender {
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function set_game(value:IGame):IGame {
|
||||||
|
game = value;
|
||||||
|
game.connect(this);
|
||||||
|
game.engine.spawnSignal.connect(onSpawn);
|
||||||
|
return game;
|
||||||
|
}
|
||||||
|
|
||||||
private function drawBackground(engine:IEngine):Void {
|
private function drawBackground(engine:IEngine):Void {
|
||||||
var g:Graphics = backgroundLayer.graphics;
|
var g:Graphics = backgroundLayer.graphics;
|
||||||
g.clear();
|
g.clear();
|
||||||
@@ -52,38 +67,25 @@ class Render extends SpriteView implements IRender {
|
|||||||
setContentSize(engine.map.width, engine.map.height);
|
setContentSize(engine.map.width, engine.map.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function draw(game:IEngine):Void {
|
public function draw():Void {
|
||||||
for (brick in game.map.bricks) if (brick.config.index > 0) {
|
|
||||||
if (!items.exists(brick.id)) {
|
|
||||||
var item:RenderItem<Dynamic, Dynamic> = switch(brick.config.type) {
|
|
||||||
case 'ace' | 'bush': new BrickItem(brick);
|
|
||||||
case 'water': new BrickAnimateItem(brick);
|
|
||||||
case 'armor' | 'brick': new BrickBreakingItem(brick);
|
|
||||||
case x: null;
|
|
||||||
};
|
|
||||||
if (item != null) {
|
|
||||||
items[brick.id] = item;
|
|
||||||
if (brick.config.layer > 2) {
|
|
||||||
upLayer.addChild(item.view);
|
|
||||||
} else {
|
|
||||||
groundLayer.addChild(item.view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
item.update();
|
item.update();
|
||||||
}
|
}
|
||||||
if (background == null) {
|
if (background == null) {
|
||||||
drawBackground(game);
|
drawBackground(game.engine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function onEnterFrame(event:Event):Void {
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
private function clearLayer(layer:DisplayObjectContainer) {
|
private function clearLayer(layer:DisplayObjectContainer) {
|
||||||
while (layer.numChildren > 0) layer.removeChildAt(0);
|
while (layer.numChildren > 0) layer.removeChildAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset():Void {
|
public function reset():Void {
|
||||||
|
content.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||||
for (item in items.iterator()) {
|
for (item in items.iterator()) {
|
||||||
item.dispose();
|
item.dispose();
|
||||||
}
|
}
|
||||||
@@ -101,23 +103,23 @@ class Render extends SpriteView implements IRender {
|
|||||||
public function onSpawn(entity:EntityType):Void {
|
public function onSpawn(entity:EntityType):Void {
|
||||||
switch entity {
|
switch entity {
|
||||||
case EAGLE(eagle):
|
case EAGLE(eagle):
|
||||||
var item = new EagleItem(eagle);
|
var item = new EagleRenderItem(eagle);
|
||||||
items.set(eagle.id, item);
|
items.set(eagle.id, item);
|
||||||
entryLayer.addChild(item.view);
|
entryLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
case TANK(tank):
|
case TANK(tank):
|
||||||
var item = new TankItem(tank);
|
var item = new TankRenderItem(tank);
|
||||||
items.set(tank.id, item);
|
items.set(tank.id, item);
|
||||||
entryLayer.addChild(item.view);
|
entryLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
playAnimate(tank.rect.center, AnimateBundle.tankSpawn());
|
playAnimate(item.rect.center, AnimateBundle.tankSpawn());
|
||||||
case BULLET(bullet):
|
case BULLET(bullet):
|
||||||
var item = new BulletItem(bullet);
|
var item = new BulletRenderItem(bullet);
|
||||||
items.set(bullet.id, item);
|
items.set(bullet.id, item);
|
||||||
entryLayer.addChild(item.view);
|
entryLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
case BONUS(bonus):
|
case BONUS(bonus):
|
||||||
var item = new BonusItem(bonus);
|
var item = new BonusRenderItem(bonus);
|
||||||
items.set(bonus.id, item);
|
items.set(bonus.id, item);
|
||||||
upperLayer.addChild(item.view);
|
upperLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
@@ -125,25 +127,51 @@ class Render extends SpriteView implements IRender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onCollision(entity:EntityType, with:EntityType):Void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onMove(entity:EntityType):Void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onDestroy(entity:EntityType):Void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
switch event {
|
switch event {
|
||||||
|
case START(_):
|
||||||
|
for (brick in game.engine.map.bricks) {
|
||||||
|
var item:IRenderItem = new BrickRenderItem(brick);
|
||||||
|
items[brick.id] = item;
|
||||||
|
if (brick.config.layer > 2) {
|
||||||
|
upLayer.addChild(item.view);
|
||||||
|
} else {
|
||||||
|
groundLayer.addChild(item.view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||||
|
case COMPLETE(_, _):
|
||||||
|
content.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||||
|
case MOVE(BULLET(id, position)):
|
||||||
|
if (items.exists(id)) {
|
||||||
|
var item = items[id];
|
||||||
|
item.move(position);
|
||||||
|
}
|
||||||
|
case MOVE(TANK(id, position)):
|
||||||
|
if (items.exists(id)) {
|
||||||
|
var item = items[id];
|
||||||
|
item.move(position);
|
||||||
|
cast(item, TankRenderItem).moves = true;
|
||||||
|
}
|
||||||
|
case STOP(TANK(id)):
|
||||||
|
if (items.exists(id)) {
|
||||||
|
var item = items[id];
|
||||||
|
cast(item, TankRenderItem).moves = false;
|
||||||
|
}
|
||||||
|
case CHANGE(TANK(id, type, hits, bonus)):
|
||||||
|
if (items.exists(id)) {
|
||||||
|
var item:TankRenderItem = cast items[id];
|
||||||
|
item.skin = game.config.getTank(type).skin;
|
||||||
|
item.hits = hits;
|
||||||
|
item.bonus = bonus;
|
||||||
|
}
|
||||||
case DESTROY(TANK(id, shot)):
|
case DESTROY(TANK(id, shot)):
|
||||||
if (items.exists(id)) {
|
if (items.exists(id)) {
|
||||||
var item = items[id];
|
var item = items[id];
|
||||||
entryLayer.removeChild(item.view);
|
entryLayer.removeChild(item.view);
|
||||||
var rect:Rectangle = item.value.rect;
|
playAnimate(item.rect.center, AnimateBundle.tankBoom());
|
||||||
playAnimate(rect.center, AnimateBundle.tankBoom());
|
|
||||||
if (shot.score != 0) {
|
if (shot.score != 0) {
|
||||||
showScore(rect.center, shot.score);
|
showScore(item.rect.center, shot.score);
|
||||||
}
|
}
|
||||||
items.remove(id);
|
items.remove(id);
|
||||||
}
|
}
|
||||||
@@ -151,38 +179,35 @@ class Render extends SpriteView implements IRender {
|
|||||||
if (items.exists(id)) {
|
if (items.exists(id)) {
|
||||||
var item = items[id];
|
var item = items[id];
|
||||||
entryLayer.removeChild(item.view);
|
entryLayer.removeChild(item.view);
|
||||||
var rect:Rectangle = item.value.rect;
|
var rect = item.rect;
|
||||||
|
// move boom
|
||||||
var point = rect.center.add(new Point(rect.width * rect.direction.x, rect.height * rect.direction.y));
|
var point = rect.center.add(new Point(rect.width * rect.direction.x, rect.height * rect.direction.y));
|
||||||
playAnimate(point, AnimateBundle.bulletBoom());
|
playAnimate(point, AnimateBundle.bulletBoom());
|
||||||
items.remove(id);
|
items.remove(id);
|
||||||
}
|
}
|
||||||
case DESTROY(BONUS(id, shot)):
|
|
||||||
if (items.exists(id)) {
|
|
||||||
var item = items[id];
|
|
||||||
upperLayer.removeChild(item.view);
|
|
||||||
var rect:Rectangle = item.value.rect;
|
|
||||||
if (shot.score != 0) {
|
|
||||||
showScore(rect.center, shot.score);
|
|
||||||
}
|
|
||||||
items.remove(id);
|
|
||||||
}
|
|
||||||
case DESTROY(EAGLE(id, shot)):
|
case DESTROY(EAGLE(id, shot)):
|
||||||
if (items.exists(id)) {
|
if (items.exists(id)) {
|
||||||
var item = items[id];
|
var item = items[id];
|
||||||
var rect:Rectangle = item.value.rect;
|
playAnimate(item.rect.center, AnimateBundle.tankBoom());
|
||||||
playAnimate(rect.center, AnimateBundle.tankBoom());
|
|
||||||
if (shot.score != 0) {
|
if (shot.score != 0) {
|
||||||
showScore(rect.center, shot.score);
|
showScore(item.rect.center, shot.score);
|
||||||
}
|
}
|
||||||
|
cast(item, EagleRenderItem).death = true;
|
||||||
}
|
}
|
||||||
case MOVE(TANK(id, position)) | MOVE(BULLET(id, position)):
|
case DESTROY(BONUS(id, shot)):
|
||||||
if (items.exists(id)) {
|
if (items.exists(id)) {
|
||||||
var item = items[id];
|
var item = items[id];
|
||||||
item.value.rect.x = position.x;
|
upperLayer.removeChild(item.view);
|
||||||
item.value.rect.y = position.y;
|
if (shot.score != 0) {
|
||||||
item.value.rect.direction = position.direction;
|
showScore(item.rect.center, shot.score);
|
||||||
item.update();
|
}
|
||||||
|
items.remove(id);
|
||||||
}
|
}
|
||||||
|
case DESTROY(CELL(cellX, cellY, shot)):
|
||||||
|
// ToDo: redraw only cell?
|
||||||
|
var brick = game.engine.map.getBrick(new Point(cellX, cellY));
|
||||||
|
var item:BrickRenderItem = cast items[brick.id];
|
||||||
|
item.redraw(brick);
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx
Normal file
34
src/client/haxe/ru/m/tankz/render/item/BitmapRenderItem.hx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
private var bitmapData:BitmapData;
|
||||||
|
private var bitmap:Bitmap;
|
||||||
|
|
||||||
|
public function new(rect:Rectangle) {
|
||||||
|
super(rect);
|
||||||
|
this.bitmap = new Bitmap(null, PixelSnapping.AUTO, true);
|
||||||
|
move(rect.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
override private function get_view():DisplayObject {
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_image(value:String):String {
|
||||||
|
if (image != value) {
|
||||||
|
image = value;
|
||||||
|
bitmapData = Assets.getBitmapData(image);
|
||||||
|
bitmap.bitmapData = bitmapData;
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx
Normal file
22
src/client/haxe/ru/m/tankz/render/item/BonusRenderItem.hx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.Bonus;
|
||||||
|
import ru.m.tankz.Type.BonusType;
|
||||||
|
|
||||||
|
class BonusRenderItem extends BitmapRenderItem {
|
||||||
|
|
||||||
|
public var type(default, set):BonusType;
|
||||||
|
|
||||||
|
public function new(bonus:Bonus) {
|
||||||
|
super(bonus.rect);
|
||||||
|
type = bonus.config.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_type(value:BonusType):BonusType {
|
||||||
|
if (type != value) {
|
||||||
|
type = value;
|
||||||
|
image = 'resources/image/bonus/${type}.png';
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx
Normal file
54
src/client/haxe/ru/m/tankz/render/item/BrickRenderItem.hx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import flash.display.Shape;
|
||||||
|
import openfl.Assets;
|
||||||
|
import openfl.display.DisplayObject;
|
||||||
|
import ru.m.tankz.map.Brick;
|
||||||
|
import ru.m.tankz.Type.BrickType;
|
||||||
|
|
||||||
|
class BrickRenderItem extends RenderItem {
|
||||||
|
|
||||||
|
public var type(default, set):BrickType;
|
||||||
|
|
||||||
|
private var image:BitmapData;
|
||||||
|
private var shape:Shape;
|
||||||
|
|
||||||
|
public function new(brick:Brick) {
|
||||||
|
super(brick.rect);
|
||||||
|
this.shape = new Shape();
|
||||||
|
this.type = brick.config.type;
|
||||||
|
redraw(brick);
|
||||||
|
move(rect.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
override private function get_view():DisplayObject {
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_type(value:BrickType):BrickType {
|
||||||
|
if (type != value) {
|
||||||
|
type = value;
|
||||||
|
image = Assets.getBitmapData('resources/image/map/${type}.png');
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function redraw(brick:Brick):Void {
|
||||||
|
shape.graphics.clear();
|
||||||
|
if (brick.destroyed) return;
|
||||||
|
if (brick.config.index > 0) {
|
||||||
|
shape.graphics.beginBitmapFill(image);
|
||||||
|
if (brick.broken == 0) {
|
||||||
|
shape.graphics.drawRect(0, 0, brick.rect.width, brick.rect.height);
|
||||||
|
} else {
|
||||||
|
for (c in brick.cells) {
|
||||||
|
if (!c.destroyed) {
|
||||||
|
shape.graphics.drawRect(c.rect.x - brick.rect.x, c.rect.y - brick.rect.y, c.rect.width, c.rect.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shape.graphics.endFill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx
Normal file
21
src/client/haxe/ru/m/tankz/render/item/BulletRenderItem.hx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.Bullet;
|
||||||
|
|
||||||
|
class BulletRenderItem extends BitmapRenderItem {
|
||||||
|
public var piercing(default, set):Int = -1;
|
||||||
|
|
||||||
|
public function new(bullet:Bullet) {
|
||||||
|
super(bullet.rect);
|
||||||
|
piercing = bullet.config.piercing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_piercing(value:Int):Int {
|
||||||
|
if (piercing != value) {
|
||||||
|
piercing = value;
|
||||||
|
var type = piercing > 0 ? 'piercing' : 'normal';
|
||||||
|
image = 'resources/image/bullet/${type}.png';
|
||||||
|
}
|
||||||
|
return piercing;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx
Normal file
21
src/client/haxe/ru/m/tankz/render/item/EagleRenderItem.hx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.Eagle;
|
||||||
|
|
||||||
|
class EagleRenderItem extends BitmapRenderItem {
|
||||||
|
public var death(default, set):Bool = true;
|
||||||
|
|
||||||
|
public function new(eagle:Eagle) {
|
||||||
|
super(eagle.rect);
|
||||||
|
death = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_death(value:Bool):Bool {
|
||||||
|
if (death != value) {
|
||||||
|
death = value;
|
||||||
|
var suffix = death ? '-death' : '';
|
||||||
|
image = 'resources/image/eagle/eagle${suffix}.png';
|
||||||
|
}
|
||||||
|
return death;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/client/haxe/ru/m/tankz/render/item/IRenderItem.hx
Normal file
13
src/client/haxe/ru/m/tankz/render/item/IRenderItem.hx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import ru.m.geom.Position;
|
||||||
|
import ru.m.geom.Rectangle;
|
||||||
|
|
||||||
|
interface IRenderItem {
|
||||||
|
public var view(get, null):DisplayObject;
|
||||||
|
public var rect(default, null):Rectangle;
|
||||||
|
public function move(position:Position):Void;
|
||||||
|
public function update():Void;
|
||||||
|
public function dispose():Void;
|
||||||
|
}
|
||||||
35
src/client/haxe/ru/m/tankz/render/item/RenderItem.hx
Normal file
35
src/client/haxe/ru/m/tankz/render/item/RenderItem.hx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
|
import ru.m.geom.Position;
|
||||||
|
import ru.m.geom.Rectangle;
|
||||||
|
|
||||||
|
class RenderItem implements IRenderItem {
|
||||||
|
|
||||||
|
public var view(get, null):DisplayObject;
|
||||||
|
|
||||||
|
public var rect(default, null):Rectangle;
|
||||||
|
|
||||||
|
public function new(rect:Rectangle) {
|
||||||
|
this.rect = rect.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get_view():DisplayObject {
|
||||||
|
throw "Not Implemented";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function move(position:Position):Void {
|
||||||
|
view.x = rect.x = position.x;
|
||||||
|
view.y = rect.y = position.y;
|
||||||
|
if (position.direction != null) {
|
||||||
|
rect.direction = position.direction;
|
||||||
|
view.rotation = rect.direction.angle;
|
||||||
|
view.x = rect.x - rect.width * (rect.direction.x + 1) / 2 + rect.width * (rect.direction.y + 1) / 2 + 0.5 * rect.width;
|
||||||
|
view.y = rect.y - rect.height * (rect.direction.x + 1) / 2 - rect.height * (rect.direction.y + 1) / 2 + 1.5 * rect.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update():Void {}
|
||||||
|
|
||||||
|
public function dispose():Void {}
|
||||||
|
}
|
||||||
97
src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx
Normal file
97
src/client/haxe/ru/m/tankz/render/item/TankRenderItem.hx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import haxework.color.Color;
|
||||||
|
import haxework.view.utils.BitmapUtil;
|
||||||
|
import openfl.Assets;
|
||||||
|
import ru.m.tankz.core.Tank;
|
||||||
|
|
||||||
|
class TankRenderItem extends BitmapRenderItem {
|
||||||
|
public var color(default, default):Color;
|
||||||
|
public var skin(default, set):String;
|
||||||
|
public var hits(default, set):Int;
|
||||||
|
public var bonus(default, set):Bool;
|
||||||
|
public var moves(default, set):Bool;
|
||||||
|
|
||||||
|
private var images:Array<BitmapData>;
|
||||||
|
private var frame:Int;
|
||||||
|
|
||||||
|
public function new(tank:Tank) {
|
||||||
|
super(tank.rect);
|
||||||
|
color = tank.color;
|
||||||
|
skin = tank.config.skin;
|
||||||
|
hits = tank.hits;
|
||||||
|
bonus = tank.bonus;
|
||||||
|
move(rect.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 color1:Color = switch hits {
|
||||||
|
case 1: 0x869C43;
|
||||||
|
case 2: 0xDEAF80;
|
||||||
|
case 3: 0x5EA67A;
|
||||||
|
case _: color;
|
||||||
|
}
|
||||||
|
var color2:Color = color1;
|
||||||
|
if (bonus) {
|
||||||
|
color1 = 0xff00aa;
|
||||||
|
}
|
||||||
|
if (!color1.zero) {
|
||||||
|
image1 = BitmapUtil.colorize(image1, color1);
|
||||||
|
}
|
||||||
|
if (!color1.zero) {
|
||||||
|
image2 = BitmapUtil.colorize(image2, color2);
|
||||||
|
}
|
||||||
|
images = [
|
||||||
|
image1, image1, image1,
|
||||||
|
image2, image2, image2,
|
||||||
|
];
|
||||||
|
frame = 0;
|
||||||
|
bitmap.bitmapData = images[frame];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_skin(value:String):String {
|
||||||
|
if (skin != value) {
|
||||||
|
skin = value;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_hits(value:Int):Int {
|
||||||
|
if (hits != value) {
|
||||||
|
hits = value;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
return hits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_bonus(value:Bool):Bool {
|
||||||
|
if (bonus != value) {
|
||||||
|
bonus = value;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
return bonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_moves(value:Bool):Bool {
|
||||||
|
if (moves != value) {
|
||||||
|
moves = value;
|
||||||
|
bitmap.bitmapData = images[0];
|
||||||
|
}
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function update():Void {
|
||||||
|
super.update();
|
||||||
|
if (moves) {
|
||||||
|
frame++;
|
||||||
|
if (frame > images.length - 1) {
|
||||||
|
frame = 0;
|
||||||
|
}
|
||||||
|
bitmap.bitmapData = images[frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,14 +14,22 @@ import ru.m.tankz.game.record.GameRecord;
|
|||||||
|
|
||||||
public function save(record:GameRecord):Void {
|
public function save(record:GameRecord):Void {
|
||||||
L.d("RecordStorage", 'save $record');
|
L.d("RecordStorage", 'save $record');
|
||||||
write(record.id, record);
|
write('${record.info.id}.info', record.info);
|
||||||
|
write(record.info.id, record);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function iterator():Iterator<GameRecord> {
|
override public function delete(id:String):Void {
|
||||||
|
super.delete(id);
|
||||||
|
super.delete('${id}.info');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function iterator():Iterator<GameRecordInfo> {
|
||||||
var data:DynamicAccess<String> = so.data;
|
var data:DynamicAccess<String> = so.data;
|
||||||
for (id in data.keys()) {
|
for (id in data.keys()) {
|
||||||
try {
|
try {
|
||||||
@yield return read(id);
|
if (StringTools.endsWith(id, '.info')) {
|
||||||
|
@yield return read(id);
|
||||||
|
}
|
||||||
} catch (error:Dynamic) {
|
} catch (error:Dynamic) {
|
||||||
L.w("RecordStorage", 'read ', error);
|
L.w("RecordStorage", 'read ', error);
|
||||||
delete(id);
|
delete(id);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package ru.m.tankz.view;
|
package ru.m.tankz.view;
|
||||||
|
|
||||||
import flash.events.Event;
|
|
||||||
import haxe.ds.Option;
|
import haxe.ds.Option;
|
||||||
import haxework.view.frame.FrameSwitcher;
|
import haxework.view.frame.FrameSwitcher;
|
||||||
import haxework.view.VGroupView;
|
import haxework.view.VGroupView;
|
||||||
@@ -51,8 +50,7 @@ import ru.m.tankz.view.game.GameView;
|
|||||||
private function start(state:GameState):Void {
|
private function start(state:GameState):Void {
|
||||||
gameView.type = state.type;
|
gameView.type = state.type;
|
||||||
game = new Game(state);
|
game = new Game(state);
|
||||||
game.connect(gameView.render);
|
gameView.render.game = game;
|
||||||
game.engine.connect(gameView.render);
|
|
||||||
game.connect(soundManager);
|
game.connect(soundManager);
|
||||||
game.connect(this);
|
game.connect(this);
|
||||||
if (gameView.panel != null) {
|
if (gameView.panel != null) {
|
||||||
@@ -63,15 +61,13 @@ import ru.m.tankz.view.game.GameView;
|
|||||||
game.connect(recorder);
|
game.connect(recorder);
|
||||||
runner = new GameRunner(game);
|
runner = new GameRunner(game);
|
||||||
runner.start(state);
|
runner.start(state);
|
||||||
content.addEventListener(Event.ENTER_FRAME, _redraw);
|
gameView.render.draw();
|
||||||
gameView.render.draw(game.engine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function play(record:GameRecord):Void {
|
private function play(record:GameRecord):Void {
|
||||||
gameView.type = record.type;
|
gameView.type = record.info.type;
|
||||||
game = new Game(record.state);
|
game = new Game(record.state);
|
||||||
game.connect(gameView.render);
|
gameView.render.game = game;
|
||||||
game.engine.connect(gameView.render);
|
|
||||||
game.connect(soundManager);
|
game.connect(soundManager);
|
||||||
//game.connect(this);
|
//game.connect(this);
|
||||||
if (gameView.panel != null) {
|
if (gameView.panel != null) {
|
||||||
@@ -79,12 +75,10 @@ import ru.m.tankz.view.game.GameView;
|
|||||||
}
|
}
|
||||||
player = new GamePlayer(game, record);
|
player = new GamePlayer(game, record);
|
||||||
player.start();
|
player.start();
|
||||||
content.addEventListener(Event.ENTER_FRAME, _redraw);
|
gameView.render.draw();
|
||||||
gameView.render.draw(game.engine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function stop():Void {
|
private function stop():Void {
|
||||||
content.removeEventListener(Event.ENTER_FRAME, _redraw);
|
|
||||||
if (runner != null) {
|
if (runner != null) {
|
||||||
runner.dispose();
|
runner.dispose();
|
||||||
runner = null;
|
runner = null;
|
||||||
@@ -122,10 +116,6 @@ import ru.m.tankz.view.game.GameView;
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _redraw(_):Void {
|
|
||||||
gameView.render.draw(game.engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function close():Void {
|
public function close():Void {
|
||||||
switcher.change(LevelFrame.ID);
|
switcher.change(LevelFrame.ID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import ru.m.tankz.storage.RecordStorage;
|
|||||||
@:template class RecordFrame extends VGroupView {
|
@:template class RecordFrame extends VGroupView {
|
||||||
public static var ID(default, never):String = "record";
|
public static var ID(default, never):String = "record";
|
||||||
|
|
||||||
@:view var data:VListView<GameRecord>;
|
@:view var data:VListView<GameRecordInfo>;
|
||||||
|
|
||||||
@:provide var recordStorage:RecordStorage;
|
@:provide var recordStorage:RecordStorage;
|
||||||
@:provide var switcher:FrameSwitcher;
|
@:provide var switcher:FrameSwitcher;
|
||||||
@@ -18,13 +18,12 @@ import ru.m.tankz.storage.RecordStorage;
|
|||||||
|
|
||||||
public function onShow():Void {
|
public function onShow():Void {
|
||||||
var data = Lambda.array(recordStorage);
|
var data = Lambda.array(recordStorage);
|
||||||
data.sort(function(a:GameRecord, b:GameRecord) return Std.int(b.date.getTime() - a.date.getTime()));
|
data.sort(function(a:GameRecordInfo, b:GameRecordInfo) return Std.int(b.date.getTime() - a.date.getTime()));
|
||||||
this.data.data = data;
|
this.data.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function onRecordSelect(item:IListItemView<GameRecord>):Void {
|
private function onRecordSelect(item:IListItemView<GameRecordInfo>):Void {
|
||||||
//record = item.data;
|
|
||||||
//switcher.change(GameFrame.ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function close() {
|
private function close() {
|
||||||
|
|||||||
@@ -7,20 +7,20 @@ import haxework.view.list.ListView;
|
|||||||
import ru.m.tankz.game.record.GameRecord;
|
import ru.m.tankz.game.record.GameRecord;
|
||||||
import ru.m.tankz.storage.RecordStorage;
|
import ru.m.tankz.storage.RecordStorage;
|
||||||
|
|
||||||
@:template class RecordView extends HGroupView implements IListItemView<GameRecord> {
|
@:template class RecordView extends HGroupView implements IListItemView<GameRecordInfo> {
|
||||||
@:view var date:LabelView;
|
@:view var date:LabelView;
|
||||||
@:view var type:LabelView;
|
@:view var type:LabelView;
|
||||||
@:view var level:LabelView;
|
@:view var level:LabelView;
|
||||||
@:view var preset:LabelView;
|
@:view var preset:LabelView;
|
||||||
|
|
||||||
public var item_index(default, default):Int;
|
public var item_index(default, default):Int;
|
||||||
public var data(default, set):GameRecord;
|
public var data(default, set):GameRecordInfo;
|
||||||
|
|
||||||
@:provide var recordStorage:RecordStorage;
|
@:provide var recordStorage:RecordStorage;
|
||||||
@:provide var switcher:FrameSwitcher;
|
@:provide var switcher:FrameSwitcher;
|
||||||
@:provide var record:GameRecord;
|
@:provide var record:GameRecord;
|
||||||
|
|
||||||
private function set_data(value:GameRecord):GameRecord {
|
private function set_data(value:GameRecordInfo):GameRecordInfo {
|
||||||
if (data != value) {
|
if (data != value) {
|
||||||
data = value;
|
data = value;
|
||||||
date.text = data.date.toString();
|
date.text = data.date.toString();
|
||||||
@@ -32,7 +32,7 @@ import ru.m.tankz.storage.RecordStorage;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function play():Void {
|
private function play():Void {
|
||||||
record = data;
|
record = recordStorage.read(data.id);
|
||||||
switcher.change(GameFrame.ID);
|
switcher.change(GameFrame.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
src/common/haxe/ru/m/geom/Position.hx
Normal file
7
src/common/haxe/ru/m/geom/Position.hx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.m.geom;
|
||||||
|
|
||||||
|
typedef Position = {
|
||||||
|
var x:Float;
|
||||||
|
var y:Float;
|
||||||
|
@:optional var direction:Direction;
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ class Rectangle {
|
|||||||
public var right(get, null):Float;
|
public var right(get, null):Float;
|
||||||
public var top(get, null):Float;
|
public var top(get, null):Float;
|
||||||
public var bottom(get, null):Float;
|
public var bottom(get, null):Float;
|
||||||
|
public var position(get, null):Position;
|
||||||
|
|
||||||
public function new(x:Float, y:Float, width:Float, height:Float) {
|
public function new(x:Float, y:Float, width:Float, height:Float) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
@@ -58,7 +59,7 @@ class Rectangle {
|
|||||||
}
|
}
|
||||||
direction = value;
|
direction = value;
|
||||||
}
|
}
|
||||||
return value;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contain(point:Point):Bool {
|
public function contain(point:Point):Bool {
|
||||||
@@ -85,6 +86,12 @@ class Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function clone():Rectangle {
|
||||||
|
var rect = new Rectangle(x, y, width, height);
|
||||||
|
rect.direction = direction;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
public function toString():String {
|
public function toString():String {
|
||||||
return 'Rectangle{x=$x,y=$y,width=$width,height=$height}';
|
return 'Rectangle{x=$x,y=$y,width=$width,height=$height}';
|
||||||
}
|
}
|
||||||
@@ -104,4 +111,8 @@ class Rectangle {
|
|||||||
function get_bottom():Float {
|
function get_bottom():Float {
|
||||||
return y + height;
|
return y + height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function get_position():Position {
|
||||||
|
return {x:x, y:y, direction:direction};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ import ru.m.tankz.map.LevelMap;
|
|||||||
var collision:Bool = false;
|
var collision:Bool = false;
|
||||||
for (cell in cells) {
|
for (cell in cells) {
|
||||||
if (cell.getCollision(entity.layer)) {
|
if (cell.getCollision(entity.layer)) {
|
||||||
entity.rect.lean(cell.rect);
|
|
||||||
collision = true;
|
collision = true;
|
||||||
var with = EntityTypeResolver.of(cell);
|
var with = EntityTypeResolver.of(cell);
|
||||||
collisionSignal.emit(entityType, with);
|
collisionSignal.emit(entityType, with);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.m.tankz.game;
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
|
import ru.m.geom.Position;
|
||||||
import ru.m.tankz.bundle.IConfigBundle;
|
import ru.m.tankz.bundle.IConfigBundle;
|
||||||
import ru.m.tankz.config.Config;
|
import ru.m.tankz.config.Config;
|
||||||
import ru.m.tankz.control.Control;
|
import ru.m.tankz.control.Control;
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
package ru.m.tankz.game;
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
import ru.m.geom.Direction;
|
import ru.m.geom.Position;
|
||||||
import ru.m.tankz.control.Control;
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
|
|
||||||
typedef Position = {
|
|
||||||
var x:Float;
|
|
||||||
var y:Float;
|
|
||||||
@:optional var direction:Direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SpawnEvent {
|
enum SpawnEvent {
|
||||||
EAGLE(id:Int, position:Position, teamId:TeamId);
|
EAGLE(id:Int, position:Position, teamId:TeamId);
|
||||||
TANK(id:Int, position:Position, playerId:PlayerId, type:TankType);
|
TANK(id:Int, position:Position, playerId:PlayerId, type:TankType);
|
||||||
@@ -41,7 +35,12 @@ enum MoveEvent {
|
|||||||
BULLET(id:Int, position:Position);
|
BULLET(id:Int, position:Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum StopEvent {
|
||||||
|
TANK(id:Int);
|
||||||
|
}
|
||||||
|
|
||||||
enum ChangeEvent {
|
enum ChangeEvent {
|
||||||
|
TANK(id:Int, type:TankType, hits:Int, bonus:Bool);
|
||||||
PLAYER_SCORE(playerId:PlayerId, value:Int);
|
PLAYER_SCORE(playerId:PlayerId, value:Int);
|
||||||
PLAYER_LIFE(playerId:PlayerId, value:Int);
|
PLAYER_LIFE(playerId:PlayerId, value:Int);
|
||||||
TEAM_SCORE(teamId:TeamId, value:Int);
|
TEAM_SCORE(teamId:TeamId, value:Int);
|
||||||
@@ -52,6 +51,7 @@ enum GameEvent {
|
|||||||
START(state:GameState);
|
START(state:GameState);
|
||||||
SPAWN(event:SpawnEvent);
|
SPAWN(event:SpawnEvent);
|
||||||
MOVE(event:MoveEvent);
|
MOVE(event:MoveEvent);
|
||||||
|
STOP(event:StopEvent);
|
||||||
HIT(event:HitEvent);
|
HIT(event:HitEvent);
|
||||||
DESTROY(event:DestroyEvent);
|
DESTROY(event:DestroyEvent);
|
||||||
CHANGE(event:ChangeEvent);
|
CHANGE(event:ChangeEvent);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package ru.m.tankz.game;
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
|
import ru.m.geom.Direction;
|
||||||
import haxe.ds.Option;
|
import haxe.ds.Option;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
import haxework.signal.Signal;
|
import haxework.signal.Signal;
|
||||||
import ru.m.geom.Line;
|
import ru.m.geom.Line;
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
|
import ru.m.geom.Position;
|
||||||
import ru.m.tankz.control.Control;
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.tankz.control.Controller;
|
import ru.m.tankz.control.Controller;
|
||||||
import ru.m.tankz.control.IControlFactory;
|
import ru.m.tankz.control.IControlFactory;
|
||||||
@@ -55,7 +57,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
return {
|
return {
|
||||||
x: (point.x + 1) * game.config.map.cellWidth,
|
x: (point.x + 1) * game.config.map.cellWidth,
|
||||||
y: (point.y + 1) * game.config.map.cellHeight,
|
y: (point.y + 1) * game.config.map.cellHeight,
|
||||||
direction: point.direction,
|
direction: Direction.fromString(point.direction),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +143,14 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline function emitTankMove(tank:Tank):Void {
|
||||||
|
gameEventSignal.emit(GameEvent.MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline function emitTankChange(tank:Tank):Void {
|
||||||
|
gameEventSignal.emit(GameEvent.CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus)));
|
||||||
|
}
|
||||||
|
|
||||||
public function onCollision(entity:EntityType, with:EntityType):Void {
|
public function onCollision(entity:EntityType, with:EntityType):Void {
|
||||||
switch entity {
|
switch entity {
|
||||||
case EntityType.TANK(tank):
|
case EntityType.TANK(tank):
|
||||||
@@ -151,8 +161,13 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
switch [entity, with] {
|
switch [entity, with] {
|
||||||
case [TANK(tank), TANK(other_tank)]:
|
case [TANK(tank), TANK(other_tank)]:
|
||||||
tank.rect.lean(other_tank.rect);
|
tank.rect.lean(other_tank.rect);
|
||||||
|
emitTankMove(tank);
|
||||||
case [TANK(tank), EAGLE(eagle)]:
|
case [TANK(tank), EAGLE(eagle)]:
|
||||||
tank.rect.lean(eagle.rect);
|
tank.rect.lean(eagle.rect);
|
||||||
|
emitTankMove(tank);
|
||||||
|
case [TANK(tank), CELL(cell)]:
|
||||||
|
tank.rect.lean(cell.rect);
|
||||||
|
emitTankMove(tank);
|
||||||
case [BULLET(bullet), BULLET(other_bullet)]:
|
case [BULLET(bullet), BULLET(other_bullet)]:
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet.id)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet.id)));
|
||||||
@@ -173,9 +188,11 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
spawnBonus();
|
spawnBonus();
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||||
|
emitTankChange(tank);
|
||||||
} else if (tank.config.downgrade != null) {
|
} else if (tank.config.downgrade != null) {
|
||||||
tank.config = game.config.getTank(tank.config.downgrade);
|
tank.config = game.config.getTank(tank.config.downgrade);
|
||||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||||
|
emitTankChange(tank);
|
||||||
} else {
|
} else {
|
||||||
var score = tank.config.score;
|
var score = tank.config.score;
|
||||||
if (tank.playerId.team == bullet.playerId.team) {
|
if (tank.playerId.team == bullet.playerId.team) {
|
||||||
@@ -198,7 +215,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
public function onMove(entity:EntityType):Void {
|
public function onMove(entity:EntityType):Void {
|
||||||
switch entity {
|
switch entity {
|
||||||
case TANK(tank):
|
case TANK(tank):
|
||||||
gameEventSignal.emit(GameEvent.MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
|
emitTankMove(tank);
|
||||||
case BULLET(bullet):
|
case BULLET(bullet):
|
||||||
gameEventSignal.emit(GameEvent.MOVE(BULLET(bullet.id, {x:bullet.rect.x, y:bullet.rect.y, direction:bullet.rect.direction})));
|
gameEventSignal.emit(GameEvent.MOVE(BULLET(bullet.id, {x:bullet.rect.x, y:bullet.rect.y, direction:bullet.rect.direction})));
|
||||||
case _:
|
case _:
|
||||||
@@ -237,6 +254,8 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
case "clock":
|
case "clock":
|
||||||
for (t in game.engine.iterTanks(alienTank(tank.playerId.team))) {
|
for (t in game.engine.iterTanks(alienTank(tank.playerId.team))) {
|
||||||
t.freezing.on(bonus.config.duration);
|
t.freezing.on(bonus.config.duration);
|
||||||
|
t.stop();
|
||||||
|
gameEventSignal.emit(GameEvent.STOP(TANK(t.id)));
|
||||||
}
|
}
|
||||||
case "shovel":
|
case "shovel":
|
||||||
// ToDo: protect eagle/area
|
// ToDo: protect eagle/area
|
||||||
@@ -260,6 +279,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
} else {
|
} else {
|
||||||
tank.hits++;
|
tank.hits++;
|
||||||
}
|
}
|
||||||
|
emitTankChange(tank);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function changeScore(playerId:PlayerId, score:Int):Void {
|
private function changeScore(playerId:PlayerId, score:Int):Void {
|
||||||
@@ -305,6 +325,8 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.SPAWN(BULLET(++entityId, position, tank.playerId)));
|
gameEventSignal.emit(GameEvent.SPAWN(BULLET(++entityId, position, tank.playerId)));
|
||||||
}
|
}
|
||||||
|
case GameEvent.ACTION(tankId, STOP):
|
||||||
|
gameEventSignal.emit(GameEvent.STOP(TANK(tankId)));
|
||||||
case GameEvent.SPAWN(TANK(_, _, playerId, _)):
|
case GameEvent.SPAWN(TANK(_, _, playerId, _)):
|
||||||
game.getPlayer(playerId).control.start();
|
game.getPlayer(playerId).control.start();
|
||||||
case GameEvent.SPAWN(BULLET(_, _, playerId)):
|
case GameEvent.SPAWN(BULLET(_, _, playerId)):
|
||||||
@@ -361,7 +383,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
if (cell.armor == bullet.config.piercing) {
|
if (cell.armor == bullet.config.piercing) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||||
} else if (cell.armor < bullet.config.piercing) {
|
} else if (cell.armor < bullet.config.piercing) {
|
||||||
var brick = game.engine.map.getBrick(cell);
|
var brick = game.engine.map.getBrick(cell.position);
|
||||||
for (cell in brick.cells) {
|
for (cell in brick.cells) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,27 +9,33 @@ typedef EventItem = {
|
|||||||
event:GameEvent
|
event:GameEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameRecord {
|
class GameRecordInfo {
|
||||||
public var id(default, default):String;
|
public var id(default, default):String;
|
||||||
public var date(default, default):Date;
|
public var date(default, default):Date;
|
||||||
public var type(default, default):GameType;
|
public var type(default, default):GameType;
|
||||||
public var presetId(default, default):PresetId;
|
public var presetId(default, default):PresetId;
|
||||||
public var levelId(default, default):LevelId;
|
public var levelId(default, default):LevelId;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GameRecord {
|
||||||
|
public var info(default, null):GameRecordInfo;
|
||||||
public var events(default, default):Array<EventItem>;
|
public var events(default, default):Array<EventItem>;
|
||||||
|
|
||||||
public var state(get, null):GameState;
|
public var state(get, null):GameState;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
this.id = UUID.generateRandom(new Random()).toString();
|
this.info = new GameRecordInfo();
|
||||||
this.date = null;
|
this.info.id = UUID.generateRandom(new Random()).toString();
|
||||||
this.events = [];
|
this.events = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline function get_state():GameState {
|
private inline function get_state():GameState {
|
||||||
return new GameState(type, presetId, levelId);
|
return new GameState(info.type, info.presetId, info.levelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toString():String {
|
public function toString():String {
|
||||||
return 'GameRecord{id=$id,date=$date,type=$type,preset=$presetId,level=$levelId,events=${events.length}}';
|
return 'GameRecord{id=${info.id},date=${info.date},type=${info.type},preset=${info.presetId},level=${info.levelId},events=${events.length}}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ class GameRecorder implements GameListener {
|
|||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
switch event {
|
switch event {
|
||||||
case GameEvent.START(state):
|
case GameEvent.START(state):
|
||||||
record.type = state.type;
|
record.info.type = state.type;
|
||||||
record.presetId = state.presetId;
|
record.info.presetId = state.presetId;
|
||||||
record.levelId = state.levelId;
|
record.info.levelId = state.levelId;
|
||||||
start();
|
start();
|
||||||
case GameEvent.COMPLETE(_, _):
|
case GameEvent.COMPLETE(_, _):
|
||||||
stop();
|
stop();
|
||||||
@@ -30,7 +30,7 @@ class GameRecorder implements GameListener {
|
|||||||
|
|
||||||
public function start():Void {
|
public function start():Void {
|
||||||
frame = 0;
|
frame = 0;
|
||||||
record.date = Date.now();
|
record.info.date = Date.now();
|
||||||
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ class LevelMap {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBrick(cell:GridCell):Brick {
|
public function getBrick(position:Point):Brick {
|
||||||
return bricksMap.get(cell.position);
|
return bricksMap.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPointBrick(point:Point):Brick {
|
public function getPointBrick(point:Point):Brick {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ presets:
|
|||||||
- {<<: *team_human}
|
- {<<: *team_human}
|
||||||
- id: bot
|
- id: bot
|
||||||
spawnInterval: 3000
|
spawnInterval: 3000
|
||||||
life: 1
|
life: 10
|
||||||
players:
|
players:
|
||||||
- {<<: *bot, index: 0, control: bot-stupid}
|
- {<<: *bot, index: 0, control: bot-stupid}
|
||||||
- {<<: *bot, index: 1, control: bot-stupid}
|
- {<<: *bot, index: 1, control: bot-stupid}
|
||||||
|
|||||||
Reference in New Issue
Block a user