[common] add ICaller; [client] rework BrickRenderItem
This commit is contained in:
1
WORK.md
1
WORK.md
@@ -22,3 +22,4 @@
|
|||||||
* ice brick fix
|
* ice brick fix
|
||||||
* shot delay
|
* shot delay
|
||||||
* boat in tank state
|
* boat in tank state
|
||||||
|
* updater version compare
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package ru.m.tankz.local;
|
package ru.m.tankz.local;
|
||||||
|
|
||||||
import flash.events.Event;
|
|
||||||
import flash.Lib;
|
|
||||||
import ru.m.tankz.control.HumanControl;
|
import ru.m.tankz.control.HumanControl;
|
||||||
import ru.m.tankz.game.GameEvent;
|
import ru.m.tankz.game.GameEvent;
|
||||||
import ru.m.tankz.game.GameRunner;
|
import ru.m.tankz.game.GameRunner;
|
||||||
@@ -13,25 +11,15 @@ class LocalGame extends GameRunner {
|
|||||||
|
|
||||||
@:provide static var gameStorage:GameStorage;
|
@:provide static var gameStorage:GameStorage;
|
||||||
|
|
||||||
private var updateEvent:String;
|
|
||||||
|
|
||||||
public function new(start:Start) {
|
public function new(start:Start) {
|
||||||
super(start);
|
super(start);
|
||||||
controlFactory = new LocalControlFactory();
|
controlFactory = new LocalControlFactory();
|
||||||
updateEvent = Event.ENTER_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function onUpdateEvent(_):Void {
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function onGameEvent(event:GameEvent):Void {
|
override public function onGameEvent(event:GameEvent):Void {
|
||||||
super.onGameEvent(event);
|
super.onGameEvent(event);
|
||||||
switch event {
|
switch event {
|
||||||
case START(_):
|
|
||||||
Lib.current.stage.addEventListener(updateEvent, onUpdateEvent);
|
|
||||||
case COMPLETE(result):
|
case COMPLETE(result):
|
||||||
Lib.current.stage.removeEventListener(updateEvent, onUpdateEvent);
|
|
||||||
updateProgress(result);
|
updateProgress(result);
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
@@ -51,9 +39,4 @@ class LocalGame extends GameRunner {
|
|||||||
gameStorage.set(progress);
|
gameStorage.set(progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function dispose():Void {
|
|
||||||
super.dispose();
|
|
||||||
Lib.current.stage.removeEventListener(updateEvent, onUpdateEvent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/client/haxe/ru/m/tankz/local/StageCaller.hx
Normal file
31
src/client/haxe/ru/m/tankz/local/StageCaller.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,62 +1,77 @@
|
|||||||
package ru.m.tankz.render.item;
|
package ru.m.tankz.render.item;
|
||||||
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.Shape;
|
|
||||||
import openfl.Assets;
|
import openfl.Assets;
|
||||||
import openfl.display.DisplayObject;
|
import ru.m.geom.GridPoint;
|
||||||
import ru.m.geom.Point;
|
|
||||||
import ru.m.geom.Rectangle;
|
import ru.m.geom.Rectangle;
|
||||||
import ru.m.tankz.Type.BrickType;
|
import ru.m.tankz.Type;
|
||||||
|
|
||||||
enum BrickState {
|
class BrickBitmapBundle {
|
||||||
UNBROKEN;
|
|
||||||
BROKEN;
|
private var data:Map<String, BitmapData>;
|
||||||
DESTROYED;
|
|
||||||
|
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 type(default, set):BrickType;
|
||||||
public var state(get, never):BrickState;
|
|
||||||
|
|
||||||
private var image:BitmapData;
|
private var cells:Array<GridPoint>;
|
||||||
private var shape:Shape;
|
|
||||||
private var cells:Array<Point>;
|
|
||||||
|
|
||||||
private static function buildCells():Array<Point> {
|
private static function buildCells():Array<GridPoint> {
|
||||||
return [
|
return [
|
||||||
new Point(0, 0),
|
new GridPoint(0, 0),
|
||||||
new Point(0, 1),
|
new GridPoint(0, 1),
|
||||||
new Point(1, 0),
|
new GridPoint(1, 0),
|
||||||
new Point(1, 1),
|
new GridPoint(1, 1),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new(rect:Rectangle, type:BrickType) {
|
public function new(rect:Rectangle, type:BrickType) {
|
||||||
super(rect);
|
super(rect);
|
||||||
this.shape = new Shape();
|
|
||||||
cells = buildCells();
|
cells = buildCells();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
move(rect.position);
|
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 {
|
private function set_type(value:BrickType):BrickType {
|
||||||
if (type != value) {
|
if (type != value) {
|
||||||
type = value;
|
type = value;
|
||||||
cells = buildCells();
|
cells = buildCells();
|
||||||
image = Assets.getBitmapData('resources/image/map/${type}.png');
|
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
@@ -73,24 +88,6 @@ class BrickRenderItem extends RenderItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function redraw():Void {
|
public function redraw():Void {
|
||||||
shape.graphics.clear();
|
image = bundle.get(type, cells);
|
||||||
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:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,4 +20,8 @@ abstract GridPoint({x:Int, y:Int}) {
|
|||||||
@:to inline public function toPoint():Point {
|
@:to inline public function toPoint():Point {
|
||||||
return new Point(this.x, this.y);
|
return new Point(this.x, this.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toString():String {
|
||||||
|
return '${this.x}:${this.y}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
src/common/haxe/ru/m/tankz/engine/ICaller.hx
Normal file
6
src/common/haxe/ru/m/tankz/engine/ICaller.hx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package ru.m.tankz.engine;
|
||||||
|
|
||||||
|
interface ICaller {
|
||||||
|
public function start(calback:Void -> Void):Void;
|
||||||
|
public function stop():Void;
|
||||||
|
}
|
||||||
24
src/common/haxe/ru/m/tankz/engine/TimerCaller.hx
Normal file
24
src/common/haxe/ru/m/tankz/engine/TimerCaller.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,9 @@ import ru.m.tankz.core.EntityType;
|
|||||||
import ru.m.tankz.core.Tank;
|
import ru.m.tankz.core.Tank;
|
||||||
import ru.m.tankz.core.Weapon;
|
import ru.m.tankz.core.Weapon;
|
||||||
import ru.m.tankz.engine.Engine;
|
import ru.m.tankz.engine.Engine;
|
||||||
|
import ru.m.tankz.engine.ICaller;
|
||||||
import ru.m.tankz.engine.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
|
import ru.m.tankz.engine.TimerCaller;
|
||||||
import ru.m.tankz.game.GameEvent;
|
import ru.m.tankz.game.GameEvent;
|
||||||
import ru.m.tankz.game.GameState;
|
import ru.m.tankz.game.GameState;
|
||||||
import ru.m.tankz.game.Spawner;
|
import ru.m.tankz.game.Spawner;
|
||||||
@@ -20,11 +22,14 @@ import ru.m.tankz.Type;
|
|||||||
using ru.m.tankz.game.GameUtil;
|
using ru.m.tankz.game.GameUtil;
|
||||||
|
|
||||||
class GameRunner extends Game implements EngineListener {
|
class GameRunner extends Game implements EngineListener {
|
||||||
|
private var updater:ICaller;
|
||||||
|
|
||||||
private var builder:EntityBuilder;
|
private var builder:EntityBuilder;
|
||||||
private var bonuses:BonusFactory;
|
private var bonuses:BonusFactory;
|
||||||
|
|
||||||
public function new(start:Start) {
|
public function new(start:Start, ?updater:ICaller) {
|
||||||
super(start.state.type);
|
super(start.state.type);
|
||||||
|
this.updater = updater != null ? updater : new TimerCaller();
|
||||||
this.level = start.level;
|
this.level = start.level;
|
||||||
this.state = start.state;
|
this.state = start.state;
|
||||||
builder = new EntityBuilder(config);
|
builder = new EntityBuilder(config);
|
||||||
@@ -52,15 +57,12 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
override public function start():Void {
|
override public function start():Void {
|
||||||
super.start();
|
super.start();
|
||||||
gameEventSignal.emit(START({level:level, state:state}));
|
gameEventSignal.emit(START({level:level, state:state}));
|
||||||
|
updater.start(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function dispose():Void {
|
override public function dispose():Void {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
if (timer != null) {
|
updater.stop();
|
||||||
timer.stop();
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
engine.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newPlayerTank(playerId:PlayerId):TankInfo {
|
public function newPlayerTank(playerId:PlayerId):TankInfo {
|
||||||
@@ -277,6 +279,7 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
engine.ticker.start();
|
engine.ticker.start();
|
||||||
case COMPLETE(_):
|
case COMPLETE(_):
|
||||||
engine.ticker.stop();
|
engine.ticker.stop();
|
||||||
|
updater.stop();
|
||||||
case ACTION(tankId, SHOT(index)):
|
case ACTION(tankId, SHOT(index)):
|
||||||
var tank:Tank = cast engine.entities.get(tankId);
|
var tank:Tank = cast engine.entities.get(tankId);
|
||||||
var player = getPlayer(tank.playerId);
|
var player = getPlayer(tank.playerId);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package ru.m.tankz.server.game;
|
package ru.m.tankz.server.game;
|
||||||
|
|
||||||
import ru.m.tankz.control.Controller;
|
|
||||||
import ru.m.tankz.bundle.ILevelBundle;
|
import ru.m.tankz.bundle.ILevelBundle;
|
||||||
|
import ru.m.tankz.control.Controller;
|
||||||
import ru.m.tankz.control.PlayerControl;
|
import ru.m.tankz.control.PlayerControl;
|
||||||
import ru.m.tankz.core.EntityType;
|
import ru.m.tankz.core.EntityType;
|
||||||
import ru.m.tankz.game.EventUtil;
|
import ru.m.tankz.game.EventUtil;
|
||||||
@@ -38,19 +38,6 @@ class ServerGame extends GameRunner {
|
|||||||
return room.game.id;
|
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 {
|
public function contains(user:UserProto):Bool {
|
||||||
for (slot in room.slots) {
|
for (slot in room.slots) {
|
||||||
if (slot.hasUser() && slot.user.uuid == user.uuid) {
|
if (slot.hasUser() && slot.user.uuid == user.uuid) {
|
||||||
@@ -103,14 +90,6 @@ class ServerGame extends GameRunner {
|
|||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function dispose():Void {
|
|
||||||
super.dispose();
|
|
||||||
if (timer != null) {
|
|
||||||
timer.stop();
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function restore():Array<GameEvent> {
|
public function restore():Array<GameEvent> {
|
||||||
var result = [];
|
var result = [];
|
||||||
result.push(EventUtil.buildBricksSpawn(engine.map));
|
result.push(EventUtil.buildBricksSpawn(engine.map));
|
||||||
|
|||||||
Reference in New Issue
Block a user