[core] add hand part position

This commit is contained in:
2020-03-31 22:12:37 +03:00
parent 4bb2cd5be8
commit 75c6e835c2
14 changed files with 86 additions and 25 deletions

View File

@@ -8,7 +8,7 @@
"gulp-add": "0.0.2", "gulp-add": "0.0.2",
"gulp-clean": "^0.4.0", "gulp-clean": "^0.4.0",
"gulp-cli": "^2.2.0", "gulp-cli": "^2.2.0",
"gulp-haxetool": "0.1.7", "gulp-haxetool": "0.1.8",
"yargs": "^13.2.4" "yargs": "^13.2.4"
}, },
"haxeDependencies": { "haxeDependencies": {

View File

@@ -3,6 +3,7 @@ package ru.m.puzzlez;
import hw.app.App; import hw.app.App;
import hw.app.Const; import hw.app.Const;
import hw.log.TraceLogger; import hw.log.TraceLogger;
import ru.m.puzzlez.render.part.IPartBuilder;
import ru.m.puzzlez.storage.GameStorage; import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.storage.ImageStorage; import ru.m.puzzlez.storage.ImageStorage;
import ru.m.puzzlez.storage.SettingsStorage; import ru.m.puzzlez.storage.SettingsStorage;
@@ -18,6 +19,7 @@ class PuzzlezApp {
GameStorage; GameStorage;
ImageStorage; ImageStorage;
SettingsStorage; SettingsStorage;
IPartBuilder;
L.push(new TraceLogger()); L.push(new TraceLogger());
updater = new Updater(Const.instance.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json"); updater = new Updater(Const.instance.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
var app = new App(); var app = new App();

View File

@@ -31,7 +31,7 @@ import ru.m.puzzlez.proto.pack.Response;
connection = ConnectionFactory.buildClientConnection("127.0.0.1", 5000, Response); connection = ConnectionFactory.buildClientConnection("127.0.0.1", 5000, Response);
connection.handler.connect(onConnectionChange); connection.handler.connect(onConnectionChange);
connection.receiveHandler.connect(onReceivePacket); connection.receiveHandler.connect(onReceivePacket);
connection.connect(); connection.connect().catchError(_ -> {});
} }
public function login():Void { public function login():Void {

View File

@@ -3,12 +3,15 @@ package ru.m.puzzlez.render;
import flash.display.Shape; import flash.display.Shape;
import flash.geom.Matrix; import flash.geom.Matrix;
import ru.m.puzzlez.core.GamePreset; import ru.m.puzzlez.core.GamePreset;
import ru.m.puzzlez.render.part.IPartBuilder;
class CompleteView extends Shape { class CompleteView extends Shape {
public var parts:Array<PartView>; public var parts:Array<PartView>;
public var preset:GamePreset; public var preset:GamePreset;
@:provide static var builder:IPartBuilder;
public function new() { public function new() {
super(); super();
parts = []; parts = [];
@@ -51,7 +54,7 @@ class CompleteView extends Shape {
var rect = part.rect.clone(); var rect = part.rect.clone();
rect.x = part.gridX * part.rect.width; rect.x = part.gridX * part.rect.width;
rect.y = part.gridY * part.rect.height; rect.y = part.gridY * part.rect.height;
var path = RenderUtil.builder.build(rect, part.bounds); var path = builder.build(rect, part.bounds);
for (value in RenderUtil.borderSettings) { for (value in RenderUtil.borderSettings) {
graphics.lineStyle(1, value.color, value.opacity); graphics.lineStyle(1, value.color, value.opacity);
path.move(value.offset.x, value.offset.y).draw(graphics); path.move(value.offset.x, value.offset.y).draw(graphics);

View File

@@ -6,7 +6,9 @@ import flash.display.PixelSnapping;
import flash.display.Sprite; import flash.display.Sprite;
import hw.geom.Point; import hw.geom.Point;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.render.RenderUtil; import ru.m.puzzlez.render.RenderUtil;
import ru.m.puzzlez.render.part.IPartBuilder;
class PartView extends Sprite { class PartView extends Sprite {
@@ -42,6 +44,16 @@ class PartView extends Sprite {
public var size(default, null):Point; public var size(default, null):Point;
public var playerId(default, set):Null<PlayerId>;
private function set_playerId(value:Null<PlayerId>):Null<PlayerId> {
if (playerId != value) {
playerId = value;
redraw();
}
return playerId;
}
public function new(part:Part) { public function new(part:Part) {
super(); super();
this.id = part.id; this.id = part.id;
@@ -63,6 +75,7 @@ class PartView extends Sprite {
public function complete():Void { public function complete():Void {
position = target; position = target;
playerId = null;
completed = true; completed = true;
refresh(); refresh();
redraw(); redraw();
@@ -75,6 +88,8 @@ class PartView extends Sprite {
class SpritePartView extends PartView { class SpritePartView extends PartView {
@:provide static var builder:IPartBuilder;
override private function redraw():Void { override private function redraw():Void {
if (image == null) { if (image == null) {
return; return;
@@ -84,6 +99,15 @@ class SpritePartView extends PartView {
graphics.beginBitmapFill(image, null, false, true); graphics.beginBitmapFill(image, null, false, true);
graphics.drawRect(0, 0, image.width, image.height); graphics.drawRect(0, 0, image.width, image.height);
graphics.endFill(); graphics.endFill();
if (playerId != null) {
var rect = part.rect.clone();
rect.x += (image.width - size.x) / 2;
rect.y += (image.height - size.y) / 2;
var path = builder.build(rect, part.bounds);
graphics.lineStyle(4, 0xffff00, 0.3);
path.draw(graphics);
}
} }
} }

View File

@@ -1,5 +1,7 @@
package ru.m.puzzlez.render; package ru.m.puzzlez.render;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.net.Network;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.PNGEncoderOptions; import flash.display.PNGEncoderOptions;
import flash.display.Sprite; import flash.display.Sprite;
@@ -26,6 +28,13 @@ class Render extends SpriteView implements IRender {
public var manager(default, null):RenderManager; public var manager(default, null):RenderManager;
@:provide static var settings:SettingsStorage; @:provide static var settings:SettingsStorage;
@:provide static var network:Network;
private var playerId(get, never):PlayerId;
private function get_playerId():PlayerId {
return network.user.uuid;
}
private function get_scale():Float { private function get_scale():Float {
return tableView.scaleX; return tableView.scaleX;
@@ -76,6 +85,11 @@ class Render extends SpriteView implements IRender {
case CHANGE(PART_UPDATE(id, TABLE(point))): case CHANGE(PART_UPDATE(id, TABLE(point))):
var part:PartView = parts[id]; var part:PartView = parts[id];
part.position = point; 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)): case CHANGE(PART_UPDATE(id, IMAGE)):
var part:PartView = parts[id]; var part:PartView = parts[id];
part.complete(); part.complete();
@@ -189,21 +203,21 @@ class Render extends SpriteView implements IRender {
activePoint = RenderUtil.convertPoint(tableView.globalToLocal(point)); activePoint = RenderUtil.convertPoint(tableView.globalToLocal(point));
tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
signal.emit(ACTION(PART_TAKE(activePart.id))); signal.emit(ACTION(PART_TAKE(playerId, activePart.id)));
} }
} }
private function onMouseMove(event:MouseEvent):Void { private function onMouseMove(event:MouseEvent):Void {
var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY))); var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)));
var partPosition = activePart.position.add(newPoint).subtract(activePoint); var partPosition = activePart.position.add(newPoint).subtract(activePoint);
signal.emit(ACTION(PART_MOVE(activePart.id, partPosition.clone()))); signal.emit(ACTION(PART_MOVE(playerId, activePart.id, partPosition.clone())));
activePoint = newPoint; activePoint = newPoint;
} }
private function onMouseUp(event:MouseEvent):Void { private function onMouseUp(event:MouseEvent):Void {
var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY))); var newPoint:Point = RenderUtil.convertPoint(tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)));
var partPosition = activePart.position.add(newPoint).subtract(activePoint); var partPosition = activePart.position.add(newPoint).subtract(activePoint);
signal.emit(ACTION(PART_PUT(activePart.id, partPosition.clone()))); signal.emit(ACTION(PART_PUT(playerId, activePart.id, partPosition.clone())));
tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
activePart = null; activePart = null;

View File

@@ -8,7 +8,6 @@ import hw.geom.Point;
import hw.geom.Rectangle; import hw.geom.Rectangle;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.render.part.ClassicPartBuilder;
import ru.m.puzzlez.render.part.IPartBuilder; import ru.m.puzzlez.render.part.IPartBuilder;
import ru.m.puzzlez.render.part.PartMask; import ru.m.puzzlez.render.part.PartMask;
@@ -34,7 +33,7 @@ class RenderUtil {
{offset: new Point(1, 1), color: 0xcccccc, opacity: 0.4}, {offset: new Point(1, 1), color: 0xcccccc, opacity: 0.4},
]; ];
public static var builder(default, null):IPartBuilder = new ClassicPartBuilder(); @:provide static var builder:IPartBuilder;
public static function cropImage(source:BitmapData, rect:Rectangle):BitmapData { public static function cropImage(source:BitmapData, rect:Rectangle):BitmapData {
var image = new BitmapData(Std.int(rect.width), Std.int(rect.height)); var image = new BitmapData(Std.int(rect.width), Std.int(rect.height));

View File

@@ -4,6 +4,6 @@ import hw.geom.Rectangle;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
interface IPartBuilder { @:provide(ClassicPartBuilder) interface IPartBuilder {
public function build(rect:Rectangle, bound:PartBounds):DrawPath; public function build(rect:Rectangle, bound:PartBounds):DrawPath;
} }

View File

@@ -1,15 +1,17 @@
package ru.m.puzzlez.view.common; package ru.m.puzzlez.view.common;
import flash.display.BitmapData;
import flash.display.Graphics; import flash.display.Graphics;
import flash.display.BitmapData;
import flash.display.Shape; import flash.display.Shape;
import hw.view.group.GroupView; import hw.view.group.GroupView;
import ru.m.puzzlez.core.GameState; import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.render.part.IPartBuilder;
import ru.m.puzzlez.render.RenderUtil; import ru.m.puzzlez.render.RenderUtil;
import ru.m.puzzlez.storage.ImageStorage; import ru.m.puzzlez.storage.ImageStorage;
class PresetView extends GroupView { class PresetView extends GroupView {
@:provide var imageStorage:ImageStorage; @:provide var imageStorage:ImageStorage;
@:provide static var builder:IPartBuilder;
public var scale(get, set):Float; public var scale(get, set):Float;
@@ -67,7 +69,7 @@ class PresetView extends GroupView {
var rect = part.rect.clone(); var rect = part.rect.clone();
rect.x = part.gridX * part.rect.width; rect.x = part.gridX * part.rect.width;
rect.y = part.gridY * part.rect.height; rect.y = part.gridY * part.rect.height;
var path = RenderUtil.builder.build(rect, part.bounds); var path = builder.build(rect, part.bounds);
for (value in RenderUtil.borderSettings) { for (value in RenderUtil.borderSettings) {
graphics.lineStyle(1, value.color, value.opacity); graphics.lineStyle(1, value.color, value.opacity);
path.move(value.offset.x, value.offset.y).draw(graphics); path.move(value.offset.x, value.offset.y).draw(graphics);

View File

@@ -64,25 +64,37 @@ class Game implements IGame {
private function onGameEvent(event:GameEvent):Void { private function onGameEvent(event:GameEvent):Void {
switch event { switch event {
case ACTION(PART_MOVE(id, point)): case ACTION(PART_TAKE(playerId, partId)):
var part = partsById[id]; var part = partsById[partId];
part.location = TABLE(point); switch part.location {
signal.emit(CHANGE(PART_UPDATE(id, part.location))); case TABLE(point):
case ACTION(PART_PUT(id, point)): part.location = HAND(playerId, point);
var part:Part = partsById[id]; signal.emit(CHANGE(PART_UPDATE(partId, part.location)));
case _:
}
case ACTION(PART_MOVE(playerId, partId, point)):
var part = partsById[partId];
switch part.location {
case HAND(currentPlayerId, _) if (currentPlayerId == playerId):
part.location = HAND(playerId, point);
signal.emit(CHANGE(PART_UPDATE(partId, part.location)));
case _:
}
case ACTION(PART_PUT(playerId, partId, point)):
var part:Part = partsById[partId];
var target:Point = state.preset.imageRect.position.clone(); var target:Point = state.preset.imageRect.position.clone();
target = target.add(new Point(part.gridX * part.rect.width, part.gridY * part.rect.height)); target = target.add(new Point(part.gridX * part.rect.width, part.gridY * part.rect.height));
var d = distance(target, point); var d = distance(target, point);
if (d < 70) { if (d < 70) {
part.location = IMAGE; part.location = IMAGE;
signal.emit(CHANGE(PART_UPDATE(id, part.location))); signal.emit(CHANGE(PART_UPDATE(partId, part.location)));
if (checkIsComplete()) { if (checkIsComplete()) {
state.status = COMPLETE; state.status = COMPLETE;
signal.emit(COMPLETE); signal.emit(COMPLETE);
} }
} else { } else {
part.location = TABLE(point); part.location = TABLE(point);
signal.emit(CHANGE(PART_UPDATE(id, part.location))); signal.emit(CHANGE(PART_UPDATE(partId, part.location)));
} }
case _: case _:
} }

View File

@@ -1,11 +1,12 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import ru.m.puzzlez.core.Id;
import hw.geom.Point; import hw.geom.Point;
enum GameAction { enum GameAction {
PART_TAKE(id:Int); PART_TAKE(playerId:PlayerId, partId:PartId);
PART_MOVE(id:Int, point:Point); PART_MOVE(playerId:PlayerId, partId:PartId, point:Point);
PART_PUT(id:Int, point:Point); PART_PUT(playerId:PlayerId, partId:PartId, point:Point);
} }
enum GameChange { enum GameChange {

View File

@@ -24,3 +24,7 @@ abstract ImageId({source:SourceId, id:String}) {
return '${this.source}_${this.id}'; return '${this.source}_${this.id}';
} }
} }
typedef PlayerId = String;
typedef PartId = Int;

View File

@@ -1,9 +1,10 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import hw.geom.Point; import hw.geom.Point;
import ru.m.puzzlez.core.Id;
enum PartLocation { enum PartLocation {
//PANEL(index:Int); HAND(playerId:PlayerId, point:Point);
TABLE(point:Point); TABLE(point:Point);
IMAGE; IMAGE;
} }

View File

@@ -28,7 +28,7 @@ class PuzzlezServer extends ThreadServer<GameSession, Message> {
} }
override public function readClientMessage(session:GameSession, buf:Bytes, pos:Int, len:Int): ClientMessage<Message> { override public function readClientMessage(session:GameSession, buf:Bytes, pos:Int, len:Int): ClientMessage<Message> {
L.d(TAG, 'Client message: ${buf}'); //L.d(TAG, 'Client message: ${buf}');
return {msg: buf.sub(pos, len), bytes: len}; return {msg: buf.sub(pos, len), bytes: len};
} }
@@ -38,7 +38,6 @@ class PuzzlezServer extends ThreadServer<GameSession, Message> {
public static function main():Void { public static function main():Void {
L.push(new TraceLogger()); L.push(new TraceLogger());
L.d(TAG, 'Running');
L.i(TAG, 'Build: ${CompilationOption.get("build")}'); L.i(TAG, 'Build: ${CompilationOption.get("build")}');
var host:String = Sys.args().length > 0 ? Sys.args()[0] : "0.0.0.0"; var host:String = Sys.args().length > 0 ? Sys.args()[0] : "0.0.0.0";
var port:Int = Sys.args().length > 1 ? Std.parseInt(Sys.args()[1]) : 5000; var port:Int = Sys.args().length > 1 ? Std.parseInt(Sys.args()[1]) : 5000;