[update] (render) add PartView

This commit is contained in:
2020-01-13 17:47:55 +03:00
parent 99ebedabd6
commit 081f8ade75
13 changed files with 145 additions and 77 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@@ -1,5 +1,8 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Point;
enum GameEvent { enum GameEvent {
START(state:GameState); START(state:GameState);
PART_MOVE(id:Int, position:Point);
} }

View File

@@ -1,6 +1,10 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Rectangle;
typedef GamePreset = { typedef GamePreset = {
var image:String; var image:String;
var grid:Grid; var grid:Grid;
var tableRect:Rectangle;
var imageRect:Rectangle;
} }

View File

@@ -2,4 +2,5 @@ package ru.m.puzzlez.core;
typedef GameState = { typedef GameState = {
var preset:GamePreset; var preset:GamePreset;
var parts:Array<Part>;
} }

View File

@@ -1,10 +1,37 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Rectangle;
class GameUtil { class GameUtil {
public static function buildPreset(image:String):GamePreset {
return {
image:image,
grid: {width: 8, height: 8},
tableRect: new Rectangle(0, 0, 0, 0),
imageRect: new Rectangle(0, 0, 2304, 2304),
}
}
public static function buildState(preset:GamePreset):GameState { public static function buildState(preset:GamePreset):GameState {
var parts:Array<Part> = [];
var partWidth = preset.imageRect.width / preset.grid.width;
var partHeight = preset.imageRect.height / preset.grid.height;
var offset = 5;
for (x in 0...preset.grid.width) {
for (y in 0...preset.grid.height) {
var id = (x << 16) + y;
parts.push({
id: id,
gridX: x,
gridY: y,
rect: new Rectangle(offset + x * (partWidth + offset), offset + y * (partHeight + offset), partWidth, partHeight),
});
}
}
return { return {
preset: preset, preset: preset,
parts: parts,
} }
} }
} }

View File

@@ -1,6 +1,10 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Rectangle;
typedef Part = { typedef Part = {
var x:Int; var id:Int;
var y:Int; var gridX:Int;
var gridY:Int;
var rect:Rectangle;
} }

View File

@@ -1,8 +1,10 @@
package ru.m.puzzlez.render; package ru.m.puzzlez.render;
import haxework.signal.Signal;
import haxework.view.IView; import haxework.view.IView;
import ru.m.puzzlez.core.GameEvent; import ru.m.puzzlez.core.GameEvent;
interface IRender extends IView<Dynamic> { interface IRender extends IView<Dynamic> {
public var signal(default, null):Signal<GameEvent>;
public function onGameEvent(event:GameEvent):Void; public function onGameEvent(event:GameEvent):Void;
} }

View File

@@ -0,0 +1,20 @@
package ru.m.puzzlez.render;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
class PartView extends Sprite {
public var id(default, null):Int;
private var bitmap:Bitmap;
public function new(id:Int, image:BitmapData) {
super();
this.id = id;
bitmap = new Bitmap();
bitmap.bitmapData = image;
addChild(bitmap);
}
}

View File

