From 6f338584eb59013f102fc5d4c5294e6a2301ef12 Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 1 Feb 2018 00:05:14 +0300 Subject: [PATCH] [render] added animates --- package.json | 2 +- project.xml | 1 + src/client/haxe/ru/m/animate/Animate.hx | 62 +++++++++++++++ src/client/haxe/ru/m/animate/OnceAnimate.hx | 31 ++++++++ src/client/haxe/ru/m/tankz/render/Render.hx | 47 ++++++++++- .../haxe/ru/m/tankz/render/RenderItem.hx | 77 ++++++++++++------- 6 files changed, 191 insertions(+), 29 deletions(-) create mode 100644 src/client/haxe/ru/m/animate/Animate.hx create mode 100644 src/client/haxe/ru/m/animate/OnceAnimate.hx diff --git a/package.json b/package.json index acb1743..c2d66c0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.2.1", + "version": "0.2.2", "private": true, "devDependencies": { "ansi-colors": "^1.0.1", diff --git a/project.xml b/project.xml index 66938b0..0536f4c 100755 --- a/project.xml +++ b/project.xml @@ -12,6 +12,7 @@ + diff --git a/src/client/haxe/ru/m/animate/Animate.hx b/src/client/haxe/ru/m/animate/Animate.hx new file mode 100644 index 0000000..7dc5bf4 --- /dev/null +++ b/src/client/haxe/ru/m/animate/Animate.hx @@ -0,0 +1,62 @@ +package ru.m.animate; + +import flash.display.PixelSnapping; +import haxe.Timer; +import flash.display.Bitmap; +import flash.display.BitmapData; + + +class Animate extends Bitmap { + + private static var timer:Timer; + private static var instances:Array = []; + + private static function init():Void { + if (timer == null) { + timer = new Timer(30); + timer.run = updateAll; + } + } + + private static function updateAll():Void { + for (instance in instances) { + if (instance.playing) { + instance.update(); + } + } + } + + public var playing(default, set):Bool; + private var frames:Array; + private var index:Int; + + public function new(frames:Array) { + super(frames[0], PixelSnapping.AUTO, true); + this.frames = frames; + init(); + instances.push(this); + } + + public function set_playing(value:Bool):Bool { + if (playing != value) { + playing = value; + } + return playing; + } + + private function update():Void { + if (++index >= frames.length) { + index = 0; + } + var nextBitmapData = frames[index]; + x -= (nextBitmapData.width - bitmapData.width) / 2; + y -= (nextBitmapData.height - bitmapData.height) / 2; + bitmapData = nextBitmapData; + } + + public function dispose():Void { + if (instances.indexOf(this) > -1) { + instances.remove(this); + } + } +} diff --git a/src/client/haxe/ru/m/animate/OnceAnimate.hx b/src/client/haxe/ru/m/animate/OnceAnimate.hx new file mode 100644 index 0000000..0d7b8c3 --- /dev/null +++ b/src/client/haxe/ru/m/animate/OnceAnimate.hx @@ -0,0 +1,31 @@ +package ru.m.animate; + +import promhx.Deferred; +import flash.display.BitmapData; +import promhx.Promise; + + +class OnceAnimate extends Animate { + + private var deferred:Deferred; + + public function new(frames:Array) { + super(frames); + } + + public function play():Promise { + deferred = new Deferred(); + playing = true; + return deferred.promise(); + } + + override private function update():Void { + super.update(); + if (index == 0) { + playing = false; + if (deferred != null) { + deferred.resolve(this); + } + } + } +} diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index bdc16ae..9171d12 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -1,5 +1,8 @@ package ru.m.tankz.render; +import ru.m.geom.Point; +import openfl.Assets; +import ru.m.animate.OnceAnimate; import flash.display.DisplayObjectContainer; import ru.m.tankz.core.EntityType; import flash.display.DisplayObject; @@ -19,20 +22,24 @@ class Render extends SpriteView implements EngineListener { private var groundLayer:Sprite; private var entryLayer:Sprite; private var upLayer:Sprite; + private var upperLayer:Sprite; private var background:Sprite; - private var items:Map>; + private var items:Map>; public function new() { super(); + items = new Map(); backgroundLayer = new Sprite(); groundLayer = new Sprite(); entryLayer = new Sprite(); upLayer = new Sprite(); + upperLayer = new Sprite(); contentAsSprite.addChild(backgroundLayer); contentAsSprite.addChild(groundLayer); contentAsSprite.addChild(entryLayer); contentAsSprite.addChild(upLayer); + contentAsSprite.addChild(upperLayer); reset(); } @@ -74,7 +81,10 @@ class Render extends SpriteView implements EngineListener { } public function reset():Void { - items = new Map>(); + for (item in items.iterator()) { + item.dispose(); + } + items = new Map(); if (background != null) { backgroundLayer.removeChild(background); background = null; @@ -115,18 +125,51 @@ class Render extends SpriteView implements EngineListener { if (items.exists(tank.key)) { entryLayer.removeChild(items.get(tank.key).view); items.remove(tank.key); + playTankBoom(tank.rect.center); } case EntityType.BULLET(bullet): if (items.exists(bullet.key)) { entryLayer.removeChild(items.get(bullet.key).view); items.remove(bullet.key); + playBulletBoom(bullet.rect.center); } case EntityType.EAGLE(eagle): if (items.exists(eagle.key)) { cast(items.get(eagle.key), EagleItem).destoyed = true; items.get(eagle.key).redraw(); + playTankBoom(eagle.rect.center); } case _: } } + + private function playBulletBoom(point:Point):Void { + var arr = [ + 0, 1, 1, 0, 0, 1 + ]; + var frames = [for (i in arr) Assets.getBitmapData('resources/images/bullet/boom/boom-${i}.png')]; + var animate = new OnceAnimate(frames); + animate.x = point.x - animate.width / 2; + animate.y = point.y - animate.height / 2; + upperLayer.addChild(animate); + animate.play().then(function(animate) { + upperLayer.removeChild(animate); + animate.dispose(); + }); + } + + private function playTankBoom(point:Point):Void { + var arr = [ + 0, 1, 2, 3, 4, 4, 4, 1, 4, 4, 7, 7, 8, 9, 9 + ]; + var frames = [for (i in arr) Assets.getBitmapData('resources/images/tank/kaboom/kaboom-${i}.png')]; + var animate = new OnceAnimate(frames); + animate.x = point.x - animate.width / 2; + animate.y = point.y - animate.height / 2; + upperLayer.addChild(animate); + animate.play().then(function(animate) { + upperLayer.removeChild(animate); + animate.dispose(); + }); + } } diff --git a/src/client/haxe/ru/m/tankz/render/RenderItem.hx b/src/client/haxe/ru/m/tankz/render/RenderItem.hx index c51892b..de4b3ca 100644 --- a/src/client/haxe/ru/m/tankz/render/RenderItem.hx +++ b/src/client/haxe/ru/m/tankz/render/RenderItem.hx @@ -1,5 +1,6 @@ package ru.m.tankz.render; +import ru.m.animate.Animate; import ru.m.tankz.core.Eagle; import flash.display.DisplayObject; import flash.display.Shape; @@ -17,23 +18,17 @@ typedef TRectangle = { } -class RenderItem { +class RenderItem { public var value(default, null):T; - public var view(default, null):DisplayObject; - - private var bitmap:Bitmap; + public var view(default, null):D; public function new(value:T) { this.value = value; - this.bitmap = new Bitmap(); - this.view = bitmap; - redraw(); + this.view = null; } - public function redraw():Void { - bitmap.bitmapData = Assets.getBitmapData(getImage()); - } + public function redraw():Void {} public function update():Void { var rect = value.rect; @@ -42,10 +37,6 @@ class RenderItem { view.y = rect.y - rect.height * (rect.direction.x + 1) / 2 - rect.height * (rect.direction.y + 1) / 2 + 1.5 * rect.height; } - private function getImage():String { - return 'ERROR'; - } - private static function calcRotate(direction:Direction):Float { return (if (direction == Direction.RIGHT) { 0; @@ -59,23 +50,42 @@ class RenderItem { 0; }); } + + public function dispose():Void {} } -class BrickItem extends RenderItem { +class BitmapItem extends RenderItem { + + public function new(value:T) { + super(value); + this.view = new Bitmap(); + redraw(); + } + + override public function redraw():Void { + view.bitmapData = Assets.getBitmapData(getImage()); + } + + private function getImage():String { + return 'ERROR'; + } +} + + +class BrickItem extends RenderItem { - private var shape:Shape; private var broken:Int; public function new(value:Brick) { - this.shape = new Shape(); super(value); - this.view = shape; + this.view = new Shape(); + redraw(); } override public function redraw():Void { var image = Assets.getBitmapData(getImage()); - var g = shape.graphics; + var g = view.graphics; g.clear(); if (value.destroyed) return; g.beginBitmapFill(image); @@ -98,18 +108,22 @@ class BrickItem extends RenderItem { } } - override private function getImage():String { + private function getImage():String { return 'resources/images/map/map_${value.config.type}.png'; } } - -class TankItem extends RenderItem { +class TankItem extends RenderItem { private var type:String; - override private function getImage():String { + public function new(value:Tank) { + super(value); + this.view = new Animate(getFrames().map(function(s) return Assets.getBitmapData(s))); + } + + private function getFrames():Array { var group = value.config.group; var index = value.playerId.index; if (group == 'human') group = 'player'; @@ -122,7 +136,10 @@ class TankItem extends RenderItem { index = 1; } if (group == 'bot') index = 0; - return 'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-0.png'; + return [ + 'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-0.png', + 'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-1.png', + ]; } override public function update():Void { @@ -132,11 +149,19 @@ class TankItem extends RenderItem { this.type = t; redraw(); } + view.playing = (value.mx !=0 || value.my != 0); + } + + override public function dispose():Void { + if (view != null) { + view.dispose(); + view = null; + } } } -class BulletItem extends RenderItem { +class BulletItem extends BitmapItem { override private function getImage():String { return 'resources/images/bullet/bullet_${value.config.piercing > 1 ? 1 : 0}.png'; @@ -144,7 +169,7 @@ class BulletItem extends RenderItem { } -class EagleItem extends RenderItem { +class EagleItem extends BitmapItem { public var destoyed(default, default):Bool;