[common] add ICaller; [client] rework BrickRenderItem

This commit is contained in:
2019-09-29 20:34:51 +03:00
parent b34cb41bff
commit 1e79fcfacb
10 changed files with 124 additions and 120 deletions

View File

@@ -22,3 +22,4 @@
* ice brick fix
* shot delay
* boat in tank state
* updater version compare

View File

@@ -1,7 +1,5 @@
package ru.m.tankz.local;
import flash.events.Event;
import flash.Lib;
import ru.m.tankz.control.HumanControl;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.GameRunner;
@@ -13,25 +11,15 @@ class LocalGame extends GameRunner {
@:provide static var gameStorage:GameStorage;
private var updateEvent:String;
public function new(start:Start) {
super(start);
controlFactory = new LocalControlFactory();
updateEvent = Event.ENTER_FRAME;
}
private function onUpdateEvent(_):Void {
update();
}
override public function onGameEvent(event:GameEvent):Void {
super.onGameEvent(event);
switch event {
case START(_):
Lib.current.stage.addEventListener(updateEvent, onUpdateEvent);
case COMPLETE(result):
Lib.current.stage.removeEventListener(updateEvent, onUpdateEvent);
updateProgress(result);
case _:
}
@@ -51,9 +39,4 @@ class LocalGame extends GameRunner {
gameStorage.set(progress);
}
}
override public function dispose():Void {
super.dispose();
Lib.current.stage.removeEventListener(updateEvent, onUpdateEvent);
}
}

View File

@@ -0,0 +1,31 @@
package ru.m.tankz.local;
import flash.display.Stage;
import flash.events.Event;
import ru.m.tankz.engine.ICaller;
class StageCaller implements ICaller {
private var stage:Stage;
private var event:String;
private var calback:Void -> Void;
public function new(stage:Stage, ?event:String) {
this.stage = stage;
this.event = event != null ? event : Event.ENTER_FRAME;
}
private function onEvent(_):Void {
calback();
}
public function start(calback:Void -> Void):Void {
this.calback = calback;
stage.addEventListener(event, onEvent);
}
public function stop():Void {
stage.removeEventListener(event, onEvent);
calback = null;
}
}

View File

