[common] use proto types
This commit is contained in:
@@ -2,8 +2,10 @@ package ru.m.data;
|
||||
|
||||
import flash.net.SharedObject;
|
||||
import haxe.DynamicAccess;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.Serializer;
|
||||
import haxe.Unserializer;
|
||||
import hw.connect.PacketUtil;
|
||||
import promhx.Promise;
|
||||
import ru.m.data.IDataSource;
|
||||
|
||||
@@ -34,6 +36,15 @@ class DefaultConverter<D> extends Converter<D, String> {
|
||||
}
|
||||
}
|
||||
|
||||
class ProtoConverter<D:protohx.Message> extends Converter<D, String> {
|
||||
public function new(messageClass:Class<D>) {
|
||||
super(
|
||||
item -> PacketUtil.toBytes(item).toHex(),
|
||||
data -> PacketUtil.fromBytes(Bytes.ofHex(data), messageClass)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EmptyConverter<T> extends Converter<T, T> {
|
||||
public function new() {
|
||||
super(item -> item, data -> data);
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package ru.m.puzzlez.net;
|
||||
|
||||
import haxe.Unserializer;
|
||||
import hw.connect.ConnectionFactory;
|
||||
import hw.connect.IConnection;
|
||||
import hw.signal.Signal;
|
||||
import hw.storage.SharedObjectStorage;
|
||||
import promhx.Promise;
|
||||
import ru.m.data.IDataSource;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.proto.game.GameProto;
|
||||
import ru.m.puzzlez.proto.core.UserProto;
|
||||
import ru.m.puzzlez.proto.core.User;
|
||||
import ru.m.puzzlez.proto.event.GameAction;
|
||||
import ru.m.puzzlez.proto.event.GameEvent;
|
||||
import ru.m.puzzlez.proto.game.GameItem;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import ru.m.puzzlez.proto.pack.GameActionRequest;
|
||||
import ru.m.puzzlez.proto.pack.GameCreateRequest;
|
||||
import ru.m.puzzlez.proto.pack.GameJoinRequest;
|
||||
import ru.m.puzzlez.proto.pack.LoginRequest;
|
||||
@@ -19,14 +20,14 @@ import ru.m.puzzlez.proto.pack.Request;
|
||||
import ru.m.puzzlez.proto.pack.Response;
|
||||
|
||||
@:provide class Network implements IDataIndex<ImageId> {
|
||||
public var user(default, null):UserProto;
|
||||
public var userSignal(default, null):Signal<UserProto> = new Signal();
|
||||
public var user(default, null):User;
|
||||
public var userSignal(default, null):Signal<User> = new Signal();
|
||||
|
||||
public var gameList(default, null):Array<GameProto>;
|
||||
public var gameListSignal(default, null):Signal<Array<GameProto>> = new Signal();
|
||||
public var gameList(default, null):Array<GameItem>;
|
||||
public var gameListSignal(default, null):Signal<Array<GameItem>> = new Signal();
|
||||
|
||||
public var game(default, null):GameProto;
|
||||
public var gameSignal(default, null):Signal<GameProto> = new Signal();
|
||||
public var game(default, null):GameItem;
|
||||
public var gameSignal(default, null):Signal<GameItem> = new Signal();
|
||||
|
||||
public var gameEventSignal(default, null):Signal<GameEvent> = new Signal();
|
||||
|
||||
@@ -37,11 +38,11 @@ import ru.m.puzzlez.proto.pack.Response;
|
||||
|
||||
public function new() {
|
||||
gameList = [];
|
||||
storage = new SharedObjectStorage("network");
|
||||
storage = new SharedObjectStorage("network/2");
|
||||
if (storage.exists(USER_KEY)) {
|
||||
user = storage.read(USER_KEY);
|
||||
} else {
|
||||
user = new UserProto().setName('Anonimus #${IdUtil.generate()}');
|
||||
user = new User().setName('Anonimus #${IdUtil.generate()}');
|
||||
storage.write(USER_KEY, user);
|
||||
}
|
||||
connection = ConnectionFactory.buildClientConnection("127.0.0.1", 5000, Response);
|
||||
@@ -63,8 +64,7 @@ import ru.m.puzzlez.proto.pack.Response;
|
||||
}
|
||||
|
||||
public function sendGameAction(action:GameAction):Void {
|
||||
// ToDo: send action
|
||||
//connection.send(new Request().setGameEvent());
|
||||
connection.send(new Request().setGameAction(new GameActionRequest().setActions([action])));
|
||||
}
|
||||
|
||||
private function onConnectionChange(event:ConnectionEvent):Void {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package ru.m.puzzlez.net;
|
||||
|
||||
import hw.signal.Signal;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.core.IGame;
|
||||
import ru.m.puzzlez.proto.event.GameAction;
|
||||
import ru.m.puzzlez.proto.event.GameEvent;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import ru.m.puzzlez.proto.game.GameStatus;
|
||||
|
||||
class NetworkGame implements IGame {
|
||||
public var state(default, null):GameState;
|
||||
@@ -23,7 +25,7 @@ class NetworkGame implements IGame {
|
||||
public function start():Void {
|
||||
network.gameEventSignal.connect(onEvent);
|
||||
switch state.status {
|
||||
case READY:
|
||||
case GameStatus.READY:
|
||||
network.startGame(state);
|
||||
case _:
|
||||
network.joinGame(state);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package ru.m.puzzlez.render;
|
||||
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
import ru.m.puzzlez.proto.game.GamePreset;
|
||||
import flash.display.Shape;
|
||||
import flash.geom.Matrix;
|
||||
import ru.m.puzzlez.core.GamePreset;
|
||||
import ru.m.puzzlez.render.part.IPartBuilder;
|
||||
|
||||
class CompleteView extends Shape {
|
||||
@@ -29,8 +30,8 @@ class CompleteView extends Shape {
|
||||
return;
|
||||
}
|
||||
|
||||
var partWidth = preset.imageRect.width / preset.grid.width;
|
||||
var partHeight = preset.imageRect.height / preset.grid.height;
|
||||
var partWidth = preset.imageRect.width / preset.grid.x;
|
||||
var partHeight = preset.imageRect.height / preset.grid.y;
|
||||
|
||||
graphics.clear();
|
||||
graphics.lineStyle(2, 0xCCCCCC);
|
||||
@@ -51,9 +52,9 @@ class CompleteView extends Shape {
|
||||
graphics.endFill();
|
||||
}
|
||||
|
||||
var rect = part.rect.clone();
|
||||
rect.x = part.gridX * part.rect.width;
|
||||
rect.y = part.gridY * part.rect.height;
|
||||
var rect = cast(part.rect, RectangleExt).clone();
|
||||
rect.x = part.point.x * part.rect.width;
|
||||
rect.y = part.point.y * part.rect.height;
|
||||
var path = builder.build(rect, part.bounds);
|
||||
for (value in RenderUtil.borderSettings) {
|
||||
graphics.lineStyle(1, value.color, value.opacity);
|
||||
|
||||
@@ -2,7 +2,8 @@ package ru.m.puzzlez.render;
|
||||
|
||||
import hw.signal.Signal;
|
||||
import hw.view.IView;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.proto.event.GameAction;
|
||||
import ru.m.puzzlez.proto.event.GameEvent;
|
||||
|
||||
interface IRender extends IView<Dynamic> {
|
||||
public var actions(default, null):Signal<GameAction>;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package ru.m.puzzlez.render;
|
||||
|
||||
import ru.m.puzzlez.render.RenderUtil;
|
||||
import flash.display.BitmapData;
|
||||
import haxe.Timer;
|
||||
import promhx.PublicStream;
|
||||
import promhx.Stream;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.game.Part;
|
||||
import ru.m.puzzlez.render.RenderUtil;
|
||||
|
||||
typedef Result = {
|
||||
var part:Part;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package ru.m.puzzlez.render;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.PixelSnapping;
|
||||
import flash.display.Sprite;
|
||||
import hw.geom.Point;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.render.RenderUtil;
|
||||
import ru.m.puzzlez.proto.core.Point;
|
||||
import ru.m.puzzlez.proto.game.Part;
|
||||
import ru.m.puzzlez.render.part.IPartBuilder;
|
||||
import ru.m.puzzlez.render.RenderUtil;
|
||||
import ru.m.puzzlez.wrap.PointExt;
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
|
||||
class PartView extends Sprite {
|
||||
|
||||
@@ -19,7 +21,7 @@ class PartView extends Sprite {
|
||||
public var target(default, null):Point;
|
||||
|
||||
private function set_position(value:Point):Point {
|
||||
position = value.clone();
|
||||
position = cast(value, PointExt).clone();
|
||||
refresh();
|
||||
return position;
|
||||
}
|
||||
@@ -58,8 +60,8 @@ class PartView extends Sprite {
|
||||
super();
|
||||
this.id = part.id;
|
||||
this.part = part;
|
||||
this.size = part.rect.size.clone();
|
||||
this.target = new Point(part.gridX * size.x, part.gridY * size.y);
|
||||
this.size = cast(part.rect, RectangleExt).size;
|
||||
this.target = new Point().setX(part.point.x * size.x).setY(part.point.y * size.y);
|
||||
}
|
||||
|
||||
private function redraw():Void {
|
||||
@@ -101,7 +103,7 @@ class SpritePartView extends PartView {
|
||||
graphics.endFill();
|
||||
|
||||
if (playerId != null) {
|
||||
var rect = part.rect.clone();
|
||||
var rect = cast(part.rect, RectangleExt).clone();
|
||||
rect.x += (image.width - size.x) / 2;
|
||||
rect.y += (image.height - size.y) / 2;
|
||||
var path = builder.build(rect, part.bounds);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package ru.m.puzzlez.render;
|
||||
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.net.Network;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.PNGEncoderOptions;
|
||||
import flash.display.Sprite;
|
||||
@@ -10,16 +8,20 @@ import flash.geom.Point as FlashPoint;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.net.FileReference;
|
||||
import flash.utils.ByteArray;
|
||||
import hw.geom.Point;
|
||||
import hw.signal.Signal;
|
||||
import hw.view.popup.AlertView;
|
||||
import hw.view.SpriteView;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.PartLocation;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.net.Network;
|
||||
import ru.m.puzzlez.proto.event.gameaction.Action;
|
||||
import ru.m.puzzlez.proto.event.GameAction;
|
||||
import ru.m.puzzlez.proto.event.GameEvent;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import ru.m.puzzlez.proto.game.PartLocation;
|
||||
import ru.m.puzzlez.render.ImagePartBuilder;
|
||||
import ru.m.puzzlez.storage.ImageStorage;
|
||||
import ru.m.puzzlez.storage.SettingsStorage;
|
||||
import ru.m.puzzlez.wrap.PointExt;
|
||||
|
||||
class Render extends SpriteView implements IRender {
|
||||
|
||||
@@ -33,7 +35,7 @@ class Render extends SpriteView implements IRender {
|
||||
private var playerId(get, never):PlayerId;
|
||||
|
||||
private function get_playerId():PlayerId {
|
||||
return network.user.uuid;
|
||||
return network.user.hasUuid() ? network.user.uuid : "local";
|
||||
}
|
||||
|
||||
private function get_scale():Float {
|
||||
@@ -57,7 +59,7 @@ class Render extends SpriteView implements IRender {
|
||||
private var imageView:CompleteView;
|
||||
private var parts:Map<Int, PartView>;
|
||||
private var activePart:PartView;
|
||||
private var activePoint:Point;
|
||||
private var activePoint:PointExt;
|
||||
|
||||
private var movePoint:FlashPoint;
|
||||
|
||||
@@ -79,25 +81,21 @@ class Render extends SpriteView implements IRender {
|
||||
}
|
||||
|
||||
public function onGameEvent(event:GameEvent):Void {
|
||||
switch event {
|
||||
case START(state, resume):
|
||||
onStart(state);
|
||||
case CHANGE(PART_UPDATE(id, TABLE(point))):
|
||||
var part:PartView = parts[id];
|
||||
part.position = point;
|
||||
part.playerId = null;
|
||||
case CHANGE(PART_UPDATE(id, HAND(playerId, point))):
|
||||
var part:PartView = parts[id];
|
||||
part.position = point;
|
||||
part.playerId = playerId;
|
||||
case CHANGE(PART_UPDATE(id, IMAGE)):
|
||||
var part:PartView = parts[id];
|
||||
part.complete();
|
||||
imageView.addChild(part);
|
||||
imageView.redraw();
|
||||
case COMPLETE:
|
||||
AlertView.alert("Complete!");
|
||||
case _:
|
||||
if (event.hasStart()) {
|
||||
onStart(event.start.state);
|
||||
} else if (event.hasChange()) {
|
||||
var part:PartView = parts[event.change.partId];
|
||||
part.playerId = event.change.playerId;
|
||||
part.position = event.change.position;
|
||||
switch event.change.location {
|
||||
case PartLocation.IMAGE:
|
||||
part.complete();
|
||||
imageView.addChild(part);
|
||||
imageView.redraw();
|
||||
case _:
|
||||
}
|
||||
} else if (event.hasComplete()) {
|
||||
AlertView.alert("Complete!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,10 +106,10 @@ class Render extends SpriteView implements IRender {
|
||||
var partView = PartView.factory(part);
|
||||
parts.set(part.id, partView);
|
||||
switch part.location {
|
||||
case TABLE(point):
|
||||
partView.position = point;
|
||||
case PartLocation.TABLE:
|
||||
partView.position = part.position;
|
||||
tableView.addChild(partView);
|
||||
case IMAGE:
|
||||
case PartLocation.IMAGE:
|
||||
partView.complete();
|
||||
imageView.addChild(partView);
|
||||
case _:
|
||||
@@ -200,24 +198,38 @@ class Render extends SpriteView implements IRender {
|
||||
}
|
||||
activePart = pointPart;
|
||||
tableView.setChildIndex(activePart, tableView.numChildren - 1);
|
||||
activePoint = RenderUtil.convertPoint(tableView.globalToLocal(point));
|
||||
activePoint = tableView.globalToLocal(point);
|
||||
tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
|
||||
tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
||||
actions.emit(PART_TAKE(playerId, activePart.id));
|
||||
actions.emit(new GameAction()
|
||||
.setAction(Action.TAKE)
|
||||
.setPlayerId(playerId)
|
||||
.setPartId(activePart.id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function onMouseMove(event:MouseEvent):Void {
|
||||
var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)));
|
||||
var partPosition = activePart.position.add(newPoint).subtract(activePoint);
|
||||
actions.emit(PART_MOVE(playerId, activePart.id, partPosition.clone()));
|
||||
var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY));
|
||||
var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint);
|
||||
actions.emit(new GameAction()
|
||||
.setAction(Action.MOVE)
|
||||
.setPlayerId(playerId)
|
||||
.setPartId(activePart.id)
|
||||
.setPosition(partPosition)
|
||||
);
|
||||
activePoint = newPoint;
|
||||
}
|
||||
|
||||
private function onMouseUp(event:MouseEvent):Void {
|
||||
var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)));
|
||||
var partPosition = activePart.position.add(newPoint).subtract(activePoint);
|
||||
actions.emit(PART_PUT(playerId, activePart.id, partPosition.clone()));
|
||||
var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY));
|
||||
var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint);
|
||||
actions.emit(new GameAction()
|
||||
.setAction(Action.PUT)
|
||||
.setPlayerId(playerId)
|
||||
.setPartId(activePart.id)
|
||||
.setPosition(partPosition)
|
||||
);
|
||||
tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
|
||||
tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
||||
activePart = null;
|
||||
|
||||
@@ -4,12 +4,13 @@ import flash.display.BitmapData;
|
||||
import flash.display.Shape;
|
||||
import flash.geom.Matrix;
|
||||
import hw.color.Color;
|
||||
import hw.geom.Point;
|
||||
import hw.geom.Rectangle;
|
||||
import ru.m.draw.DrawPath;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.core.Point;
|
||||
import ru.m.puzzlez.proto.core.Rectangle;
|
||||
import ru.m.puzzlez.proto.game.Part;
|
||||
import ru.m.puzzlez.render.part.IPartBuilder;
|
||||
import ru.m.puzzlez.render.part.PartMask;
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
|
||||
typedef DrawSetting = {
|
||||
var offset:Point;
|
||||
@@ -24,13 +25,13 @@ typedef PartImage = {
|
||||
|
||||
class RenderUtil {
|
||||
public static var shadowSettings(default, null):Array<DrawSetting> = [
|
||||
{offset: new Point(-2, -2), color: 0x000000, opacity: 0.4},
|
||||
{offset: new Point(2, 2), color: 0xffffff, opacity: 0.4},
|
||||
{offset: new Point().setX(-2).setY(-2), color: 0x000000, opacity: 0.4},
|
||||
{offset: new Point().setX(2).setY(2), color: 0xffffff, opacity: 0.4},
|
||||
];
|
||||
|
||||
public static var borderSettings(default, null):Array<DrawSetting> = [
|
||||
{offset: new Point(-1, -1), color: 0x555555, opacity: 0.4},
|
||||
{offset: new Point(1, 1), color: 0xcccccc, opacity: 0.4},
|
||||
{offset: new Point().setX(-1).setY(-1), color: 0x555555, opacity: 0.4},
|
||||
{offset: new Point().setX(1).setY(1), color: 0xcccccc, opacity: 0.4},
|
||||
];
|
||||
|
||||
@:provide static var builder:IPartBuilder;
|
||||
@@ -46,14 +47,18 @@ class RenderUtil {
|
||||
}
|
||||
|
||||
private static function buildPartGeometry(part:Part):{rect:Rectangle, drawRect:Rectangle} {
|
||||
var source = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.height);
|
||||
var rect = source.clone();
|
||||
var source = new Rectangle()
|
||||
.setX(part.rect.width * part.point.x)
|
||||
.setY(part.rect.height * part.point.y)
|
||||
.setWidth(part.rect.width)
|
||||
.setHeight(part.rect.height);
|
||||
var rect = cast(source, RectangleExt).clone();
|
||||
var offset = rect.width / 4 + rect.width * 0.05;
|
||||
rect.x -= offset;
|
||||
rect.y -= offset;
|
||||
rect.width += offset * 2;
|
||||
rect.height += offset * 2;
|
||||
var drawRect = source.clone();
|
||||
var drawRect = cast(source, RectangleExt).clone();
|
||||
drawRect.x = offset;
|
||||
drawRect.y = offset ;
|
||||
return {rect:rect, drawRect:drawRect};
|
||||
@@ -113,10 +118,10 @@ class RenderUtil {
|
||||
var s = Math.min(1, Math.min(target.width / source.width, target.height / source.height));
|
||||
var width = source.width * s;
|
||||
var height = source.height * s;
|
||||
return new Rectangle((target.width - width) / 2, (target.height - height) / 2, width, height);
|
||||
}
|
||||
|
||||
public static function convertPoint(point:flash.geom.Point):Point {
|
||||
return new Point(point.x, point.y);
|
||||
return new Rectangle()
|
||||
.setX((target.width - width) / 2)
|
||||
.setY((target.height - height) / 2)
|
||||
.setWidth(width)
|
||||
.setHeight(height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package ru.m.puzzlez.render.part;
|
||||
|
||||
import hw.geom.Rectangle;
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
import ru.m.puzzlez.proto.core.Rectangle;
|
||||
import ru.m.draw.DrawPath;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.game.PartBound;
|
||||
import ru.m.puzzlez.proto.game.PartBounds;
|
||||
import ru.m.puzzlez.render.part.IPartBuilder;
|
||||
|
||||
class BasePartBuilder implements IPartBuilder {
|
||||
@@ -17,7 +19,7 @@ class BasePartBuilder implements IPartBuilder {
|
||||
private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void {
|
||||
}
|
||||
|
||||
public function build(rect:Rectangle, bounds:PartBounds):DrawPath {
|
||||
public function build(rect:RectangleExt, bounds:PartBounds):DrawPath {
|
||||
var path = new DrawPath();
|
||||
createAngle(path, rect.left, rect.top, true);
|
||||
createBound(path, rect.left, rect.top, rect.right, rect.top, bounds.top);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package ru.m.puzzlez.render.part;
|
||||
|
||||
import ru.m.draw.DrawPath;
|
||||
import ru.m.puzzlez.core.BoundType;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.game.BoundType;
|
||||
import ru.m.puzzlez.proto.game.PartBound;
|
||||
|
||||
class ClassicPartBuilder extends BasePartBuilder {
|
||||
|
||||
@@ -13,18 +13,17 @@ class ClassicPartBuilder extends BasePartBuilder {
|
||||
var spikeWidth = boundLength * 0.2;
|
||||
var spikeOffset = (boundLength - spikeWidth) / 2;
|
||||
var spikeDepth = switch bound.spike {
|
||||
case NONE: 0;
|
||||
case IN: spikeWidth;
|
||||
case OUT: -spikeWidth;
|
||||
case BoundType.IN: spikeWidth;
|
||||
case BoundType.OUT: -spikeWidth;
|
||||
case _: 0;
|
||||
};
|
||||
var spikeSideOffset = switch bound.side {
|
||||
case NONE: 0;
|
||||
case IN: boundLength * -0.04;
|
||||
case OUT: boundLength * 0.04;
|
||||
case BoundType.IN: boundLength * -0.04;
|
||||
case BoundType.OUT: boundLength * 0.04;
|
||||
case _: 0;
|
||||
}
|
||||
switch bound.spike {
|
||||
case NONE:
|
||||
case IN | OUT:
|
||||
case BoundType.IN | BoundType.OUT:
|
||||
path.commands.push(LINE_TO(
|
||||
fromX + spikeOffset * dx + spikeSideOffset * dy,
|
||||
fromY + spikeOffset * dy + spikeSideOffset * dx
|
||||
@@ -41,6 +40,7 @@ class ClassicPartBuilder extends BasePartBuilder {
|
||||
fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy,
|
||||
fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx
|
||||
));
|
||||
case _:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package ru.m.puzzlez.render.part;
|
||||
|
||||
import hw.geom.Rectangle;
|
||||
import ru.m.draw.DrawPath;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.game.PartBounds;
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
|
||||
@:provide(ClassicPartBuilder) interface IPartBuilder {
|
||||
public function build(rect:Rectangle, bound:PartBounds):DrawPath;
|
||||
public function build(rect:RectangleExt, bound:PartBounds):DrawPath;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package ru.m.puzzlez.render.part;
|
||||
|
||||
import ru.m.draw.DrawPath;
|
||||
import ru.m.puzzlez.core.BoundType;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.proto.game.BoundType;
|
||||
import ru.m.puzzlez.proto.game.PartBound;
|
||||
|
||||
class SquarePartBuilder extends BasePartBuilder {
|
||||
|
||||
@@ -13,13 +13,13 @@ class SquarePartBuilder extends BasePartBuilder {
|
||||
var spikeWidth = boundLength * 0.2;
|
||||
var spikeOffset = (boundLength - spikeWidth) / 2;
|
||||
var spikeDepth = switch bound.spike {
|
||||
case NONE: 0;
|
||||
case IN: spikeWidth;
|
||||
case OUT: -spikeWidth;
|
||||
case BoundType.NONE: 0;
|
||||
case BoundType.IN: spikeWidth;
|
||||
case BoundType.OUT: -spikeWidth;
|
||||
}
|
||||
switch bound.spike {
|
||||
case NONE:
|
||||
case IN | OUT:
|
||||
case BoundType.NONE:
|
||||
case BoundType.IN | BoundType.OUT:
|
||||
path.commands.push(LINE_TO(
|
||||
fromX + spikeOffset * dx,
|
||||
fromY + spikeOffset * dy
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
package ru.m.puzzlez.storage;
|
||||
|
||||
import ru.m.data.DataStorage;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.core.ImageListSource;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
|
||||
@:provide class GameStorage extends DataStorage<ImageId, GameState> {
|
||||
inline private static var NAME = "game";
|
||||
inline private static var VERSION = 4;
|
||||
inline private static var VERSION = 6;
|
||||
|
||||
public function new() {
|
||||
super(
|
||||
'${NAME}/${VERSION}',
|
||||
new MetaBuilder<GameState>(item -> ["id" => item.preset.imageId, "status" => item.status, "date" => Date.now().toString()]),
|
||||
new Converter<ImageId, String>(id -> id.toString(), data -> ImageId.fromString(data))
|
||||
new MetaBuilder<GameState>(item -> [
|
||||
"id" => item.preset.imageId,
|
||||
"status" => Std.string(item.status),
|
||||
"date" => Date.now().toString()
|
||||
]),
|
||||
new Converter<ImageId, String>(id -> id.toString(), data -> ImageId.fromString(data)),
|
||||
new ProtoConverter(GameState)
|
||||
);
|
||||
}
|
||||
|
||||
public function statusSource(status:GameStatus):ImageListSource {
|
||||
public function statusSource(status:Int):ImageListSource {
|
||||
return {
|
||||
title: status,
|
||||
title: Std.string(status), // # ToDo:
|
||||
source: this,
|
||||
filter: ["status" => status],
|
||||
filter: ["status" => Std.string(status)],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package ru.m.puzzlez.view;
|
||||
|
||||
import ru.m.puzzlez.proto.game.GameStatus;
|
||||
import haxe.Timer;
|
||||
import hw.view.frame.FrameSwitcher;
|
||||
import hw.view.frame.FrameView;
|
||||
import hw.view.popup.ConfirmView;
|
||||
import promhx.Promise;
|
||||
import ru.m.puzzlez.core.Game;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.IGame;
|
||||
import ru.m.puzzlez.net.NetworkGame;
|
||||
import ru.m.puzzlez.proto.event.GameEvent;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import ru.m.puzzlez.render.IRender;
|
||||
import ru.m.puzzlez.storage.GameStorage;
|
||||
import ru.m.puzzlez.storage.SettingsStorage;
|
||||
@@ -73,10 +74,8 @@ import ru.m.puzzlez.view.popup.PreviewPopup;
|
||||
}
|
||||
|
||||
private function onGameEvent(event:GameEvent):Void {
|
||||
switch event {
|
||||
case START(_) | ACTION(PART_PUT(_, _)):
|
||||
toSave();
|
||||
case _:
|
||||
if (event.hasStart() || event.hasAction()) {
|
||||
toSave();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +93,7 @@ import ru.m.puzzlez.view.popup.PreviewPopup;
|
||||
}
|
||||
|
||||
private function back():Void {
|
||||
(game.state.status == COMPLETE ? Promise.promise(true) : ConfirmView.confirm("Exit?"))
|
||||
(game.state.status == GameStatus.COMPLETE ? Promise.promise(true) : ConfirmView.confirm("Exit?"))
|
||||
.then(result -> {
|
||||
if (result) {
|
||||
switcher.change(ImageListFrame.ID, storage.statusSource(game.state.status));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.puzzlez.view;
|
||||
|
||||
import ru.m.puzzlez.proto.game.GameStatus;
|
||||
import ru.m.puzzlez.net.Network;
|
||||
import hw.view.data.DataView;
|
||||
import hw.view.form.ButtonView;
|
||||
@@ -7,7 +8,6 @@ import hw.view.frame.FrameSwitcher;
|
||||
import hw.view.frame.FrameView;
|
||||
import ru.m.data.IDataSource;
|
||||
import ru.m.pixabay.PixabayApi;
|
||||
import ru.m.puzzlez.core.GameState.GameStatus;
|
||||
import ru.m.puzzlez.core.ImageListSource;
|
||||
import ru.m.puzzlez.source.AssetSource;
|
||||
import ru.m.puzzlez.source.FileSource;
|
||||
@@ -43,13 +43,13 @@ import ru.m.update.Updater;
|
||||
}
|
||||
|
||||
private function refresh():Void {
|
||||
var startedRequest:Page = {index: 0, count: 0, filter: ["status" => STARTED]};
|
||||
var startedRequest:Page = {index: 0, count: 0, filter: ["status" => Std.string(GameStatus.STARTED)]};
|
||||
gameStorage.getIndexPage(startedRequest).then(page -> {
|
||||
var total = page.total;
|
||||
loadButton.text = 'Resume (${total})';
|
||||
loadButton.disabled = total == 0;
|
||||
});
|
||||
var completeRequest:Page = {index: 0, count: 0, filter: ["status" => COMPLETE]};
|
||||
var completeRequest:Page = {index: 0, count: 0, filter: ["status" => Std.string(GameStatus.COMPLETE)]};
|
||||
gameStorage.getIndexPage(completeRequest).then(page -> {
|
||||
var total = page.total;
|
||||
completeButton.text = 'Complete (${total})';
|
||||
@@ -77,7 +77,7 @@ import ru.m.update.Updater;
|
||||
switcher.change(ImageListFrame.ID, source);
|
||||
}
|
||||
|
||||
private function openGames(status:GameStatus):Void {
|
||||
private function openGames(status:Int):Void {
|
||||
switcher.change(ImageListFrame.ID, gameStorage.statusSource(status));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@ views:
|
||||
- id: load
|
||||
$type: hw.view.form.ButtonView
|
||||
text: Load
|
||||
+onPress: ~openGames('started')
|
||||
+onPress: ~openGames(1)
|
||||
- id: complete
|
||||
$type: hw.view.form.ButtonView
|
||||
text: Complete
|
||||
+onPress: ~openGames('complete')
|
||||
+onPress: ~openGames(2)
|
||||
- id: network
|
||||
$type: hw.view.form.ButtonView
|
||||
text: Network
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package ru.m.puzzlez.view.common;
|
||||
|
||||
import ru.m.puzzlez.wrap.RectangleExt;
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import flash.display.Graphics;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.Shape;
|
||||
import hw.view.group.GroupView;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.render.part.IPartBuilder;
|
||||
import ru.m.puzzlez.render.RenderUtil;
|
||||
import ru.m.puzzlez.storage.ImageStorage;
|
||||
@@ -57,8 +58,8 @@ class PresetView extends GroupView {
|
||||
return;
|
||||
}
|
||||
var preset = state.preset;
|
||||
var partWidth = preset.imageRect.width / preset.grid.width;
|
||||
var partHeight = preset.imageRect.height / preset.grid.height;
|
||||
var partWidth = preset.imageRect.width / preset.grid.x;
|
||||
var partHeight = preset.imageRect.height / preset.grid.y;
|
||||
var graphics:Graphics = table.graphics;
|
||||
graphics.clear();
|
||||
graphics.beginBitmapFill(image, null, false, true);
|
||||
@@ -66,9 +67,9 @@ class PresetView extends GroupView {
|
||||
graphics.endFill();
|
||||
|
||||
for (part in state.parts) {
|
||||
var rect = part.rect.clone();
|
||||
rect.x = part.gridX * part.rect.width;
|
||||
rect.y = part.gridY * part.rect.height;
|
||||
var rect = cast(part.rect, RectangleExt).clone();
|
||||
rect.x = part.point.x * part.rect.width;
|
||||
rect.y = part.point.y * part.rect.height;
|
||||
var path = builder.build(rect, part.bounds);
|
||||
for (value in RenderUtil.borderSettings) {
|
||||
graphics.lineStyle(1, value.color, value.opacity);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package ru.m.puzzlez.view.popup;
|
||||
|
||||
import ru.m.puzzlez.proto.game.GameState;
|
||||
import flash.events.MouseEvent;
|
||||
import hw.view.popup.PopupView;
|
||||
import promhx.Promise;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.view.common.PresetView;
|
||||
|
||||
@:singleton @:template class PreviewPopup extends PopupView<Dynamic> {
|
||||
|
||||
Reference in New Issue
Block a user