[client] added AniamteBundle

This commit is contained in:
2018-02-16 17:57:43 +03:00
parent 1ae84cf5a8
commit 52a4e44e47
10 changed files with 126 additions and 88 deletions

View File

@@ -6,6 +6,11 @@ import flash.display.Bitmap;
import flash.display.BitmapData; import flash.display.BitmapData;
typedef Frame = {
var image:BitmapData;
var length:Int;
}
class Animate extends Bitmap { class Animate extends Bitmap {
private static var timer:Timer; private static var timer:Timer;
@@ -27,21 +32,29 @@ class Animate extends Bitmap {
} }
public var playing(default, set):Bool; public var playing(default, set):Bool;
public var frames(default, set):Array<BitmapData>; public var frames(default, set):Array<Frame>;
private var sequence:Array<BitmapData>;
private var index:Int; private var index:Int;
public function new(?frames:Array<BitmapData>) { public function new(?frames:Array<Frame>) {
super(null, PixelSnapping.AUTO, true); super(null, PixelSnapping.AUTO, true);
this.frames = frames == null ? [] : frames; this.frames = frames == null ? [] : frames;
init(); init();
instances.push(this); instances.push(this);
} }
public function set_frames(value:Array<BitmapData>):Array<BitmapData> { public function set_frames(value:Array<Frame>):Array<Frame> {
sequence = [];
index = 0;
if (value != null) { if (value != null) {
frames = value; frames = value;
bitmapData = frames[0]; for (frame in frames) {
index = 0; sequence = sequence.concat([for (i in 0...frame.length) frame.image]);
}
bitmapData = sequence[0];
} else {
bitmapData = null;
} }
return frames; return frames;
} }
@@ -54,10 +67,10 @@ class Animate extends Bitmap {
} }
private function update():Void { private function update():Void {
if (++index >= frames.length) { if (++index >= sequence.length) {
index = 0; index = 0;
} }
var nextBitmapData = frames[index]; var nextBitmapData = sequence[index];
x -= (nextBitmapData.width - bitmapData.width) / 2; x -= (nextBitmapData.width - bitmapData.width) / 2;
y -= (nextBitmapData.height - bitmapData.height) / 2; y -= (nextBitmapData.height - bitmapData.height) / 2;
bitmapData = nextBitmapData; bitmapData = nextBitmapData;

View File

@@ -1,7 +1,6 @@
package ru.m.animate; package ru.m.animate;
import promhx.Deferred; import promhx.Deferred;
import flash.display.BitmapData;
import promhx.Promise; import promhx.Promise;
@@ -9,10 +8,6 @@ class OnceAnimate extends Animate {
private var deferred:Deferred<Animate>; private var deferred:Deferred<Animate>;
public function new(frames:Array<BitmapData>) {
super(frames);
}
public function play():Promise<Animate> { public function play():Promise<Animate> {
deferred = new Deferred(); deferred = new Deferred();
playing = true; playing = true;

View File

@@ -0,0 +1,61 @@
package ru.m.tankz.render;
import ru.m.draw.BitmapUtil;
import ru.m.draw.Color;
import flash.display.BitmapData;
import openfl.Assets;
import ru.m.animate.Animate;
import ru.m.animate.OnceAnimate;
import ru.m.tankz.core.Tank;
import ru.m.tankz.Type;
class AnimateBundle {
private static function buildAnimate(template:String, sequence:Array<Int>):OnceAnimate {
var frames = [for (i in sequence) ({
image: Assets.getBitmapData(StringTools.replace(template, '%index%', Std.string(i))),
length: 1
})];
return new OnceAnimate(frames);
}
public static function tankSpawn():OnceAnimate {
return buildAnimate('resources/images/tank/appear/appear-%index%.png', [
0, 1, 2, 3, 3, 4, 5, 5, 6
]);
}
public static function tankBoom():OnceAnimate {
return buildAnimate('resources/images/tank/kaboom/kaboom-%index%.png', [
0, 1, 2, 3, 4, 4, 4, 1, 4, 4, 7, 7, 8, 9, 9
]);
}
public static function bulletBoom():OnceAnimate {
return buildAnimate('resources/images/bullet/boom/boom-%index%.png', [
0, 1, 1, 0, 0, 1
]);
}
public static function tankProtect():Animate {
return new Animate([for (i in 0...2) ({
image: Assets.getBitmapData('resources/images/tank/protect/protect-${i}.png'),
length: 5
})]);
}
public static function tankFrames(tank:Tank):Array<Frame> {
var colors:Array<Color> = [tank.color, tank.bonus ? 0xff00aa : tank.color];
return [for (i in 0...2) ({
image: BitmapUtil.colorize(Assets.getBitmapData('resources/image/tank/${tank.config.skin}-${i}.png'), colors[i]),
length: 3
})];
}
public static function bonusFrames(type:BonusType):Array<Frame> {
var image = Assets.getBitmapData('resources/image/bonus/${type}.png');
var empty = new BitmapData(image.width, image.height, true, 0x00000000);
return [{image: image, length: 15}, {image: empty, length: 15}];
}
}

View File

@@ -1,15 +1,15 @@
package ru.m.tankz.render; package ru.m.tankz.render;
import ru.m.geom.Point;
import openfl.Assets;
import ru.m.animate.OnceAnimate;
import flash.display.DisplayObjectContainer; import flash.display.DisplayObjectContainer;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.render.RenderItem;
import ru.m.tankz.engine.Engine;
import flash.display.Sprite;
import flash.display.Graphics; import flash.display.Graphics;
import flash.display.Sprite;
import haxework.gui.SpriteView; import haxework.gui.SpriteView;
import ru.m.animate.Animate;
import ru.m.animate.OnceAnimate;
import ru.m.geom.Point;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.render.RenderItem;
class Render extends SpriteView implements EngineListener { class Render extends SpriteView implements EngineListener {
@@ -105,7 +105,7 @@ class Render extends SpriteView implements EngineListener {
items.set(tank.key, item); items.set(tank.key, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
item.update(); item.update();
playTankSpawn(tank.rect.center); playAnimate(tank.rect.center, AnimateBundle.tankSpawn());
case EntityType.BULLET(bullet): case EntityType.BULLET(bullet):
var item = new BulletItem(bullet); var item = new BulletItem(bullet);
items.set(bullet.key, item); items.set(bullet.key, item);
@@ -128,7 +128,9 @@ class Render extends SpriteView implements EngineListener {
public function onCollision(entity:EntityType, with:EntityType):Void { public function onCollision(entity:EntityType, with:EntityType):Void {
switch [entity, with] { switch [entity, with] {
case [EntityType.BULLET(_), EntityType.EAGLE(eagle)]: case [EntityType.BULLET(_), EntityType.EAGLE(eagle)]:
playTankBoom(eagle.rect.center); if (eagle.death) {
playAnimate(eagle.rect.center, AnimateBundle.tankBoom());
}
case _: case _:
} }
} }
@@ -139,13 +141,14 @@ class Render extends SpriteView implements EngineListener {
if (items.exists(tank.key)) { if (items.exists(tank.key)) {
entryLayer.removeChild(items.get(tank.key).view); entryLayer.removeChild(items.get(tank.key).view);
items.remove(tank.key); items.remove(tank.key);
playTankBoom(tank.rect.center); playAnimate(tank.rect.center, AnimateBundle.tankBoom());
} }
case EntityType.BULLET(bullet): case EntityType.BULLET(bullet):
if (items.exists(bullet.key)) { if (items.exists(bullet.key)) {
entryLayer.removeChild(items.get(bullet.key).view); entryLayer.removeChild(items.get(bullet.key).view);
items.remove(bullet.key); items.remove(bullet.key);
playBulletBoom(bullet.rect.center.add(new Point(bullet.rect.width * bullet.rect.direction.x, bullet.rect.height * bullet.rect.direction.y))); var point = bullet.rect.center.add(new Point(bullet.rect.width * bullet.rect.direction.x, bullet.rect.height * bullet.rect.direction.y));
playAnimate(point, AnimateBundle.bulletBoom());
} }
case EntityType.BONUS(bonus): case EntityType.BONUS(bonus):
if (items.exists(bonus.key)) { if (items.exists(bonus.key)) {
@@ -156,46 +159,11 @@ class Render extends SpriteView implements EngineListener {
} }
} }
private function playTankSpawn(point:Point):Void { private function playAnimate(point:Point, animate:OnceAnimate):Void {
var arr = [
0, 1, 2, 3, 3, 4, 5, 5, 6
];
var frames = [for (i in arr) Assets.getBitmapData('resources/images/tank/appear/appear-${i}.png')];
var animate = new OnceAnimate(frames);
animate.x = point.x - animate.width / 2; animate.x = point.x - animate.width / 2;
animate.y = point.y - animate.height / 2; animate.y = point.y - animate.height / 2;
upperLayer.addChild(animate); upperLayer.addChild(animate);
animate.play().then(function(animate) { animate.play().then(function(animate:Animate):Void {
upperLayer.removeChild(animate);
animate.dispose();
});
}
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); upperLayer.removeChild(animate);
animate.dispose(); animate.dispose();
}); });

View File

@@ -1,22 +1,19 @@
package ru.m.tankz.render; package ru.m.tankz.render;
import ru.m.tankz.Type.BrickType;
import openfl.display.BitmapData;
import ru.m.draw.Color;
import ru.m.tankz.core.Bonus;
import flash.display.Bitmap; import flash.display.Bitmap;
import flash.display.DisplayObject; import flash.display.DisplayObject;
import flash.display.Shape; import flash.display.Shape;
import flash.display.Sprite; import flash.display.Sprite;
import openfl.Assets; import openfl.Assets;
import ru.m.animate.Animate; import ru.m.animate.Animate;
import ru.m.draw.BitmapUtil;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
import ru.m.tankz.core.Bonus;
import ru.m.tankz.core.Bullet; import ru.m.tankz.core.Bullet;
import ru.m.tankz.core.Eagle; import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
import ru.m.tankz.map.Brick; import ru.m.tankz.map.Brick;
import ru.m.tankz.Type.BrickType;
typedef TRectangle = { typedef TRectangle = {
@@ -96,8 +93,6 @@ class BrickItem extends BitmapItem<Brick> {
} }
} }
override private function getImage():String { override private function getImage():String {
return 'resources/image/map/${value.config.type}.png'; return 'resources/image/map/${value.config.type}.png';
} }
@@ -112,9 +107,10 @@ class BrickAnimateItem extends AnimateItem<Brick> {
} }
override public function redraw():Void { override public function redraw():Void {
var frame0 = Assets.getBitmapData('resources/image/map/${value.config.type}-0.png'); view.frames = [for (i in 0...2) ({
var frame1 = Assets.getBitmapData('resources/image/map/${value.config.type}-1.png'); image: Assets.getBitmapData('resources/image/map/${value.config.type}-${i}.png'),
view.frames = [for (i in 0...15) frame0].concat([for (i in 0...15) frame1]); length: 15
})];
view.playing = true; view.playing = true;
} }
} }
@@ -193,25 +189,17 @@ class TankItem extends RenderItem<Tank, Sprite> {
view = new Sprite(); view = new Sprite();
tankView = new Animate(); tankView = new Animate();
view.addChild(tankView); view.addChild(tankView);
protectView = new Animate( protectView = AnimateBundle.tankProtect();
[for (i in 0...5) Assets.getBitmapData('resources/images/tank/protect/protect-0.png')].concat(
[for (i in 0...5) Assets.getBitmapData('resources/images/tank/protect/protect-1.png')])
);
protectView.visible = false; protectView.visible = false;
view.addChild(protectView); view.addChild(protectView);
redraw(); redraw();
} }
override public function redraw():Void { override public function redraw():Void {
var colors:Array<Color> = [value.color, value.bonus ? 0xff00aa : value.color]; tankView.frames = AnimateBundle.tankFrames(value);
var frames = [for (frame in getFrames()) BitmapUtil.colorize(Assets.getBitmapData(frame), colors.shift())];
tankView.frames = [
frames[0], frames[0], frames[0],
frames[1], frames[1], frames[1],
];
if (value.protect.active) { if (value.protect.active) {
protectView.x = (tankView.frames[0].width - protectView.frames[0].width) / 2; protectView.x = (tankView.frames[0].image.width - protectView.frames[0].image.width) / 2;
protectView.y = (tankView.frames[0].height - protectView.frames[0].height) / 2; protectView.y = (tankView.frames[0].image.height - protectView.frames[0].image.height) / 2;
protectView.playing = true; protectView.playing = true;
protectView.visible = true; protectView.visible = true;
} else { } else {
@@ -262,18 +250,22 @@ class BulletItem extends BitmapItem<Bullet> {
class EagleItem extends BitmapItem<Eagle> { class EagleItem extends BitmapItem<Eagle> {
private var death:Bool; private var death:Bool;
private var protected:Bool;
override public function update():Void { override public function update():Void {
super.update(); super.update();
var d = value.death; var d = value.death;
if (d != death) { var p = value.protect.active;
if (d != death || p != protected) {
death = d; death = d;
protected = p;
redraw(); redraw();
} }
} }
override private function getImage():String { override private function getImage():String {
return 'resources/image/eagle/eagle${value.death ? '-death' : ''}.png'; var suffix = value.death ? '-death' : value.protect.active ? '-protected' : '';
return 'resources/image/eagle/eagle${suffix}.png';
} }
} }
@@ -287,8 +279,7 @@ class BonusItem extends AnimateItem<Bonus> {
override public function redraw():Void { override public function redraw():Void {
var image = Assets.getBitmapData('resources/image/bonus/${value.bonusType}.png'); var image = Assets.getBitmapData('resources/image/bonus/${value.bonusType}.png');
var empty = new BitmapData(image.width, image.height, true, 0x00000000); view.frames = AnimateBundle.bonusFrames(value.bonusType);
view.frames = [for (i in 0...15) image].concat([for (i in 0...15) empty]);
view.playing = true; view.playing = true;
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -8,10 +8,12 @@ class Eagle extends Entity {
public var team(default, null):TeamId; public var team(default, null):TeamId;
public var death(default, default):Bool; public var death(default, default):Bool;
public var protect(default, null):Modificator;
public function new(team:TeamId) { public function new(team:TeamId) {
super(new Rectangle(0, 0, 44, 44)); super(new Rectangle(0, 0, 44, 44)); // ToDo: hardcode size
this.team = team; this.team = team;
this.death = false; this.death = false;
this.protect = new Modificator();
} }
} }

View File

@@ -57,7 +57,9 @@ class CollisionProcessor implements EngineListener {
engine.destroy(bullet); engine.destroy(bullet);
case [EntityType.BULLET(bullet), EntityType.EAGLE(eagle)]: case [EntityType.BULLET(bullet), EntityType.EAGLE(eagle)]:
engine.destroy(bullet); engine.destroy(bullet);
if (!eagle.protect.active) {
eagle.death = true; eagle.death = true;
}
case _: case _:
} }
} }

View File

@@ -113,6 +113,7 @@ class Game implements EngineListener {
var eaglePoint = team.spawner.getPoint('eagle'); var eaglePoint = team.spawner.getPoint('eagle');
if (eaglePoint != null) { if (eaglePoint != null) {
var eagle = new Eagle(team.id); var eagle = new Eagle(team.id);
team.eagleId = eagle.id;
applyPoint(eagle, eaglePoint); applyPoint(eagle, eaglePoint);
engine.spawn(eagle); engine.spawn(eagle);
} }
@@ -249,6 +250,10 @@ class Game implements EngineListener {
} }
case 'shovel': case 'shovel':
// ToDo: protect eagle/area // ToDo: protect eagle/area
var team:Team = teams[tank.playerId.team];
if (team.eagleId > 0) {
cast(engine.entities[team.eagleId], Eagle).protect.on(10);
}
case _: case _:
engine.destroy(tank); // :-D engine.destroy(tank); // :-D
} }

View File

@@ -12,6 +12,7 @@ class Team {
public var players(default, null):Map<Int, Player>; public var players(default, null):Map<Int, Player>;
public var life(default, default):Int; public var life(default, default):Int;
public var isAlive(get, null):Bool; public var isAlive(get, null):Bool;
public var eagleId(default, default):Int;
public function new(config:TeamConfig, points:Array<SpawnPoint>) { public function new(config:TeamConfig, points:Array<SpawnPoint>) {
this.id = config.id; this.id = config.id;