[add] ImagePartBuilder
This commit is contained in:
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"haxeDependencies": {
|
||||
"haxework": "git@bitbucket.org:shmyga/haxework.git",
|
||||
"lime": "7.5.0",
|
||||
"openfl": "8.9.1",
|
||||
"lime": "7.6.3",
|
||||
"openfl": "8.9.5",
|
||||
"hxcpp": "4.0.52"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
||||
@@ -6,6 +6,7 @@ import flash.display.Loader;
|
||||
import flash.display.LoaderInfo;
|
||||
import flash.events.Event;
|
||||
import haxe.io.Bytes;
|
||||
import openfl.events.IOErrorEvent;
|
||||
import promhx.Deferred;
|
||||
import promhx.Promise;
|
||||
|
||||
@@ -17,6 +18,9 @@ class ImageUtil {
|
||||
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event) {
|
||||
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);
|
||||
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 {
|
||||
image = value;
|
||||
bitmap.bitmapData = image;
|
||||
redraw();
|
||||
refresh();
|
||||
return image;
|
||||
}
|
||||
|
||||
private var size:Point;
|
||||
private var bitmap:Bitmap;
|
||||
|
||||
public function new(id:Int, image:BitmapData, size:Point) {
|
||||
super();
|
||||
filters = RenderUtil.buildFilters();
|
||||
this.id = id;
|
||||
this.size = size;
|
||||
bitmap = new Bitmap(image, PixelSnapping.ALWAYS, true);
|
||||
addChild(bitmap);
|
||||
if (image != null) {
|
||||
this.image = image;
|
||||
}
|
||||
}
|
||||
|
||||
private function redraw():Void {
|
||||
throw "Unimplemented";
|
||||
}
|
||||
|
||||
private function refresh():Void {
|
||||
if (position != null && image != null) {
|
||||
x = position.x - (bitmap.bitmapData.width - size.x) / 2;
|
||||
y = position.y - (bitmap.bitmapData.height - size.y) / 2;
|
||||
x = position.x - (image.width - size.x) / 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.net.FileReference;
|
||||
import flash.utils.ByteArray;
|
||||
import haxe.Timer;
|
||||
import haxework.signal.Signal;
|
||||
import haxework.view.SpriteView;
|
||||
import ru.m.puzzlez.core.GameEvent;
|
||||
@@ -73,7 +72,7 @@ class Render extends SpriteView implements IRender {
|
||||
clean();
|
||||
this.state = state;
|
||||
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;
|
||||
parts.set(part.id, partView);
|
||||
table.addChild(partView);
|
||||
@@ -93,22 +92,14 @@ class Render extends SpriteView implements IRender {
|
||||
|
||||
private function onImageResolved(image:BitmapData):Void {
|
||||
this.image = RenderUtil.cropImage(image, state.preset.imageRect);
|
||||
var builder = new ImagePartBuilder(this.image);
|
||||
var i = 0;
|
||||
var loadNext = null;
|
||||
loadNext = function():Void {
|
||||
var part = state.parts[i];
|
||||
var partImage = RenderUtil.cropImagePart(this.image, part);
|
||||
var partView = parts[part.id];
|
||||
partView.image = partImage;
|
||||
progress.setProgress(i, state.parts.length);
|
||||
if (i < state.parts.length - 1) {
|
||||
i++;
|
||||
Timer.delay(loadNext, 0);
|
||||
} else {
|
||||
builder.build(state.parts).then(function(result) {
|
||||
parts[result.part.id].image = result.image;
|
||||
progress.setProgress(++i, state.parts.length);
|
||||
}).endThen(function(_) {
|
||||
content.removeChild(progress.content);
|
||||
}
|
||||
}
|
||||
Timer.delay(loadNext, 0);
|
||||
});
|
||||
}
|
||||
|
||||
override public function update():Void {
|
||||
|
||||
@@ -2,10 +2,10 @@ package ru.m.puzzlez.render;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.Shape;
|
||||
import flash.filters.BitmapFilter;
|
||||
import flash.filters.BitmapFilterQuality;
|
||||
import flash.filters.DropShadowFilter;
|
||||
import flash.geom.Matrix;
|
||||
import flash.geom.Point;
|
||||
import flash.geom.Rectangle;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.render.mask.PartMask;
|
||||
@@ -22,6 +22,17 @@ class RenderUtil {
|
||||
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 {
|
||||
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);
|
||||
@@ -35,15 +46,6 @@ class RenderUtil {
|
||||
var matrix = new Matrix();
|
||||
matrix.translate(-mask.rect.x, -mask.rect.y);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,13 +29,13 @@ class ClassicMaskBuilder extends BaseMaskBuilder {
|
||||
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.8) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
||||
path.data.push(fromY + spikeDepth * dx + (spikeOffset * 0.8) * dy + spikeSideOffset * dx);
|
||||
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.2) * dx - spikeDepth * dy + spikeSideOffset * dy);
|
||||
path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.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.data.push(fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy);
|
||||
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> {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user