@@ -1,62 +1,77 @@
package ru.m.tankz.render.item;
import flash.display.BitmapData;
import flash.display.Shape;
import openfl.Assets;
import openfl.display.DisplayObject;
import ru.m.geom.Point;
import ru.m.geom.GridPoint;
import ru.m.geom.Rectangle;
import ru.m.tankz.Type.BrickType;
import ru.m.tankz.Type;
enum BrickState {
UNBROKEN;
BROKEN;
DESTROYED;
class BrickBitmapBundle {
private var data:Map<String, BitmapData>;
public function new() {
data = new Map();
}
class BrickRenderItem extends RenderItem {
private function resolve(type:BrickType, cells:Array<GridPoint>):BitmapData {
return switch cells.length {
case 0:
Assets.getBitmapData('resources/image/map/none.png');
case 4:
Assets.getBitmapData('resources/image/map/${type}.png');
case _:
var image = Assets.getBitmapData('resources/image/map/${type}.png');
var result = new BitmapData(image.width, image.height, true, 0x00000000);
for (point in cells) {
var rect = new flash.geom.Rectangle(
point.x * image.width / 2,
point.y * image.height / 2,
image.width / 2,
image.height / 2);
result.draw(image, null, null, null, rect);
}
return result;
}
}
public function get(type:BrickType, cells:Array<GridPoint>):BitmapData {
var key:String = '${type}_${cells.map(function(point) return point.toString()).join(",")}';
if (!data.exists(key)) {
data.set(key, resolve(type, cells));
}
return data.get(key);
}
}
class BrickRenderItem extends BitmapRenderItem {
private static var bundle:BrickBitmapBundle = new BrickBitmapBundle();
public var type(default, set):BrickType;
public var state(get, never):BrickState;
private var image:BitmapData;
private var shape:Shape;
private var cells:Array<Point>;
private var cells:Array<GridPoint>;
private static function buildCells():Array<Point> {
private static function buildCells():Array<GridPoint> {
return [
new Point(0, 0),
new Point(0, 1),
new Point(1, 0),
new Point(1, 1),
new GridPoint(0, 0),
new GridPoint(0, 1),
new GridPoint(1, 0),
new GridPoint(1, 1),
];
}
public function new(rect:Rectangle, type:BrickType) {
super(rect);
this.shape = new Shape();
cells = buildCells();
this.type = type;
move(rect.position);
}
private function get_state():BrickState {
return switch cells.length {
case 0: DESTROYED;
case 4: UNBROKEN;
case _: BROKEN;
}
}
override private function get_view():DisplayObject {
return shape;
}
private function set_type(value:BrickType):BrickType {
if (type != value) {
type = value;
cells = buildCells();
image = Assets.getBitmapData('resources/image/map/${type}.png');
redraw();
}
return type;
@@ -73,24 +88,6 @@ class BrickRenderItem extends RenderItem {
}
public function redraw():Void {
shape.graphics.clear();
if (type == "none") return;
switch state {
case UNBROKEN:
shape.graphics.beginBitmapFill(image);
shape.graphics.drawRect(0, 0, rect.width, rect.height);
shape.graphics.endFill();
case BROKEN:
shape.graphics.beginBitmapFill(image);
for (point in cells) {
var x = point.x * (rect.width / 2);
var y = point.y * (rect.width / 2);
var width = rect.width / 2;
var height = rect.height / 2;
shape.graphics.drawRect(x, y, width, height);
}
shape.graphics.endFill();
case DESTROYED:
}
image = bundle.get(type, cells);
}
}

View File

@@ -20,4 +20,8 @@ abstract GridPoint({x:Int, y:Int}) {
@:to inline public function toPoint():Point {
return new Point(this.x, this.y);
}
public function toString():String {
return '${this.x}:${this.y}';
}
}

View File

@@ -1,24 +0,0 @@
package ru.m.tankz.core;
abstract TimeInterval(Array<Int>) {
public function new(min:Int, ?max:Null<Int>) {
this = [min, max != null ? max : min]
}
public function resolve():Int {
return this[0] + (this[1] - this[0]) * Math.random();
}
@:from public static function fromArray(value:Array<Int>):TimeInterval {
return new TimeInterval(value[0], value[1]);
}
@:from public static function fromInt(value:Int):TimeInterval {
return new TimeInterval(value);
}
@:from public static function fromFloat(value:Float):TimeInterval {
return new TimeInterval(value * 1000);
}
}

View File

@@ -0,0 +1,6 @@
package ru.m.tankz.engine;
interface ICaller {
public function start(calback:Void -> Void):Void;
public function stop():Void;
}

View File

@@ -0,0 +1,24 @@
package ru.m.tankz.engine;
class TimerCaller implements ICaller {
private var interval:Int;
private var timer:Timer;
public function new(interval:Int = 30) {
this.interval = interval;
}
public function start(calback:Void -> Void):Void {
stop();
timer = new Timer(interval);
timer.run = calback;
}
public function stop():Void {
if (timer != null) {
timer.stop();
timer = null;
}
}
}

View File

@@ -11,7 +11,9 @@ import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank;
import ru.m.tankz.core.Weapon;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.engine.ICaller;
import ru.m.tankz.engine.IEngine;
import ru.m.tankz.engine.TimerCaller;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.GameState;
import ru.m.tankz.game.Spawner;
@@ -20,11 +22,14 @@ import ru.m.tankz.Type;
using ru.m.tankz.game.GameUtil;
class GameRunner extends Game implements EngineListener {
private var updater:ICaller;
private var builder:EntityBuilder;
private var bonuses:BonusFactory;
public function new(start:Start) {
public function new(start:Start, ?updater:ICaller) {
super(start.state.type);
this.updater = updater != null ? updater : new TimerCaller();
this.level = start.level;
this.state = start.state;
builder = new EntityBuilder(config);
@@ -52,15 +57,12 @@ class GameRunner extends Game implements EngineListener {
override public function start():Void {
super.start();
gameEventSignal.emit(START({level:level, state:state}));
updater.start(update);
}
override public function dispose():Void {
super.dispose();
if (timer != null) {
timer.stop();
timer = null;
}
engine.dispose();
updater.stop();
}
public function newPlayerTank(playerId:PlayerId):TankInfo {
@@ -277,6 +279,7 @@ class GameRunner extends Game implements EngineListener {
engine.ticker.start();
case COMPLETE(_):
engine.ticker.stop();
updater.stop();
case ACTION(tankId, SHOT(index)):
var tank:Tank = cast engine.entities.get(tankId);
var player = getPlayer(tank.playerId);

View File

@@ -1,7 +1,7 @@
package ru.m.tankz.server.game;
import ru.m.tankz.control.Controller;
import ru.m.tankz.bundle.ILevelBundle;
import ru.m.tankz.control.Controller;
import ru.m.tankz.control.PlayerControl;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.game.EventUtil;
@@ -38,19 +38,6 @@ class ServerGame extends GameRunner {
return room.game.id;
}
override public function onGameEvent(event:GameEvent):Void {
switch event {
case START(_):
timer = new Timer(30);
timer.run = update;
case COMPLETE(_):
if (timer != null) {
timer.stop();
timer = null;
}
}
}
public function contains(user:UserProto):Bool {
for (slot in room.slots) {
if (slot.hasUser() && slot.user.uuid == user.uuid) {
@@ -103,14 +90,6 @@ class ServerGame extends GameRunner {
super.start();
}
override public function dispose():Void {
super.dispose();
if (timer != null) {
timer.stop();
timer = null;
}
}
public function restore():Array<GameEvent> {
var result = [];
result.push(EventUtil.buildBricksSpawn(engine.map));