@@ -1,6 +1,6 @@
package ru.m.puzzlez.render; package ru.m.puzzlez.render;
import flash.display.Bitmap; import haxework.signal.Signal;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.Sprite; import flash.display.Sprite;
import flash.events.MouseEvent; import flash.events.MouseEvent;
@@ -12,67 +12,69 @@ import ru.m.puzzlez.core.GameState;
class Render extends SpriteView implements IRender { class Render extends SpriteView implements IRender {
public var signal(default, null):Signal<GameEvent>;
private var state:GameState; private var state:GameState;
private var image:BitmapData; private var image:BitmapData;
private var table:Sprite; private var table:Sprite;
private var parts:Array<Bitmap>; private var parts:Map<Int, PartView>;
private var activePart:Bitmap; private var activePart:PartView;
private var activePoint:Point; private var activePoint:Point;
public function new() { public function new() {
super(); super();
signal = new Signal();
table = new Sprite(); table = new Sprite();
table.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); table.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
content.addChild(table); content.addChild(table);
parts = []; parts = new Map();
} }
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
switch event { switch event {
case START(state): onStart(state); case START(state):
onStart(state);
case PART_MOVE(id, point):
var part = parts[id];
part.x = point.x;
part.y = point.y;
} }
} }
private function onStart(state:GameState):Void { private function onStart(state:GameState):Void {
clean(); clean();
image = Assets.getBitmapData(state.preset.image); image = Assets.getBitmapData(state.preset.image);
image = RenderUtil.cropImage(image, state.preset.grid); image = RenderUtil.cropImage(image, state.preset.imageRect);
var partWidth = image.width / state.preset.grid.width + 2; for (part in state.parts) {
var partHeight = image.height / state.preset.grid.height + 2; var partImage = RenderUtil.cropImagePart(image, part.gridX, part.gridY, part.rect);
for (x in 0...state.preset.grid.width) { var partView = new PartView(part.id, partImage);
for (y in 0...state.preset.grid.height) { partView.x = part.rect.x;
var partImage = RenderUtil.cropImagePart(image, state.preset.grid, x, y); partView.y = part.rect.y;
var bitmap = new Bitmap(partImage); parts.set(part.id, partView);
bitmap.x = 5 + partWidth * x; table.addChild(partView);
bitmap.y = 5 + partHeight * y;
parts.push(bitmap);
table.addChild(bitmap);
}
} }
table.graphics.clear();
table.graphics.beginFill(0xffff00, 1);
table.graphics.drawRect(0, 0, image.width, image.height);
table.graphics.endFill();
table.scaleX = table.scaleY = 0.25; table.scaleX = table.scaleY = 0.25;
} }
private function onMouseDown(event:MouseEvent):Void { private function onMouseDown(event:MouseEvent):Void {
for (part in parts) { if (Std.is(event.target, PartView)) {
if (part.x < event.localX && part.x + part.width > event.localX && part.y < event.localY && part.y + width > event.localY) { activePart = event.target;
activePart = part; table.setChildIndex(activePart, table.numChildren - 1);
table.setChildIndex(activePart, table.numChildren - 1); activePoint = table.globalToLocal(new Point(event.stageX, event.stageY));
activePoint = new Point(event.localX - part.x, event.localY - part.y); table.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
table.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); table.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
table.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
break;
}
} }
} }
private function onMouseMove(event:MouseEvent):Void { private function onMouseMove(event:MouseEvent):Void {
activePart.x = event.localX - activePoint.x; var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY));
activePart.y = event.localY - activePoint.y; var partPosition = new Point(
activePart.x + newPoint.x - activePoint.x,
activePart.y + newPoint.y - activePoint.y
);
signal.emit(GameEvent.PART_MOVE(activePart.id, partPosition));
activePoint = newPoint;
} }
private function onMouseUp(event:MouseEvent):Void { private function onMouseUp(event:MouseEvent):Void {
@@ -83,9 +85,9 @@ class Render extends SpriteView implements IRender {
} }
private function clean() { private function clean() {
for (bitmap in parts) { for (partView in parts) {
table.removeChild(bitmap); table.removeChild(partView);
} }
parts = []; parts = new Map();
} }
} }

View File

