[improve] Render

This commit is contained in:
2020-01-14 17:50:59 +03:00
parent 036300b779
commit c1ba14539d
10 changed files with 110 additions and 25 deletions

View File

@@ -1,20 +1,49 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Point;
import haxework.signal.Signal; import haxework.signal.Signal;
class Game implements IGame { class Game implements IGame {
public var state(default, null):GameState; public var state(default, null):GameState;
public var signal(default, null):Signal<GameEvent>; public var signal(default, null):Signal<GameEvent>;
private var partsById:Map<Int, Part>;
public function new(preset:GamePreset) { public function new(preset:GamePreset) {
state = GameUtil.buildState(preset); state = GameUtil.buildState(preset);
partsById = new Map();
for (part in state.parts) {
partsById[part.id] = part;
}
signal = new Signal(); signal = new Signal();
signal.connect(onGameEvent);
} }
public function start():Void { public function start():Void {
signal.emit(GameEvent.START(state)); 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 { public function stop():Void {
} }

View File

@@ -5,4 +5,6 @@ import flash.geom.Point;
enum GameEvent { enum GameEvent {
START(state:GameState); START(state:GameState);
PART_MOVE(id:Int, position:Point); PART_MOVE(id:Int, position:Point);
PART_PUT(id:Int, position:Point);
PART_MOVED(id:Int, position:Point);
} }

View File

@@ -1,8 +1,9 @@
package ru.m.puzzlez.core; 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.Bounds;
import ru.m.puzzlez.core.Part.BoundType; import ru.m.puzzlez.core.Part.BoundType;
import flash.geom.Rectangle;
class GameUtil { class GameUtil {
@@ -10,7 +11,7 @@ class GameUtil {
return { return {
image:image, image:image,
grid: {width: 8, height: 8}, 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, 2304, 2304),
imageRect: new Rectangle(0, 0, 1024, 1024), imageRect: new Rectangle(0, 0, 1024, 1024),
} }
@@ -20,7 +21,10 @@ class GameUtil {
var parts:Array<Part> = []; var parts:Array<Part> = [];
var partWidth = preset.imageRect.width / preset.grid.width; var partWidth = preset.imageRect.width / preset.grid.width;
var partHeight = preset.imageRect.height / preset.grid.height; 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 (x in 0...preset.grid.width) {
for (y in 0...preset.grid.height) { for (y in 0...preset.grid.height) {
var bounds:Bounds = { var bounds:Bounds = {
@@ -42,11 +46,13 @@ class GameUtil {
bounds.bottom = BoundType.NONE; bounds.bottom = BoundType.NONE;
} }
var id = (x << 16) + y; var id = (x << 16) + y;
var position = new Point(topLeft.x + x * partWidth, topLeft.y + y * partHeight);
parts.push({ parts.push({
id: id, id: id,
gridX: x, gridX: x,
gridY: y, 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 bounds: bounds
}); });
} }

View File

@@ -1,5 +1,6 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
import flash.geom.Point;
import flash.geom.Rectangle; import flash.geom.Rectangle;
enum BoundType { enum BoundType {
@@ -19,6 +20,7 @@ typedef Part = {
var id:Int; var id:Int;
var gridX:Int; var gridX:Int;
var gridY:Int; var gridY:Int;
var position:Point;
var rect:Rectangle; var rect:Rectangle;
var bounds:Bounds; var bounds:Bounds;
} }

View File

@@ -6,5 +6,6 @@ import ru.m.puzzlez.core.GameEvent;
interface IRender extends IView<Dynamic> { interface IRender extends IView<Dynamic> {
public var signal(default, null):Signal<GameEvent>; public var signal(default, null):Signal<GameEvent>;
public var scale(get, set):Float;
public function onGameEvent(event:GameEvent):Void; public function onGameEvent(event:GameEvent):Void;
} }

View File

@@ -1,5 +1,6 @@
package ru.m.puzzlez.render; package ru.m.puzzlez.render;
import flash.geom.Point;
import flash.display.Bitmap; import flash.display.Bitmap;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.Sprite; import flash.display.Sprite;
@@ -7,14 +8,25 @@ import flash.display.Sprite;
class PartView extends Sprite { class PartView extends Sprite {
public var id(default, null):Int; 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; private var bitmap:Bitmap;
public function new(id:Int, image:BitmapData) { public function new(id:Int, image:BitmapData, size:Point) {
super(); super();
this.id = id; this.id = id;
this.size = size;
bitmap = new Bitmap(); bitmap = new Bitmap();
bitmap.bitmapData = image; bitmap.bitmapData = image;
addChild(bitmap); addChild(bitmap);
} }
} }

View File

@@ -13,6 +13,17 @@ 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>; public var signal(default, null):Signal<GameEvent>;
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 state:GameState;
private var image:BitmapData; private var image:BitmapData;
@@ -35,10 +46,10 @@ class Render extends SpriteView implements IRender {
switch event { switch event {
case START(state): case START(state):
onStart(state); onStart(state);
case PART_MOVE(id, point): case PART_MOVED(id, point):
var part = parts[id]; var part:PartView = parts[id];
part.x = point.x; part.position = point;
part.y = point.y; case _:
} }
} }
@@ -48,13 +59,18 @@ class Render extends SpriteView implements IRender {
image = RenderUtil.cropImage(image, state.preset.imageRect); image = RenderUtil.cropImage(image, state.preset.imageRect);
for (part in state.parts) { for (part in state.parts) {
var partImage = RenderUtil.cropImagePart(image, part); var partImage = RenderUtil.cropImagePart(image, part);
var partView = new PartView(part.id, partImage); var partView = new PartView(part.id, partImage, part.rect.size);
partView.x = part.rect.x; partView.position = part.rect.topLeft;
partView.y = part.rect.y;
parts.set(part.id, partView); parts.set(part.id, partView);
table.addChild(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 { private function onMouseDown(event:MouseEvent):Void {
@@ -69,15 +85,15 @@ class Render extends SpriteView implements IRender {
private function onMouseMove(event:MouseEvent):Void { private function onMouseMove(event:MouseEvent):Void {
var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY)); var newPoint = table.globalToLocal(new Point(event.stageX, event.stageY));
var partPosition = new Point( var partPosition = activePart.position.add(newPoint).subtract(activePoint);
activePart.x + newPoint.x - activePoint.x, signal.emit(GameEvent.PART_MOVE(activePart.id, partPosition.clone()));
activePart.y + newPoint.y - activePoint.y
);
signal.emit(GameEvent.PART_MOVE(activePart.id, partPosition));
activePoint = newPoint; activePoint = newPoint;
} }
private function onMouseUp(event:MouseEvent):Void { 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_MOVE, onMouseMove);
table.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); table.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
activePart = null; activePart = null;

View File

@@ -33,13 +33,14 @@ class RenderUtil {
var matrix = new Matrix(); var matrix = new Matrix();
matrix.translate(-mask.rect.x, -mask.rect.y); matrix.translate(-mask.rect.x, -mask.rect.y);
image.draw(canvas, matrix); image.draw(canvas, matrix);
var borderWidth = image.width * 0.05; var borderWidth = image.width * 0.02;
var borderAlpha = 1.0; var borderAlpha = 1.0;
#if flash #if flash
borderWidth /= 3; borderWidth /= 3;
borderAlpha = 0.5; //borderAlpha = 0.5;
#end #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; return image;
} }

View File

@@ -3,6 +3,7 @@ package ru.m.puzzlez.view;
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.list.ScrollBarView;
import haxework.view.utils.DrawUtil; import haxework.view.utils.DrawUtil;
import openfl.utils.Assets; import openfl.utils.Assets;
import openfl.utils.AssetType; import openfl.utils.AssetType;
@@ -13,6 +14,7 @@ import ru.m.puzzlez.render.IRender;
@:template class PuzzlezAppView extends VGroupView { @:template class PuzzlezAppView extends VGroupView {
@:view private var scale:ScrollBarView;
@:view private var images:DataView<String, ImageView>; @:view private var images:DataView<String, ImageView>;
@:view private var render:IRender; @:view private var render:IRender;
private var game:IGame; private var game:IGame;
@@ -20,6 +22,7 @@ import ru.m.puzzlez.render.IRender;
public function new() { public function new() {
super(); super();
images.data = Assets.list(AssetType.IMAGE); images.data = Assets.list(AssetType.IMAGE);
scale.position = render.scale - scale.ratio;
} }
private function imageViewFactory(index:Int, image:String):ImageView { private function imageViewFactory(index:Int, image:String):ImageView {
@@ -32,6 +35,10 @@ import ru.m.puzzlez.render.IRender;
return result; return result;
} }
public function setScale(value:Float):Void {
render.scale = value + scale.ratio;
}
public function start(image:String):Void { public function start(image:String):Void {
stop(); stop();
game = new Game(GameUtil.buildPreset(image)); game = new Game(GameUtil.buildPreset(image));

View File

@@ -7,19 +7,28 @@ views:
font.size: 42 font.size: 42
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
geometry.stretch: true geometry.stretch: true
geometry.margin: 5
views: views:
- id: images - id: images
$type: haxework.view.data.DataView $type: haxework.view.data.DataView
layout: layout:
$type: haxework.view.layout.VerticalLayout $type: haxework.view.layout.VerticalLayout
margin: 5
geometry.height: 100% geometry.height: 100%
# geometry.height: 100 # geometry.height: 100
factory: ~imageViewFactory factory: ~imageViewFactory
+onDataSelect: ~start +onDataSelect: ~start
geometry.margin: 5 geometry.margin: 5
- id: render - id: scale
$type: ru.m.puzzlez.render.Render $type: haxework.view.list.VScrollBarView
ratio: 0.5
+onScroll: ~setScale
- $type: haxework.view.group.GroupView
style: frame
geometry.width: 100% geometry.width: 100%
geometry.height: 100% geometry.height: 100%
geometry.margin: 5 overflow.x: scroll
style: frame overflow.y: scroll
views:
- id: render
$type: ru.m.puzzlez.render.Render