[refactor] GameEvent

This commit is contained in:
2020-02-03 22:44:52 +03:00
parent 05d02b44c7
commit 71d765c231
16 changed files with 136 additions and 90 deletions

View File

@@ -0,0 +1,7 @@
package ru.m.puzzlez.core;
enum BoundType {
NONE;
OUT;
IN;
}

View File

@@ -2,6 +2,8 @@ package ru.m.puzzlez.core;
import flash.geom.Point;
import haxework.signal.Signal;
import ru.m.puzzlez.core.GameEvent;
import ru.m.puzzlez.core.PartLocation;
class Game implements IGame {
public var state(default, null):GameState;
@@ -26,11 +28,14 @@ class Game implements IGame {
public function shuffle():Void {
for (part in state.parts) {
if (!part.completed) {
var bound = part.rect.width * 0.25;
part.rect.x = bound + Math.random() * (state.preset.tableRect.width - part.rect.width - bound * 2);
part.rect.y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2);
signal.emit(GameEvent.PART_MOVED(part.id, part.rect.topLeft));
switch part.location {
case TABLE(_):
var bound = part.rect.width * 0.25;
var x = bound + Math.random() * (state.preset.tableRect.width - part.rect.width - bound * 2);
var y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2);
part.location = TABLE(new Point(x, y));
signal.emit(CHANGE(PART_UPDATE(part.id, part.location)));
case _:
}
}
}
@@ -42,19 +47,21 @@ class Game implements IGame {
private function onGameEvent(event:GameEvent):Void {
switch event {
case GameEvent.PART_MOVE(id, position):
case ACTION(PART_MOVE(id, point)):
var part = partsById[id];
part.rect.topLeft = position;
signal.emit(GameEvent.PART_MOVED(id, position));
case GameEvent.PART_PUT(id, position):
var part = partsById[id];
var d = distance(part.position, position);
part.location = TABLE(point);
signal.emit(CHANGE(PART_UPDATE(id, part.location)));
case ACTION(PART_PUT(id, point)):
var part:Part = partsById[id];
var target:Point = state.preset.imageRect.topLeft.clone();
target = target.add(new Point(part.gridX * part.rect.width, part.gridY * part.rect.height));
var d = distance(target, point);
if (d < 70) {
part.completed = true;
part.rect.topLeft = part.position;
signal.emit(GameEvent.PART_COMPLETED(id, part.position));
part.location = IMAGE;
signal.emit(CHANGE(PART_UPDATE(id, part.location)));
} else {
signal.emit(GameEvent.PART_MOVED(id, position));
part.location = TABLE(point);
signal.emit(CHANGE(PART_UPDATE(id, part.location)));
}
case _:
}

View File

@@ -2,10 +2,19 @@ package ru.m.puzzlez.core;
import flash.geom.Point;
enum GameAction {
PART_TAKE(id:Int);
PART_MOVE(id:Int, point:Point);
PART_PUT(id:Int, point:Point);
}
enum GameChange {
PART_UPDATE(id:Int, location:PartLocation);
}
enum GameEvent {
START(state:GameState);
PART_MOVE(id:Int, position:Point);
PART_PUT(id:Int, position:Point);
PART_MOVED(id:Int, position:Point);
PART_COMPLETED(id:Int, position:Point);
ACTION(action:GameAction);
CHANGE(change:GameChange);
COMPLETE;
}

View File

@@ -1,9 +1,11 @@
package ru.m.puzzlez.core;
import ru.m.puzzlez.core.Id.ImageId;
import flash.geom.Point;
import flash.geom.Rectangle;
import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.core.Side;
class BoundsMap {
@@ -92,7 +94,7 @@ class GameUtil {
var boundsMap = new BoundsMap(preset.grid);
for (y in 0...preset.grid.height) {
for (x in 0...preset.grid.width) {
var bounds:Bounds = {
var bounds:PartBounds = {
left: boundsMap.getBound(x, y, LEFT),
right: boundsMap.getBound(x, y, RIGHT),
top: boundsMap.getBound(x, y, TOP),
@@ -116,10 +118,9 @@ class GameUtil {
id: id,
gridX: x,
gridY: y,
position: position,
rect: new Rectangle(position.x, position.y, partWidth, partHeight),
location: PartLocation.TABLE(position),
bounds: bounds,
completed: false,
rect: new Rectangle(0, 0, partWidth, partHeight),
});
}
}

View File

@@ -7,7 +7,10 @@ interface IGame {
public var signal(default, null):Signal<GameEvent>;
public function start():Void;
public function stop():Void;
public function shuffle():Void;
public function dispose():Void;
}

View File

@@ -4,9 +4,11 @@ typedef SourceId = String;
abstract ImageId({source:SourceId, id:String}) {
public var source(get, never):SourceId;
private inline function get_source():SourceId return this.source;
public var id(get, never):String;
private inline function get_id():String return this.id;
public function new(source:SourceId, id:String) {

View File

@@ -1,27 +1,13 @@
package ru.m.puzzlez.core;
import flash.geom.Point;
import flash.geom.Rectangle;
enum Side {
TOP;
LEFT;
RIGHT;
BOTTOM;
}
enum BoundType {
NONE;
OUT;
IN;
}
typedef PartBound = {
var spike: BoundType;
var side: BoundType;
var spike:BoundType;
var side:BoundType;
}
typedef Bounds = {
typedef PartBounds = {
var left:PartBound;
var right:PartBound;
var top:PartBound;
@@ -32,8 +18,7 @@ typedef Part = {
var id:Int;
var gridX:Int;
var gridY:Int;
var position:Point;
var location:PartLocation;
var bounds:PartBounds;
var rect:Rectangle;
var bounds:Bounds;
var completed:Bool;
}

View File

@@ -0,0 +1,9 @@
package ru.m.puzzlez.core;
import flash.geom.Point;
enum PartLocation {
//PANEL(index:Int);
TABLE(point:Point);
IMAGE;
}

View File

@@ -0,0 +1,8 @@
package ru.m.puzzlez.core;
enum Side {
TOP;
LEFT;
RIGHT;
BOTTOM;
}

View File

@@ -5,12 +5,14 @@ import flash.display.BitmapData;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.geom.Point;
import ru.m.puzzlez.core.Part;
class PartView extends Sprite {
public var id(default, null):Int;
public var position(default, set):Point;
public var completed(default, default):Bool;
public var target(default, null):Point;
private function set_position(value:Point):Point {
position = value.clone();
@@ -29,16 +31,14 @@ class PartView extends Sprite {
private var size:Point;
public function new(id:Int, image:BitmapData, size:Point) {
public function new(part:Part) {
super();
#if !android
filters = RenderUtil.buildFilters();
#end
this.id = id;
this.size = size;
if (image != null) {
this.image = image;
}
this.id = part.id;
this.size = part.rect.size.clone();
this.target = new Point(part.gridX * size.x, part.gridY * size.y);
}
private function redraw():Void {
@@ -52,8 +52,13 @@ class PartView extends Sprite {
}
}
public static function factory(id:Int, image:BitmapData, size:Point):PartView {
return new SpritePartView(id, image, size);
public function complete():Void {
position = target;
completed = true;
}
public static function factory(part:Part):PartView {
return new SpritePartView(part);
}
}
@@ -70,9 +75,9 @@ class SpritePartView extends PartView {
class BitmapPartView extends PartView {
private var bitmap:Bitmap;
public function new(id:Int, image:BitmapData, size:Point) {
super(id, image, size);
bitmap = new Bitmap(image, PixelSnapping.AUTO, true);
public function new(part) {
super(part);
bitmap = new Bitmap(null, PixelSnapping.AUTO, true);
addChild(bitmap);
}

View File

@@ -12,6 +12,7 @@ import haxework.signal.Signal;
import haxework.view.SpriteView;
import ru.m.puzzlez.core.GameEvent;
import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.PartLocation;
import ru.m.puzzlez.storage.ImageStorage;
class Render extends SpriteView implements IRender {
@@ -20,13 +21,13 @@ class Render extends SpriteView implements IRender {
public var scale(get, set):Float;
private function get_scale():Float {
return table.scaleX;
return tableView.scaleX;
}
private function set_scale(value:Float):Float {
var result = table.scaleX = table.scaleY = value;
table.x = (width - state.preset.tableRect.width * value) / 2;
table.y = (height - state.preset.tableRect.height * value) / 2;
var result = tableView.scaleX = tableView.scaleY = value;
tableView.x = (width - state.preset.tableRect.width * value) / 2;
tableView.y = (height - state.preset.tableRect.height * value) / 2;
//setSize(table.width, table.height, 'table');
return result;
}
@@ -35,7 +36,8 @@ class Render extends SpriteView implements IRender {
private var image:BitmapData;
private var progress:ProgressView;
private var table:Sprite;
private var tableView:Sprite;
private var imageView:Sprite;
private var parts:Map<Int, PartView>;
private var activePart:PartView;
private var activePoint:Point;
@@ -46,9 +48,11 @@ class Render extends SpriteView implements IRender {
super();
progress = new ProgressView();
signal = new Signal();
table = new Sprite();
table.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
content.addChild(table);
tableView = new Sprite();
tableView.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
imageView = new Sprite();
tableView.addChild(imageView);
content.addChild(tableView);
parts = new Map();
}
@@ -56,14 +60,13 @@ class Render extends SpriteView implements IRender {
switch event {
case START(state):
onStart(state);
case PART_MOVED(id, point):
case CHANGE(PART_UPDATE(id, TABLE(point))):
var part:PartView = parts[id];
part.position = point;
case PART_COMPLETED(id, point):
case CHANGE(PART_UPDATE(id, IMAGE)):
var part:PartView = parts[id];
part.position = point;
part.completed = true;
table.setChildIndex(part, 0);
part.complete();
imageView.addChild(part);
case _:
}
}
@@ -72,18 +75,20 @@ class Render extends SpriteView implements IRender {
clean();
this.state = state;
for (part in state.parts) {
var partView = PartView.factory(part.id, null, part.rect.size);
var partView = PartView.factory(part);
partView.position = part.rect.topLeft;
parts.set(part.id, partView);
table.addChild(partView);
tableView.addChild(partView);
}
table.graphics.clear();
table.graphics.lineStyle(2, 0xCCCCCC);
table.graphics.beginFill(0x555555);
table.graphics.drawRect(state.preset.imageRect.x, state.preset.imageRect.y, state.preset.imageRect.width, state.preset.imageRect.height);
table.graphics.endFill();
table.graphics.lineStyle();
imageView.x = state.preset.imageRect.x;
imageView.y = state.preset.imageRect.y;
imageView.graphics.clear();
imageView.graphics.lineStyle(2, 0xCCCCCC);
imageView.graphics.beginFill(0x555555);
imageView.graphics.drawRect(0, 0, state.preset.imageRect.width, state.preset.imageRect.height);
imageView.graphics.endFill();
imageView.graphics.lineStyle();
progress.text = "Loading image";
content.addChild(progress.content);
imageStorage.resolve(state.preset.image).then(onImageResolved);
@@ -119,26 +124,27 @@ class Render extends SpriteView implements IRender {
return;
}
activePart = part;
table.setChildIndex(activePart, table.numChildren - 1);
activePoint = table.globalToLocal(new Point(event.stageX, event.stageY));
table.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
table.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
tableView.setChildIndex(activePart, tableView.numChildren - 1);
activePoint = tableView.globalToLocal(new Point(event.stageX, event.stageY));
tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
signal.emit(ACTION(PART_TAKE(activePart.id)));
}
}
private function onMouseMove(event:MouseEvent):Void {
var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY));
var newPoint = tableView.globalToLocal(new Point(event.stageX, event.stageY));
var partPosition = activePart.position.add(newPoint).subtract(activePoint);
signal.emit(GameEvent.PART_MOVE(activePart.id, partPosition.clone()));
signal.emit(ACTION(PART_MOVE(activePart.id, partPosition.clone())));
activePoint = newPoint;
}
private function onMouseUp(event:MouseEvent):Void {
var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY));
var newPoint = tableView.globalToLocal(new Point(event.stageX, event.stageY));
var partPosition = activePart.position.add(newPoint).subtract(activePoint);
signal.emit(GameEvent.PART_PUT(activePart.id, partPosition.clone()));
table.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
table.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
signal.emit(ACTION(PART_PUT(activePart.id, partPosition.clone())));
tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
//save(activePart);
activePart = null;
activePoint = null;
@@ -154,7 +160,9 @@ class Render extends SpriteView implements IRender {
private function clean() {
for (partView in parts) {
table.removeChild(partView);
if (partView.parent != null) {
partView.parent.removeChild(partView);
}
}
parts = new Map();
}

View File

@@ -20,7 +20,7 @@ class BaseMaskBuilder implements IPartMaskBuilder {
private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void {
}
public function build(rect:Rectangle, bounds:Bounds):DrawPath {
public function build(rect:Rectangle, bounds:PartBounds):DrawPath {
var path:DrawPath = {
commands: new Vector<GraphicsPathCommand>(),
data: new Vector<Float>(),

View File

@@ -1,6 +1,7 @@
package ru.m.puzzlez.render.mask;
import flash.display.GraphicsPathCommand;
import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.render.mask.IPartMaskBuilder;

View File

@@ -11,5 +11,5 @@ typedef DrawPath = {
}
interface IPartMaskBuilder {
public function build(rect:Rectangle, bound:Bounds):DrawPath;
public function build(rect:Rectangle, bound:PartBounds):DrawPath;
}

View File

@@ -11,7 +11,7 @@ class PartMask extends Shape {
private static var builder:IPartMaskBuilder = new ClassicMaskBuilder();
public function new(rect:Rectangle, bounds:Bounds) {
public function new(rect:Rectangle, bounds:PartBounds) {
super();
this.rect = rect.clone();
var offset = rect.width / 4 + rect.width * 0.05;

View File

@@ -1,6 +1,7 @@
package ru.m.puzzlez.render.mask;
import flash.display.GraphicsPathCommand;
import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.render.mask.IPartMaskBuilder;