@@ -1,41 +1,27 @@
package ru.m.puzzlez.render; package ru.m.puzzlez.render;
import flash.geom.Matrix;
import flash.display.BitmapData; import flash.display.BitmapData;
import ru.m.puzzlez.core.Grid; import flash.geom.Matrix;
import flash.geom.Rectangle; import flash.geom.Rectangle;
class RenderUtil { class RenderUtil {
public static function buildRectangle(source:Rectangle, grid:Grid):Rectangle { public static function cropImage(source:BitmapData, rect:Rectangle):BitmapData {
var r1 = grid.width / grid.height;
var r2 = source.width / source.height;
if (r1 > r2) {
var height = source.width * r1;
return new Rectangle(0, (source.height - height) / 2, source.width, height);
} else {
var width = source.height * r1;
return new Rectangle((source.width - width) / 2, 0, width, source.height);
}
}
public static function cropImage(source:BitmapData, grid:Grid):BitmapData {
var rect = buildRectangle(new Rectangle(0, 0, source.width, source.height), grid);
var image = new BitmapData(Std.int(rect.width), Std.int(rect.height)); var image = new BitmapData(Std.int(rect.width), Std.int(rect.height));
var matrix = new Matrix(); var matrix = new Matrix();
matrix.translate(-rect.x, -rect.y); var scale = Math.max(rect.width / source.width, rect.height / source.height);
matrix.scale(scale, scale);
matrix.translate((rect.width - source.width * scale) / 2, (rect.height - source.height * scale) / 2);
image.draw(source, matrix); image.draw(source, matrix);
return image; return image;
} }
public static function cropImagePart(source:BitmapData, grid:Grid, x:Int, y:Int):BitmapData { public static function cropImagePart(source:BitmapData, gridX:Int, gridY:Int, rect:Rectangle):BitmapData {
var partWidth = source.width / grid.width; var rect = new Rectangle(rect.width * gridX, rect.height * gridY, rect.width, rect.width);
var partHeight = source.height / grid.height; var image = new BitmapData(Std.int(rect.width), Std.int(rect.width));
var rect = new Rectangle(partWidth * x, partHeight * y, partWidth, partHeight);
var image = new BitmapData(Std.int(partWidth), Std.int(partHeight));
var matrix = new Matrix(); var matrix = new Matrix();
matrix.translate(-rect.x, -rect.y); matrix.translate(-rect.x, -rect.y);
image.draw(source, matrix); image.draw(source, matrix, null, null, null, true);
return image; return image;
} }

View File

@@ -1,12 +1,13 @@
package ru.m.puzzlez.view; package ru.m.puzzlez.view;
import haxework.view.utils.DrawUtil.FillType;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.group.VGroupView; import haxework.view.group.VGroupView;
import haxework.view.ImageView; import haxework.view.ImageView;
import haxework.view.utils.DrawUtil;
import openfl.utils.Assets; import openfl.utils.Assets;
import openfl.utils.AssetType; import openfl.utils.AssetType;
import ru.m.puzzlez.core.Game; import ru.m.puzzlez.core.Game;
import ru.m.puzzlez.core.GameUtil;
import ru.m.puzzlez.core.IGame; import ru.m.puzzlez.core.IGame;
import ru.m.puzzlez.render.IRender; import ru.m.puzzlez.render.IRender;
@@ -33,13 +34,15 @@ import ru.m.puzzlez.render.IRender;
public function start(image:String):Void { public function start(image:String):Void {
stop(); stop();
game = new Game({image:image, grid: {width: 7, height: 5}}); game = new Game(GameUtil.buildPreset(image));
game.signal.connect(render.onGameEvent); game.signal.connect(render.onGameEvent);
render.signal.connect(game.signal.emit);
game.start(); game.start();
} }
public function stop():Void { public function stop():Void {
if (game != null) { if (game != null) {
render.signal.disconnect(game.signal.emit);
game.stop(); game.stop();
game.dispose(); game.dispose();
game = null; game = null;

View File

@@ -5,18 +5,21 @@ views:
- $type: haxework.view.form.LabelView - $type: haxework.view.form.LabelView
text: Puzzle'z text: Puzzle'z
font.size: 42 font.size: 42
- id: images - $type: haxework.view.group.HGroupView
$type: haxework.view.data.DataView geometry.stretch: true
layout: views:
$type: haxework.view.layout.HorizontalLayout - id: images
geometry.width: 100% $type: haxework.view.data.DataView
# geometry.height: 100 layout:
factory: ~imageViewFactory $type: haxework.view.layout.VerticalLayout
+onDataSelect: ~start geometry.height: 100%
geometry.margin: 5 # geometry.height: 100
- id: render factory: ~imageViewFactory
$type: ru.m.puzzlez.render.Render +onDataSelect: ~start
geometry.width: 100% geometry.margin: 5
geometry.height: 100% - id: render
geometry.margin: 5 $type: ru.m.puzzlez.render.Render
style: frame geometry.width: 100%
geometry.height: 100%
geometry.margin: 5
style: frame

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB