[common] abstract Direction

This commit is contained in:
2019-03-05 16:39:03 +03:00
parent d2383fc4f0
commit d4a9c720d6
11 changed files with 77 additions and 164 deletions

View File

@@ -1,33 +1,25 @@
package ru.m.tankz.control;
import ru.m.geom.Direction;
import haxe.Serializer;
import haxe.Unserializer;
import ru.m.tankz.control.Control.TankAction;
import yaml.Parser;
import yaml.Renderer;
import yaml.Yaml;
typedef ActionItem = {
public var action: TankAction;
public var key: Int;
public var action:TankAction;
public var key:Int;
}
typedef KeyBinding = Map<Int, TankAction>;
typedef ActionItemRaw = {
public var action: String;
public var key: Int;
}
class ActionConfig {
public var data(default, null): Array<ActionItem>;
public var data(default, null):Array<ActionItem>;
public function new(data: Array<ActionItem>) {
public function new(data:Array<ActionItem>) {
this.data = data;
}
public function asKeyBinding(): KeyBinding {
public function asKeyBinding():KeyBinding {
var result = new Map<Int, TankAction>();
for (item in data) {
result[item.key] = item.action;
@@ -35,52 +27,15 @@ class ActionConfig {
return result;
}
public static function action2string(action: TankAction): String {
return switch (action) {
case TankAction.SHOT: "SHOT";
case TankAction.MOVE(Direction.TOP): "MOVE_TOP";
case TankAction.MOVE(Direction.LEFT): "MOVE_LEFT";
case TankAction.MOVE(Direction.BOTTOM): "MOVE_BOTTOM";
case TankAction.MOVE(Direction.RIGHT): "MOVE_RIGHT";
case _: throw 'Unsupported action "${action}"';
}
}
public static function string2action(value: String): TankAction {
return switch (value) {
case "SHOT": TankAction.SHOT;
case "MOVE_TOP": TankAction.MOVE(Direction.TOP);
case "MOVE_LEFT": TankAction.MOVE(Direction.LEFT);
case "MOVE_BOTTOM": TankAction.MOVE(Direction.BOTTOM);
case "MOVE_RIGHT": TankAction.MOVE(Direction.RIGHT);
case _: throw 'Unsupported value "${value}"';
}
}
public function clone(): ActionConfig {
public function clone():ActionConfig {
return loads(dumps());
}
public function dumps(): String {
var raw: Array<ActionItemRaw> = [];
for (item in this.data) {
raw.push({
action: action2string(item.action),
key: item.key,
});
}
return Yaml.render(raw, Renderer.options().setFlowLevel(0));
public function dumps():String {
return Serializer.run(this);
}
public static function loads(value: String): ActionConfig {
var raw: Array<ActionItemRaw> = Yaml.parse(value, Parser.options().useObjects());
var data: Array<ActionItem> = [];
for (item in raw) {
data.push({
action: string2action(item.action),
key: item.key,
});
}
return new ActionConfig(data);
public static function loads(value:String):ActionConfig {
return new Unserializer(value).unserialize();
}
}

View File

@@ -18,6 +18,7 @@ views:
$type: haxework.gui.DataView<Int>
layout:
$type: haxework.gui.layout.TailLayout
rowSize: 10
margin: 5
factory: $this:levelViewFactory
+onDataSelect: $code:function(value) level = value

View File

@@ -8,7 +8,6 @@ import haxework.gui.GroupView;
import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
import ru.m.tankz.network.NetworkGame;
import ru.m.tankz.network.NetworkManager;
import ru.m.tankz.render.Render;
import ru.m.tankz.sound.SoundManager;

View File

@@ -1,59 +0,0 @@
package ru.m.tankz.frame.common;
import haxework.resources.IResources;
import haxework.gui.ButtonView;
import haxework.gui.HGroupView;
import haxework.gui.ToggleButtonView;
import ru.m.signal.Signal;
import ru.m.tankz.config.Config.GamePreset;
import ru.m.tankz.Type;
class PresetsView extends HGroupView {
public var data(default, set):Array<GamePreset>;
public var selected(default, set):PresetId;
public var change(default, null):Signal<PresetId>;
@:provide private static var resources:IResources;
public function new() {
super();
layout.margin = 10;
change = new Signal();
}
private function set_data(value:Array<GamePreset>):Array<GamePreset> {
data = value;
removeAllViews();
for (item in data) {
var view = new ToggleButtonView();
view.skin = resources.skin.get("button.tab");
view.text = item.id;
view.fontFamily = "Courirer New";
view.fontColor = 0xffffff;
view.fontSize = 18;
view.shadowColor = 0x000000;
view.onPress.connect(onPress);
//ToDo: update text and size
view.redraw();
view.update();
addView(view);
}
return data;
}
private function set_selected(value:PresetId):PresetId {
selected = value;
for (view in views) {
var button = cast(view, ToggleButtonView);
button.on = button.text == selected;
}
change.emit(selected);
return selected;
}
public function onPress(view:ButtonView):Void {
selected = view.text;
}
}

View File

@@ -15,6 +15,7 @@ views:
$type: haxework.gui.DataView<Int>
layout:
$type: haxework.gui.layout.TailLayout
rowSize: 5
margin: 5
factory: $this:levelViewFactory
+onDataSelect: $code:function(value) level = value

View File

@@ -48,7 +48,11 @@ class KeyboardMap {
private var editDeferred: Deferred<Int>;
private static function actionLabel(action: TankAction): String {
return ActionConfig.action2string(action);
return switch (action) {
case TankAction.SHOT: "SHOT";
case TankAction.MOVE(d): 'MOVE_$d';
case x: '$x';
}
}
private static function keyLabel(key: Int): String {

View File

@@ -6,7 +6,6 @@ import flash.display.Shape;
import flash.display.Sprite;
import openfl.Assets;
import ru.m.animate.Animate;
import ru.m.geom.Direction;
import ru.m.geom.Rectangle;
import ru.m.tankz.core.Bonus;
import ru.m.tankz.core.Bullet;
@@ -15,7 +14,6 @@ import ru.m.tankz.core.Tank;
import ru.m.tankz.map.Brick;
import ru.m.tankz.Type.BrickType;
typedef TRectangle = {
var rect(default, null):Rectangle;
}
@@ -34,25 +32,11 @@ class RenderItem<T:TRectangle, D:DisplayObject> {
public function update():Void {
var rect = value.rect;
view.rotation = calcRotate(rect.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;
}
private static function calcRotate(direction:Direction):Float {
return (if (direction == Direction.RIGHT) {
0;
} else if (direction == Direction.LEFT) {
180;
} else if (direction == Direction.TOP) {
270;
} else if (direction == Direction.BOTTOM) {
90;
} else {
0;
});
}
public function dispose():Void {}
}

View File

@@ -21,7 +21,11 @@ class SettingsStorage {
var data:String = Reflect.getProperty(so.data, Std.string(index));
L.d(TAG, 'read: ${data}');
if (data != null) {
return ActionConfig.loads(data);
try {
return ActionConfig.loads(data);
} catch (error:Dynamic) {
L.w(TAG, "read", error);
}
}
return getDefault(index);
}

View File

@@ -1,47 +1,72 @@
package ru.m.geom;
import haxe.ds.IntMap;
abstract Direction(Array<Int>) {
private static var directions:Map<Int, Direction> = new Map();
class Direction {
private static var directions:IntMap<Direction> = new IntMap<Direction>();
public static var LEFT(default, never) = Direction.from(-1, 0);
public static var TOP(default, never) = Direction.from(0, -1);
public static var RIGHT(default, never) = Direction.from(1, 0);
public static var BOTTOM(default, never) = Direction.from(0, 1);
public static var LEFT(default, never) = new Direction(-1, 0);
public static var TOP(default, never) = new Direction(0, -1);
public static var RIGHT(default, never) = new Direction(1, 0);
public static var BOTTOM(default, never) = new Direction(0, 1);
public var x(get, never):Int;
public var y(get, never):Int;
public var angle(get, never):Int;
public var x(default, null):Int;
public var y(default, null):Int;
private function new(x, y) {
this.x = x;
this.y = y;
directions.set(x + y * 10, this);
inline public function new(value:Array<Int>) {
this = value;
}
public function reverse():Direction {
return from(-x, -y);
inline private function get_x():Int return this[0];
inline private function get_y():Int return this[1];
inline private function get_angle():Int {
return switch this {
case [-1, 0]: 180;
case [0, -1]: 270;
case [1, 0]: 0;
case [0, 1]: 90;
case _: 0;
}
}
public function equals(other:Direction):Bool {
return other.x == x && other.y == y;
}
public static function from(x:Int, y:Int):Direction {
return directions.get(x + y * 10);
public function reverse():Direction {
return from(-x, -y);
}
@:from static public function fromString(s:String):Direction {
return switch(s) {
case 'left': LEFT;
case 'top': TOP;
case 'right': RIGHT;
case 'bottom': BOTTOM;
@:from inline static public function fromArray(value:Array<Int>):Direction {
return new Direction(value);
}
@:from inline static public function fromString(value:String):Direction {
return switch value.toUpperCase() {
case "LEFT": LEFT;
case "TOP": TOP;
case "RIGHT": RIGHT;
case "BOTTOM": BOTTOM;
case _: null;
}
}
public function toString():String {
return 'Direction{x=$x,y=$y}';
@:to inline public function toString():String {
return (switch this {
case [-1, 0]: "LEFT";
case [0, -1]: "TOP";
case [1, 0]: "RIGHT";
case [0, 1]: "BOTTOM";
case _: null;
});
}
inline static public function from(x:Int, y:Int):Direction {
var key = x + y * 10;
if (!directions.exists(key)) {
directions.set(key, new Direction([x, y]));
}
return directions.get(key);
}
}

View File

@@ -5,7 +5,6 @@ import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.Type;
enum TankAction {
MOVE(direction:Direction);
UPGRADE;

View File

@@ -78,7 +78,7 @@ class Game {
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
entity.rect.center = new Point((point.x + 1) * engine.map.cellWidth, (point.y + 1) * engine.map.cellHeight);
entity.rect.direction = Direction.fromString(point.direction);
entity.rect.direction = point.direction;
}
public function start(state:GameState):Stream<GameState> {