diff --git a/src/haxe/ru/m/puzzlez/core/Game.hx b/src/haxe/ru/m/puzzlez/core/Game.hx index 866ddd4..e5c8a6c 100644 --- a/src/haxe/ru/m/puzzlez/core/Game.hx +++ b/src/haxe/ru/m/puzzlez/core/Game.hx @@ -1,20 +1,49 @@ package ru.m.puzzlez.core; +import flash.geom.Point; import haxework.signal.Signal; class Game implements IGame { public var state(default, null):GameState; public var signal(default, null):Signal; + private var partsById:Map; + public function new(preset:GamePreset) { state = GameUtil.buildState(preset); + partsById = new Map(); + for (part in state.parts) { + partsById[part.id] = part; + } signal = new Signal(); + signal.connect(onGameEvent); } public function start():Void { signal.emit(GameEvent.START(state)); } + private static function distance(a:Point, b:Point):Float { + var diff = a.subtract(b); + return Math.abs(diff.x) + Math.abs(diff.y); + } + + private function onGameEvent(event:GameEvent):Void { + switch event { + case GameEvent.PART_MOVE(id, position): + signal.emit(GameEvent.PART_MOVED(id, position)); + case GameEvent.PART_PUT(id, position): + var part = partsById[id]; + var d = distance(part.position, position); + if (d < 50) { + signal.emit(GameEvent.PART_MOVED(id, part.position)); + } else { + signal.emit(GameEvent.PART_MOVED(id, position)); + } + case _: + } + } + public function stop():Void { } diff --git a/src/haxe/ru/m/puzzlez/core/GameEvent.hx b/src/haxe/ru/m/puzzlez/core/GameEvent.hx index ed13b58..2e389ae 100644 --- a/src/haxe/ru/m/puzzlez/core/GameEvent.hx +++ b/src/haxe/ru/m/puzzlez/core/GameEvent.hx @@ -5,4 +5,6 @@ import flash.geom.Point; enum GameEvent { START(state:GameState); PART_MOVE(id:Int, position:Point); + PART_PUT(id:Int, position:Point); + PART_MOVED(id:Int, position:Point); } diff --git a/src/haxe/ru/m/puzzlez/core/GameUtil.hx b/src/haxe/ru/m/puzzlez/core/GameUtil.hx index 4fd85fb..a583ec3 100644 --- a/src/haxe/ru/m/puzzlez/core/GameUtil.hx +++ b/src/haxe/ru/m/puzzlez/core/GameUtil.hx @@ -1,8 +1,9 @@ package ru.m.puzzlez.core; +import flash.geom.Point; +import flash.geom.Rectangle; import ru.m.puzzlez.core.Part.Bounds; import ru.m.puzzlez.core.Part.BoundType; -import flash.geom.Rectangle; class GameUtil { @@ -10,7 +11,7 @@ class GameUtil { return { image:image, grid: {width: 8, height: 8}, - tableRect: new Rectangle(0, 0, 0, 0), + tableRect: new Rectangle(0, 0, 1128, 1128), //imageRect: new Rectangle(0, 0, 2304, 2304), imageRect: new Rectangle(0, 0, 1024, 1024), } @@ -20,7 +21,10 @@ class GameUtil { var parts:Array = []; var partWidth = preset.imageRect.width / preset.grid.width; var partHeight = preset.imageRect.height / preset.grid.height; - var offset = 0; + var topLeft = new Point( + (preset.tableRect.width - preset.imageRect.width) / 2, + (preset.tableRect.height - preset.imageRect.height) / 2 + ); for (x in 0...preset.grid.width) { for (y in 0...preset.grid.height) { var bounds:Bounds = { @@ -42,11 +46,13 @@ class GameUtil { bounds.bottom = BoundType.NONE; } var id = (x << 16) + y; + var position = new Point(topLeft.x + x * partWidth, topLeft.y + y * partHeight); parts.push({ id: id, gridX: x, gridY: y, - rect: new Rectangle(offset + x * (partWidth + offset), offset + y * (partHeight + offset), partWidth, partHeight), + position: position, + rect: new Rectangle(position.x, position.y, partWidth, partHeight), bounds: bounds }); } diff --git a/src/haxe/ru/m/puzzlez/core/Part.hx b/src/haxe/ru/m/puzzlez/core/Part.hx index aff47f4..ce8e4e3 100644 --- a/src/haxe/ru/m/puzzlez/core/Part.hx +++ b/src/haxe/ru/m/puzzlez/core/Part.hx @@ -1,5 +1,6 @@ package ru.m.puzzlez.core; +import flash.geom.Point; import flash.geom.Rectangle; enum BoundType { @@ -19,6 +20,7 @@ typedef Part = { var id:Int; var gridX:Int; var gridY:Int; + var position:Point; var rect:Rectangle; var bounds:Bounds; } diff --git a/src/haxe/ru/m/puzzlez/render/IRender.hx b/src/haxe/ru/m/puzzlez/render/IRender.hx index e54ddd0..80de569 100644 --- a/src/haxe/ru/m/puzzlez/render/IRender.hx +++ b/src/haxe/ru/m/puzzlez/render/IRender.hx @@ -6,5 +6,6 @@ import ru.m.puzzlez.core.GameEvent; interface IRender extends IView { public var signal(default, null):Signal; + public var scale(get, set):Float; public function onGameEvent(event:GameEvent):Void; } diff --git a/src/haxe/ru/m/puzzlez/render/PartView.hx b/src/haxe/ru/m/puzzlez/render/PartView.hx index 028a0c3..bc79491 100644 --- a/src/haxe/ru/m/puzzlez/render/PartView.hx +++ b/src/haxe/ru/m/puzzlez/render/PartView.hx @@ -1,5 +1,6 @@ package ru.m.puzzlez.render; +import flash.geom.Point; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; @@ -7,14 +8,25 @@ import flash.display.Sprite; class PartView extends Sprite { public var id(default, null):Int; + public var position(default, set):Point; + private function set_position(value:Point):Point { + position = value.clone(); + x = position.x - (bitmap.bitmapData.width - size.x) / 2; + y = position.y - (bitmap.bitmapData.height - size.y) / 2; + return position; + } + + private var size:Point; private var bitmap:Bitmap; - public function new(id:Int, image:BitmapData) { + public function new(id:Int, image:BitmapData, size:Point) { super(); this.id = id; + this.size = size; bitmap = new Bitmap(); bitmap.bitmapData = image; addChild(bitmap); } + } diff --git a/src/haxe/ru/m/puzzlez/render/Render.hx b/src/haxe/ru/m/puzzlez/render/Render.hx index 4dfd796..2a5f622 100644 --- a/src/haxe/ru/m/puzzlez/render/Render.hx +++ b/src/haxe/ru/m/puzzlez/render/Render.hx @@ -13,6 +13,17 @@ import ru.m.puzzlez.core.GameState; class Render extends SpriteView implements IRender { public var signal(default, null):Signal; + public var scale(get, set):Float; + + private function get_scale():Float { + return table.scaleX; + } + + private function set_scale(value:Float):Float { + var result = table.scaleX = table.scaleY = value; + setSize(table.width, table.height, 'table'); + return result; + } private var state:GameState; private var image:BitmapData; @@ -35,10 +46,10 @@ class Render extends SpriteView implements IRender { switch event { case START(state): onStart(state); - case PART_MOVE(id, point): - var part = parts[id]; - part.x = point.x; - part.y = point.y; + case PART_MOVED(id, point): + var part:PartView = parts[id]; + part.position = point; + case _: } } @@ -48,13 +59,18 @@ class Render extends SpriteView implements IRender { image = RenderUtil.cropImage(image, state.preset.imageRect); for (part in state.parts) { var partImage = RenderUtil.cropImagePart(image, part); - var partView = new PartView(part.id, partImage); - partView.x = part.rect.x; - partView.y = part.rect.y; + var partView = new PartView(part.id, partImage, part.rect.size); + partView.position = part.rect.topLeft; parts.set(part.id, partView); table.addChild(partView); } - table.scaleX = table.scaleY = 0.5; + scale = scale; + table.graphics.lineStyle(2, 0xCCCCCC); + table.graphics.beginFill(0x555555); + table.graphics.drawRect(state.preset.tableRect.x, state.preset.tableRect.y, state.preset.tableRect.width, state.preset.tableRect.height); + table.graphics.endFill(); + table.graphics.lineStyle(); + toUpdate(); } private function onMouseDown(event:MouseEvent):Void { @@ -69,15 +85,15 @@ class Render extends SpriteView implements IRender { private function onMouseMove(event:MouseEvent):Void { var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY)); - var partPosition = new Point( - activePart.x + newPoint.x - activePoint.x, - activePart.y + newPoint.y - activePoint.y - ); - signal.emit(GameEvent.PART_MOVE(activePart.id, partPosition)); + var partPosition = activePart.position.add(newPoint).subtract(activePoint); + signal.emit(GameEvent.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 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); activePart = null; diff --git a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx index ea6004d..fee5df0 100644 --- a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx +++ b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx @@ -33,13 +33,14 @@ class RenderUtil { var matrix = new Matrix(); matrix.translate(-mask.rect.x, -mask.rect.y); image.draw(canvas, matrix); - var borderWidth = image.width * 0.05; + var borderWidth = image.width * 0.02; var borderAlpha = 1.0; #if flash borderWidth /= 3; - borderAlpha = 0.5; + //borderAlpha = 0.5; #end - image.applyFilter(image, image.rect, new Point(), new GlowFilter(0xffffff, borderAlpha, borderWidth, borderWidth, 8, 1, true)); + image.applyFilter(image, image.rect, new Point(), new GlowFilter(0xffffff, 0.3, borderWidth, borderWidth, 8, 1, true)); + image.applyFilter(image, image.rect, new Point(), new GlowFilter(0x555555, 0.3, borderWidth / 2, borderWidth / 2, 16, 1, true)); return image; } diff --git a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.hx b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.hx index 9833fb4..567e274 100644 --- a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.hx +++ b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.hx @@ -3,6 +3,7 @@ package ru.m.puzzlez.view; import haxework.view.data.DataView; import haxework.view.group.VGroupView; import haxework.view.ImageView; +import haxework.view.list.ScrollBarView; import haxework.view.utils.DrawUtil; import openfl.utils.Assets; import openfl.utils.AssetType; @@ -13,6 +14,7 @@ import ru.m.puzzlez.render.IRender; @:template class PuzzlezAppView extends VGroupView { + @:view private var scale:ScrollBarView; @:view private var images:DataView; @:view private var render:IRender; private var game:IGame; @@ -20,6 +22,7 @@ import ru.m.puzzlez.render.IRender; public function new() { super(); images.data = Assets.list(AssetType.IMAGE); + scale.position = render.scale - scale.ratio; } private function imageViewFactory(index:Int, image:String):ImageView { @@ -32,6 +35,10 @@ import ru.m.puzzlez.render.IRender; return result; } + public function setScale(value:Float):Void { + render.scale = value + scale.ratio; + } + public function start(image:String):Void { stop(); game = new Game(GameUtil.buildPreset(image)); diff --git a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml index 3b083c2..5b49ae3 100644 --- a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml +++ b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml @@ -7,19 +7,28 @@ views: font.size: 42 - $type: haxework.view.group.HGroupView geometry.stretch: true + geometry.margin: 5 views: - id: images $type: haxework.view.data.DataView layout: $type: haxework.view.layout.VerticalLayout + margin: 5 geometry.height: 100% # geometry.height: 100 factory: ~imageViewFactory +onDataSelect: ~start geometry.margin: 5 - - id: render - $type: ru.m.puzzlez.render.Render + - id: scale + $type: haxework.view.list.VScrollBarView + ratio: 0.5 + +onScroll: ~setScale + - $type: haxework.view.group.GroupView + style: frame geometry.width: 100% geometry.height: 100% - geometry.margin: 5 - style: frame + overflow.x: scroll + overflow.y: scroll + views: + - id: render + $type: ru.m.puzzlez.render.Render