From 30ffd971578dd968a80ffc3b3b0e4751abc26cac Mon Sep 17 00:00:00 2001 From: shmyga Date: Wed, 12 Feb 2020 17:52:00 +0300 Subject: [PATCH] [update] (render) image shadow util method --- src/haxe/ru/m/draw/DrawPath.hx | 49 ++++++++++++++----- src/haxe/ru/m/puzzlez/PuzzlezTheme.hx | 4 ++ src/haxe/ru/m/puzzlez/render/RenderUtil.hx | 36 ++++++++------ .../m/puzzlez/render/part/BasePartBuilder.hx | 5 +- .../puzzlez/render/part/ClassicPartBuilder.hx | 30 ++++++------ .../puzzlez/render/part/SquarePartBuilder.hx | 29 ++++++----- src/haxe/ru/m/puzzlez/source/FileSource.hx | 8 +++ src/haxe/ru/m/puzzlez/view/StartFrame.hx | 15 +++++- src/haxe/ru/m/puzzlez/view/StartFrame.yaml | 15 ++++-- 9 files changed, 130 insertions(+), 61 deletions(-) diff --git a/src/haxe/ru/m/draw/DrawPath.hx b/src/haxe/ru/m/draw/DrawPath.hx index 2131583..66c4e62 100644 --- a/src/haxe/ru/m/draw/DrawPath.hx +++ b/src/haxe/ru/m/draw/DrawPath.hx @@ -4,25 +4,52 @@ import flash.display.Graphics; import flash.display.GraphicsPathCommand; import flash.Vector; -class DrawPath { - public var commands(default, null):Vector; - public var data(default, null):Vector; +enum DrawCommand { + MOVE_TO(x:Float, y:Float); + LINE_TO(x:Float, y:Float); + CURVE_TO(cx:Float, cy:Float, ax:Float, ay:Float); +} - public function new() { - commands = new Vector(); - data = new Vector(); +class DrawPath { + public var commands(default, null):Array; + + public function new(commands:Array = null) { + this.commands = commands != null ? commands : []; } public function draw(graphics:Graphics):Void { + var commands = new Vector(); + var data = new Vector(); + for (command in this.commands) { + switch command { + case MOVE_TO(x, y): + commands.push(GraphicsPathCommand.MOVE_TO); + data.push(x); + data.push(y); + case LINE_TO(x, y): + commands.push(GraphicsPathCommand.LINE_TO); + data.push(x); + data.push(y); + case CURVE_TO(cx, cy, ax, ay): + commands.push(GraphicsPathCommand.CURVE_TO); + data.push(cx); + data.push(cy); + data.push(ax); + data.push(ay); + } + } graphics.drawPath(commands, data); } - public function move(x:Float, y:Float):DrawPath { + public function move(mx:Float, my:Float):DrawPath { var result = new DrawPath(); - result.commands = commands.slice(); - for (value in data) { - result.data.push(value + x); - } + result.commands = commands.map(function(command):DrawCommand { + return switch command { + case MOVE_TO(x, y): MOVE_TO(x + mx, y + my); + case LINE_TO(x, y): LINE_TO(x + mx, y + my); + case CURVE_TO(cx, cy, ax, ay): CURVE_TO(cx + mx, cy + my, ax + mx, ay + my); + } + }); return result; } } diff --git a/src/haxe/ru/m/puzzlez/PuzzlezTheme.hx b/src/haxe/ru/m/puzzlez/PuzzlezTheme.hx index d7e0cfe..fb8019f 100644 --- a/src/haxe/ru/m/puzzlez/PuzzlezTheme.hx +++ b/src/haxe/ru/m/puzzlez/PuzzlezTheme.hx @@ -52,5 +52,9 @@ class PuzzlezTheme extends Theme { "geometry.vAlign" => VAlign.TOP, "geometry.margin" => Box.fromFloat(3), ])); + + register(new Style("button.red", [ + "skin.color" => 0xcc0000, + ], "button")); } } diff --git a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx index 5141a41..b0d88d2 100644 --- a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx +++ b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx @@ -1,5 +1,6 @@ package ru.m.puzzlez.render; +import ru.m.draw.DrawPath; import flash.display.BitmapData; import flash.display.Shape; import flash.geom.Matrix; @@ -36,6 +37,25 @@ class RenderUtil { return {rect:rect, drawRect:drawRect}; } + private static function drawShadow(source:BitmapData, path:DrawPath):BitmapData { + var shadow = 2; + var opacity = 0.4; + var canvas = new Shape(); + canvas.cacheAsBitmap = true; + canvas.graphics.beginFill(0x000000, opacity); + path.move(-shadow, -shadow).draw(canvas.graphics); + canvas.graphics.endFill(); + canvas.graphics.beginFill(0xffffff, opacity); + path.move(shadow, shadow).draw(canvas.graphics); + canvas.graphics.endFill(); + canvas.graphics.beginBitmapFill(source, null, false, true); + canvas.graphics.drawRect(0, 0, source.width, source.height); + canvas.graphics.endFill(); + var image = new BitmapData(source.width, source.height, true, 0x00000000); + image.draw(canvas, null, null, null, null, true); + return image; + } + public static function cropImagePart(source:BitmapData, part:Part):BitmapData { var geometry = buildPartGeometry(part); var path = builder.build(geometry.drawRect, part.bounds); @@ -49,21 +69,7 @@ class RenderUtil { canvas.graphics.endFill(); var image = new BitmapData(Std.int(geometry.rect.width), Std.int(geometry.rect.height), true, 0x00000000); image.draw(canvas, null, null, null, null, true); - var shadow = 2; - var canvas2 = new Shape(); - canvas2.cacheAsBitmap = true; - canvas2.graphics.beginFill(0x000000, 0.4); - path.move(-shadow, -shadow).draw(canvas2.graphics); - canvas2.graphics.endFill(); - canvas2.graphics.beginFill(0xffffff, 0.4); - path.move(shadow, shadow).draw(canvas2.graphics); - canvas2.graphics.endFill(); - canvas2.graphics.beginBitmapFill(image, null, false, true); - canvas2.graphics.drawRect(0, 0, geometry.rect.width, geometry.rect.height); - canvas2.graphics.endFill(); - var image2 = new BitmapData(image.width, image.height, true, 0x00000000); - image2.draw(canvas2, null, null, null, null, true); - return image2; + return drawShadow(image, path); } public static function containRectangle(source:Rectangle, target:Rectangle):Rectangle { diff --git a/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx index 01f2ea2..f0c430a 100644 --- a/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx @@ -1,6 +1,5 @@ package ru.m.puzzlez.render.part; -import flash.display.GraphicsPathCommand; import haxework.geom.Rectangle; import ru.m.draw.DrawPath; import ru.m.puzzlez.core.Part; @@ -12,9 +11,7 @@ class BasePartBuilder implements IPartBuilder { } private function createAngle(path:DrawPath, x:Float, y:Float):Void { - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(x); - path.data.push(y); + path.commands.push(LINE_TO(x, y)); } private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { diff --git a/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx index e3343bc..e36a714 100644 --- a/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx @@ -1,6 +1,5 @@ package ru.m.puzzlez.render.part; -import flash.display.GraphicsPathCommand; import ru.m.draw.DrawPath; import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.Part; @@ -26,19 +25,22 @@ class ClassicPartBuilder extends BasePartBuilder { switch bound.spike { case NONE: case IN | OUT: - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(fromX + spikeOffset * dx + spikeSideOffset * dy); - path.data.push(fromY + spikeOffset * dy + spikeSideOffset * dx); - path.commands.push(GraphicsPathCommand.CURVE_TO); - path.data.push(fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy); - path.data.push(fromY + spikeDepth * dx + (spikeOffset * 0.7) * dy + spikeSideOffset * dx); - path.data.push(fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy + spikeSideOffset * dy); - path.data.push(fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx); - path.commands.push(GraphicsPathCommand.CURVE_TO); - path.data.push(fromX + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx - spikeDepth * dy + spikeSideOffset * dy); - path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dy + spikeSideOffset * dx); - path.data.push(fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy); - path.data.push(fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx); + path.commands.push(LINE_TO( + fromX + spikeOffset * dx + spikeSideOffset * dy, + fromY + spikeOffset * dy + spikeSideOffset * dx + )); + path.commands.push(CURVE_TO( + fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy, + fromY + spikeDepth * dx + (spikeOffset * 0.7) * dy + spikeSideOffset * dx, + fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy + spikeSideOffset * dy, + fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx + )); + path.commands.push(CURVE_TO( + fromX + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx - spikeDepth * dy + spikeSideOffset * dy, + fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dy + spikeSideOffset * dx, + fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy, + fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx + )); } } } diff --git a/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx index 58cc7f1..beac8c3 100644 --- a/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx @@ -1,6 +1,5 @@ package ru.m.puzzlez.render.part; -import flash.display.GraphicsPathCommand; import ru.m.draw.DrawPath; import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.Part; @@ -21,18 +20,22 @@ class SquarePartBuilder extends BasePartBuilder { switch bound.spike { case NONE: case IN | OUT: - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(fromX + spikeOffset * dx); - path.data.push(fromY + spikeOffset * dy); - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(fromX + spikeOffset * dx - spikeDepth * dy); - path.data.push(fromY + spikeDepth * dx + spikeOffset * dy); - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy); - path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy); - path.commands.push(GraphicsPathCommand.LINE_TO); - path.data.push(fromX + (spikeOffset + spikeWidth) * dx); - path.data.push(fromY + (spikeOffset + spikeWidth) * dy); + path.commands.push(LINE_TO( + fromX + spikeOffset * dx, + fromY + spikeOffset * dy + )) + path.commands.push(LINE_TO( + fromX + spikeOffset * dx - spikeDepth * dy, + fromY + spikeDepth * dx + spikeOffset * dy + )); + path.commands.push(LINE_TO( + fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy, + fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy + )); + path.commands.push(LINE_TO( + fromX + (spikeOffset + spikeWidth) * dx, + fromY + (spikeOffset + spikeWidth) * dy + )); } } } diff --git a/src/haxe/ru/m/puzzlez/source/FileSource.hx b/src/haxe/ru/m/puzzlez/source/FileSource.hx index 71cf633..b4ec0f5 100644 --- a/src/haxe/ru/m/puzzlez/source/FileSource.hx +++ b/src/haxe/ru/m/puzzlez/source/FileSource.hx @@ -55,4 +55,12 @@ class FileSource implements IImageSource { access.remove(id); listData.flush(); } + + public function clean():Void { + getList().then(function(ids) { + for (id in ids) { + remove(id); + } + }); + } } diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.hx b/src/haxe/ru/m/puzzlez/view/StartFrame.hx index 54b46fc..1776771 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.hx @@ -4,10 +4,12 @@ import haxework.view.data.DataView; import haxework.view.form.ButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; +import haxework.view.popup.ConfirmView; import ru.m.puzzlez.source.AssetSource; import ru.m.puzzlez.source.FileSource; -import ru.m.puzzlez.storage.ImageStorage; import ru.m.puzzlez.source.PixabaySource; +import ru.m.puzzlez.storage.GameStorage; +import ru.m.puzzlez.storage.ImageStorage; @:template class StartFrame extends FrameView { public static var ID = "start"; @@ -15,6 +17,7 @@ import ru.m.puzzlez.source.PixabaySource; @:view var sources:DataView, ButtonView>; @:provide var storage:ImageStorage; @:provide var switcher:FrameSwitcher; + @:provide var gameStorage:GameStorage; public function new() { super(ID); @@ -36,4 +39,14 @@ import ru.m.puzzlez.source.PixabaySource; private function load(source:ImageListSource):Void { switcher.change(ImageListFrame.ID, source); } + + private function clean():Void { + ConfirmView.confirm("Really clean all saved data?").then(function(result) { + if (result) { + gameStorage.clear(); + var fileSource:FileSource = cast storage.sources.get(FileSource.ID); + fileSource.clean(); + } + }); + } } diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml index 0380261..be7d3dd 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml @@ -18,6 +18,15 @@ views: +onDataSelect: ~load geometry.margin: 5 overflow.y: scroll - - $type: haxework.view.form.ButtonView - text: Load - +onPress: ~switcher.change('game_list') + - $type: haxework.view.group.HGroupView + geometry.width: 100% + views: + - $type: haxework.view.form.ButtonView + text: Load + +onPress: ~switcher.change('game_list') + - $type: haxework.view.SpriteView + geometry.width: 100% + - $type: haxework.view.form.ButtonView + style: button.red + text: Clean + +onPress: ~clean()