[add] ImagePartBuilder
This commit is contained in:
@@ -13,8 +13,8 @@
|
|||||||
},
|
},
|
||||||
"haxeDependencies": {
|
"haxeDependencies": {
|
||||||
"haxework": "git@bitbucket.org:shmyga/haxework.git",
|
"haxework": "git@bitbucket.org:shmyga/haxework.git",
|
||||||
"lime": "7.5.0",
|
"lime": "7.6.3",
|
||||||
"openfl": "8.9.1",
|
"openfl": "8.9.5",
|
||||||
"hxcpp": "4.0.52"
|
"hxcpp": "4.0.52"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import flash.display.Loader;
|
|||||||
import flash.display.LoaderInfo;
|
import flash.display.LoaderInfo;
|
||||||
import flash.events.Event;
|
import flash.events.Event;
|
||||||
import haxe.io.Bytes;
|
import haxe.io.Bytes;
|
||||||
|
import openfl.events.IOErrorEvent;
|
||||||
import promhx.Deferred;
|
import promhx.Deferred;
|
||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
|
|
||||||
@@ -17,6 +18,9 @@ class ImageUtil {
|
|||||||
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event) {
|
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event) {
|
||||||
def.resolve(cast(cast(event.target, LoaderInfo).content, Bitmap).bitmapData);
|
def.resolve(cast(cast(event.target, LoaderInfo).content, Bitmap).bitmapData);
|
||||||
});
|
});
|
||||||
|
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent) {
|
||||||
|
def.throwError(event);
|
||||||
|
});
|
||||||
loader.loadBytes(bytes);
|
loader.loadBytes(bytes);
|
||||||
return def.promise();
|
return def.promise();
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/haxe/ru/m/puzzlez/render/ImagePartBuilder.hx
Normal file
40
src/haxe/ru/m/puzzlez/render/ImagePartBuilder.hx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package ru.m.puzzlez.render;
|
||||||
|
|
||||||
|
import flash.display.BitmapData;
|
||||||
|
import haxe.Timer;
|
||||||
|
import promhx.PublicStream;
|
||||||
|
import promhx.Stream;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
|
||||||
|
typedef Result = {
|
||||||
|
var part:Part;
|
||||||
|
var image:BitmapData;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImagePartBuilder {
|
||||||
|
|
||||||
|
private var image:BitmapData;
|
||||||
|
|
||||||
|
public function new(image:BitmapData) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildPart(index:Int, count:Int, parts:Array<Part>, stream:PublicStream<Result>):Void {
|
||||||
|
for (i in index...index + count) {
|
||||||
|
if (i >= parts.length) {
|
||||||
|
stream.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var part = parts[i];
|
||||||
|
var partImage = RenderUtil.cropImagePart(image, part);
|
||||||
|
stream.update({part: part, image: partImage});
|
||||||
|
}
|
||||||
|
Timer.delay(function() buildPart(index + count, count, parts, stream), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build(parts:Array<Part>):Stream<Result> {
|
||||||
|
var stream = new PublicStream<Result>();
|
||||||
|
Timer.delay(function() buildPart(0, 5, parts, stream), 0);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,26 +22,59 @@ class PartView extends Sprite {
|
|||||||
|
|
||||||
private function set_image(value:BitmapData):BitmapData {
|
private function set_image(value:BitmapData):BitmapData {
|
||||||
image = value;
|
image = value;
|
||||||
bitmap.bitmapData = image;
|
redraw();
|
||||||
refresh();
|
refresh();
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private var size:Point;
|
private var size:Point;
|
||||||
private var bitmap:Bitmap;
|
|
||||||
|
|
||||||
public function new(id:Int, image:BitmapData, size:Point) {
|
public function new(id:Int, image:BitmapData, size:Point) {
|
||||||
super();
|
super();
|
||||||
|
filters = RenderUtil.buildFilters();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
bitmap = new Bitmap(image, PixelSnapping.ALWAYS, true);
|
if (image != null) {
|
||||||
addChild(bitmap);
|
this.image = image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function redraw():Void {
|
||||||
|
throw "Unimplemented";
|
||||||
}
|
}
|
||||||
|
|
||||||
private function refresh():Void {
|
private function refresh():Void {
|
||||||
if (position != null && image != null) {
|
if (position != null && image != null) {
|
||||||
x = position.x - (bitmap.bitmapData.width - size.x) / 2;
|
x = position.x - (image.width - size.x) / 2;
|
||||||
y = position.y - (bitmap.bitmapData.height - size.y) / 2;
|
y = position.y - (image.height - size.y) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function factory(id:Int, image:BitmapData, size:Point):PartView {
|
||||||
|
return new BitmapPartView(id, image, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SpritePartView extends PartView {
|
||||||
|
|
||||||
|
override private function redraw():Void {
|
||||||
|
graphics.clear();
|
||||||
|
graphics.beginBitmapFill(image, null, false, true);
|
||||||
|
graphics.drawRect(0, 0, image.width, image.height);
|
||||||
|
graphics.endFill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitmapPartView extends PartView {
|
||||||
|
private var bitmap:Bitmap;
|
||||||
|
|
||||||
|
public function new(id:Int, image:BitmapData, size:Point) {
|
||||||
|
super(id, image, size);
|
||||||
|
bitmap = new Bitmap(image, PixelSnapping.AUTO, true);
|
||||||
|
addChild(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
override private function redraw():Void {
|
||||||
|
bitmap.bitmapData = image;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import flash.geom.Point;
|
|||||||
import flash.geom.Rectangle;
|
import flash.geom.Rectangle;
|
||||||
import flash.net.FileReference;
|
import flash.net.FileReference;
|
||||||
import flash.utils.ByteArray;
|
import flash.utils.ByteArray;
|
||||||
import haxe.Timer;
|
|
||||||
import haxework.signal.Signal;
|
import haxework.signal.Signal;
|
||||||
import haxework.view.SpriteView;
|
import haxework.view.SpriteView;
|
||||||
import ru.m.puzzlez.core.GameEvent;
|
import ru.m.puzzlez.core.GameEvent;
|
||||||
@@ -73,7 +72,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
clean();
|
clean();
|
||||||
this.state = state;
|
this.state = state;
|
||||||
for (part in state.parts) {
|
for (part in state.parts) {
|
||||||
var partView = new PartView(part.id, null, part.rect.size);
|
var partView = PartView.factory(part.id, null, part.rect.size);
|
||||||
partView.position = part.rect.topLeft;
|
partView.position = part.rect.topLeft;
|
||||||
parts.set(part.id, partView);
|
parts.set(part.id, partView);
|
||||||
table.addChild(partView);
|
table.addChild(partView);
|
||||||
@@ -93,22 +92,14 @@ class Render extends SpriteView implements IRender {
|
|||||||
|
|
||||||
private function onImageResolved(image:BitmapData):Void {
|
private function onImageResolved(image:BitmapData):Void {
|
||||||
this.image = RenderUtil.cropImage(image, state.preset.imageRect);
|
this.image = RenderUtil.cropImage(image, state.preset.imageRect);
|
||||||
|
var builder = new ImagePartBuilder(this.image);
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var loadNext = null;
|
builder.build(state.parts).then(function(result) {
|
||||||
loadNext = function():Void {
|
parts[result.part.id].image = result.image;
|
||||||
var part = state.parts[i];
|
progress.setProgress(++i, state.parts.length);
|
||||||
var partImage = RenderUtil.cropImagePart(this.image, part);
|
}).endThen(function(_) {
|
||||||
var partView = parts[part.id];
|
content.removeChild(progress.content);
|
||||||
partView.image = partImage;
|
});
|
||||||
progress.setProgress(i, state.parts.length);
|
|
||||||
if (i < state.parts.length - 1) {
|
|
||||||
i++;
|
|
||||||
Timer.delay(loadNext, 0);
|
|
||||||
} else {
|
|
||||||
content.removeChild(progress.content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Timer.delay(loadNext, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function update():Void {
|
override public function update():Void {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package ru.m.puzzlez.render;
|
|||||||
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.Shape;
|
import flash.display.Shape;
|
||||||
|
import flash.filters.BitmapFilter;
|
||||||
import flash.filters.BitmapFilterQuality;
|
import flash.filters.BitmapFilterQuality;
|
||||||
import flash.filters.DropShadowFilter;
|
import flash.filters.DropShadowFilter;
|
||||||
import flash.geom.Matrix;
|
import flash.geom.Matrix;
|
||||||
import flash.geom.Point;
|
|
||||||
import flash.geom.Rectangle;
|
import flash.geom.Rectangle;
|
||||||
import ru.m.puzzlez.core.Part;
|
import ru.m.puzzlez.core.Part;
|
||||||
import ru.m.puzzlez.render.mask.PartMask;
|
import ru.m.puzzlez.render.mask.PartMask;
|
||||||
@@ -22,6 +22,17 @@ class RenderUtil {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function buildFilters():Array<BitmapFilter> {
|
||||||
|
var alpha = 0.6;
|
||||||
|
var blur = 1;
|
||||||
|
var strength = 4;
|
||||||
|
var distance = 2;
|
||||||
|
return [
|
||||||
|
new DropShadowFilter(distance, 45 + 180, 0xffffff, alpha, blur, blur, strength, BitmapFilterQuality.HIGH, false),
|
||||||
|
new DropShadowFilter(distance, 45, 0x000000, alpha, blur, blur, strength, BitmapFilterQuality.HIGH, false),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public static function cropImagePart(source:BitmapData, part:Part):BitmapData {
|
public static function cropImagePart(source:BitmapData, part:Part):BitmapData {
|
||||||
var rect = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.width);
|
var rect = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.width);
|
||||||
var mask = new PartMask(rect, part.bounds);
|
var mask = new PartMask(rect, part.bounds);
|
||||||
@@ -35,15 +46,6 @@ 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, null, null, null, true);
|
image.draw(canvas, matrix, null, null, null, true);
|
||||||
var alpha = 1.0;
|
|
||||||
var blur = 2;
|
|
||||||
var strength = 255;
|
|
||||||
#if flash
|
|
||||||
alpha = 0.5;
|
|
||||||
strength = 8;
|
|
||||||
#end
|
|
||||||
image.applyFilter(image, image.rect, new Point(), new DropShadowFilter(0, 0, 0x000000, alpha, blur, blur, strength, BitmapFilterQuality.HIGH, true));
|
|
||||||
image.applyFilter(image, image.rect, new Point(), new DropShadowFilter(0, 0, 0xffffff, alpha, blur / 2, blur / 2, strength / 2, BitmapFilterQuality.HIGH, true));
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ class ClassicMaskBuilder extends BaseMaskBuilder {
|
|||||||
path.data.push(fromX + spikeOffset * dx + spikeSideOffset * dy);
|
path.data.push(fromX + spikeOffset * dx + spikeSideOffset * dy);
|
||||||
path.data.push(fromY + spikeOffset * dy + spikeSideOffset * dx);
|
path.data.push(fromY + spikeOffset * dy + spikeSideOffset * dx);
|
||||||
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
||||||
path.data.push(fromX + (spikeOffset * 0.8) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
path.data.push(fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
||||||
path.data.push(fromY + spikeDepth * dx + (spikeOffset * 0.8) * dy + spikeSideOffset * dx);
|
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(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.data.push(fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx);
|
||||||
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
||||||
path.data.push(fromX + (spikeOffset + spikeWidth + spikeOffset * 0.2) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
path.data.push(fromX + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
||||||
path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.2) * dy + spikeSideOffset * dx);
|
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(fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy);
|
||||||
path.data.push(fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx);
|
path.data.push(fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,15 @@ class FileSource implements IImageSource<Dynamic> {
|
|||||||
|
|
||||||
public function loadImage(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
public function loadImage(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
||||||
var fileData = SharedObject.getLocal(id);
|
var fileData = SharedObject.getLocal(id);
|
||||||
return ImageUtil.bytesToImage(Bytes.ofHex(Reflect.field(fileData.data, "image")));
|
var bytes = null;
|
||||||
|
try {
|
||||||
|
bytes = Bytes.ofHex(Reflect.field(fileData.data, "image"));
|
||||||
|
} catch (error:Dynamic) {
|
||||||
|
var result = new Promise<BitmapData>();
|
||||||
|
result.reject(error);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return ImageUtil.bytesToImage(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function append(data:Bytes):ImageId {
|
public function append(data:Bytes):ImageId {
|
||||||
|
|||||||
Reference in New Issue
Block a user