[common] abstract Direction
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@ class SettingsStorage {
|
||||
var data:String = Reflect.getProperty(so.data, Std.string(index));
|
||||
L.d(TAG, 'read: ${data}');
|
||||
if (data != null) {
|
||||
try {
|
||||
return ActionConfig.loads(data);
|
||||
} catch (error:Dynamic) {
|
||||
L.w(TAG, "read", error);
|
||||
}
|
||||
}
|
||||
return getDefault(index);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user