[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.display.GraphicsPathCommand;
import flash.Vector; import flash.Vector;
class DrawPath { enum DrawCommand {
public var commands(default, null):Vector<GraphicsPathCommand>; MOVE_TO(x:Float, y:Float);
public var data(default, null):Vector<Float>; LINE_TO(x:Float, y:Float);
CURVE_TO(cx:Float, cy:Float, ax:Float, ay:Float);
}
public function new() { class DrawPath {
commands = new Vector(); public var commands(default, null):Array<DrawCommand>;
data = new Vector();
public function new(commands:Array<DrawCommand> = null) {
this.commands = commands != null ? commands : [];
} }
public function draw(graphics:Graphics):Void { 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); graphics.drawPath(commands, data);
} }
public function move(x:Float, y:Float):DrawPath { public function move(mx:Float, my:Float):DrawPath {
var result = new DrawPath(); var result = new DrawPath();
result.commands = commands.slice(); result.commands = commands.map(function(command):DrawCommand {
for (value in data) { return switch command {
result.data.push(value + x); 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; return result;
} }
} }

View File

@@ -52,5 +52,9 @@ class PuzzlezTheme extends Theme {
"geometry.vAlign" => VAlign.TOP, "geometry.vAlign" => VAlign.TOP,
"geometry.margin" => Box.fromFloat(3), "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; package ru.m.puzzlez.render;
import ru.m.draw.DrawPath;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.Shape; import flash.display.Shape;
import flash.geom.Matrix; import flash.geom.Matrix;
@@ -36,6 +37,25 @@ class RenderUtil {
return {rect:rect, drawRect:drawRect}; 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 { public static function cropImagePart(source:BitmapData, part:Part):BitmapData {
var geometry = buildPartGeometry(part); var geometry = buildPartGeometry(part);
var path = builder.build(geometry.drawRect, part.bounds); var path = builder.build(geometry.drawRect, part.bounds);
@@ -49,21 +69,7 @@ class RenderUtil {
canvas.graphics.endFill(); canvas.graphics.endFill();
var image = new BitmapData(Std.int(geometry.rect.width), Std.int(geometry.rect.height), true, 0x00000000); var image = new BitmapData(Std.int(geometry.rect.width), Std.int(geometry.rect.height), true, 0x00000000);
image.draw(canvas, null, null, null, null, true); image.draw(canvas, null, null, null, null, true);
var shadow = 2; return drawShadow(image, path);
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;
} }
public static function containRectangle(source:Rectangle, target:Rectangle):Rectangle { public static function containRectangle(source:Rectangle, target:Rectangle):Rectangle {

View File

@@ -1,6 +1,5 @@
package ru.m.puzzlez.render.part; package ru.m.puzzlez.render.part;
import flash.display.GraphicsPathCommand;
import haxework.geom.Rectangle; import haxework.geom.Rectangle;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
@@ -12,9 +11,7 @@ class BasePartBuilder implements IPartBuilder {
} }
private function createAngle(path:DrawPath, x:Float, y:Float):Void { private function createAngle(path:DrawPath, x:Float, y:Float):Void {
path.commands.push(GraphicsPathCommand.LINE_TO); path.commands.push(LINE_TO(x, y));
path.data.push(x);
path.data.push(y);
} }
private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { 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; package ru.m.puzzlez.render.part;
import flash.display.GraphicsPathCommand;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
@@ -26,19 +25,22 @@ class ClassicPartBuilder extends BasePartBuilder {
switch bound.spike { switch bound.spike {
case NONE: case NONE:
case IN | OUT: case IN | OUT:
path.commands.push(GraphicsPathCommand.LINE_TO); path.commands.push(LINE_TO(
path.data.push(fromX + spikeOffset * dx + spikeSideOffset * dy); fromX + spikeOffset * dx + spikeSideOffset * dy,
path.data.push(fromY + spikeOffset * dy + spikeSideOffset * dx); fromY + spikeOffset * dy + spikeSideOffset * dx
path.commands.push(GraphicsPathCommand.CURVE_TO); ));
path.data.push(fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy); path.commands.push(CURVE_TO(
path.data.push(fromY + spikeDepth * dx + (spikeOffset * 0.7) * dy + spikeSideOffset * dx); fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy,
path.data.push(fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy + spikeSideOffset * dy); fromY + spikeDepth * dx + (spikeOffset * 0.7) * dy + spikeSideOffset * dx,
path.data.push(fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx); fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy + spikeSideOffset * dy,
path.commands.push(GraphicsPathCommand.CURVE_TO); fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx
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.commands.push(CURVE_TO(
path.data.push(fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy); fromX + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx - spikeDepth * dy + spikeSideOffset * dy,
path.data.push(fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx); 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; package ru.m.puzzlez.render.part;
import flash.display.GraphicsPathCommand;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
@@ -21,18 +20,22 @@ class SquarePartBuilder extends BasePartBuilder {
switch bound.spike { switch bound.spike {
case NONE: case NONE:
case IN | OUT: case IN | OUT:
path.commands.push(GraphicsPathCommand.LINE_TO); path.commands.push(LINE_TO(
path.data.push(fromX + spikeOffset * dx); fromX + spikeOffset * dx,
path.data.push(fromY + spikeOffset * dy); fromY + spikeOffset * dy
path.commands.push(GraphicsPathCommand.LINE_TO); ))
path.data.push(fromX + spikeOffset * dx - spikeDepth * dy); path.commands.push(LINE_TO(
path.data.push(fromY + spikeDepth * dx + spikeOffset * dy); fromX + spikeOffset * dx - spikeDepth * dy,
path.commands.push(GraphicsPathCommand.LINE_TO); fromY + spikeDepth * dx + spikeOffset * dy
path.data.push(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy); ));
path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy); path.commands.push(LINE_TO(
path.commands.push(GraphicsPathCommand.LINE_TO); fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy,
path.data.push(fromX + (spikeOffset + spikeWidth) * dx); fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy
path.data.push(fromY + (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); access.remove(id);
listData.flush(); 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.form.ButtonView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import haxework.view.popup.ConfirmView;
import ru.m.puzzlez.source.AssetSource; import ru.m.puzzlez.source.AssetSource;
import ru.m.puzzlez.source.FileSource; import ru.m.puzzlez.source.FileSource;
import ru.m.puzzlez.storage.ImageStorage;
import ru.m.puzzlez.source.PixabaySource; import ru.m.puzzlez.source.PixabaySource;
import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.storage.ImageStorage;
@:template class StartFrame extends FrameView<Dynamic> { @:template class StartFrame extends FrameView<Dynamic> {
public static var ID = "start"; public static var ID = "start";
@@ -15,6 +17,7 @@ import ru.m.puzzlez.source.PixabaySource;
@:view var sources:DataView<ImageListSource<Dynamic>, ButtonView>; @:view var sources:DataView<ImageListSource<Dynamic>, ButtonView>;
@:provide var storage:ImageStorage; @:provide var storage:ImageStorage;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var gameStorage:GameStorage;
public function new() { public function new() {
super(ID); super(ID);
@@ -36,4 +39,14 @@ import ru.m.puzzlez.source.PixabaySource;
private function load(source:ImageListSource<Dynamic>):Void { private function load(source:ImageListSource<Dynamic>):Void {
switcher.change(ImageListFrame.ID, source); 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 +onDataSelect: ~load
geometry.margin: 5 geometry.margin: 5
overflow.y: scroll overflow.y: scroll
- $type: haxework.view.group.HGroupView
geometry.width: 100%
views:
- $type: haxework.view.form.ButtonView - $type: haxework.view.form.ButtonView
text: Load text: Load
+onPress: ~switcher.change('game_list') +onPress: ~switcher.change('game_list')
- $type: haxework.view.SpriteView
geometry.width: 100%
- $type: haxework.view.form.ButtonView
style: button.red
text: Clean
+onPress: ~clean()