[update] (render) image shadow util method

This commit is contained in:
2020-02-12 17:52:00 +03:00
parent fe6d605b13
commit 30ffd97157
9 changed files with 130 additions and 61 deletions

View File

@@ -4,25 +4,52 @@ import flash.display.Graphics;
import flash.display.GraphicsPathCommand;
import flash.Vector;
class DrawPath {
public var commands(default, null):Vector<GraphicsPathCommand>;
public var data(default, null):Vector<Float>;
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<DrawCommand>;
public function new(commands:Array<DrawCommand> = null) {
this.commands = commands != null ? commands : [];
}
public function draw(graphics:Graphics):Void {
var commands = new Vector<GraphicsPathCommand>();
var data = new Vector<Float>();
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;
}
}

View File

@@ -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"));
}
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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
));
}
}
}

View File

@@ -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
));
}
}
}

View File

@@ -55,4 +55,12 @@ class FileSource implements IImageSource<Dynamic> {
access.remove(id);
listData.flush();
}
public function clean():Void {
getList().then(function(ids) {
for (id in ids) {
remove(id);
}
});
}
}

View File

@@ -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<Dynamic> {
public static var ID = "start";
@@ -15,6 +17,7 @@ import ru.m.puzzlez.source.PixabaySource;
@:view var sources:DataView<ImageListSource<Dynamic>, 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<Dynamic>):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();
}
});
}
}

View File

@@ -18,6 +18,15 @@ views:
+onDataSelect: ~load
geometry.margin: 5
overflow.y: scroll
- $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()