diff --git a/CHANGELOG.MD b/CHANGELOG.MD
index d02aa1bd6..4d77d562d 100644
--- a/CHANGELOG.MD
+++ b/CHANGELOG.MD
@@ -1,5 +1,23 @@
# Change Log
+## v3.64.0 - Nov 10, 2023
+
+* Fixes making thumbnails of single-layer prefabs.
+* Allows merging Import and Open buttons in the Asset Pack Entry section.
+* [#251](https://github.com/PhaserEditor2D/PhaserEditor2D-v3/issues/251) Fixes sprite positioning in Animations Editor.
+* [#209](https://github.com/PhaserEditor2D/PhaserEditor2D-v3/issues/209) Improves scene border painting.
+* Improves animations preview UI:
+ - New Animation preview section.
+ - New Animations Preview section.
+ - Shows a preview button in the Animation Key user property.
+* Adds new Animation section to Sprite game objects. It is about to auto-start a sprite animation.
+* Adds `showBeforeDelay` to the Animations Editor.
+* Shows Sprite Animation blocks in the Scene Editor's Blocks view.
+* Aseprite animations support.
+* New Code Snippets scene elements.
+* Optimizes pooling of WEBGL contexts.
+* [#295](https://github.com/PhaserEditor2D/PhaserEditor2D-v3/issues/295) Fixes tilemapLayer nullable method factory.
+
## v3.63.0 - Sep 30, 2023
* Opens the file given in the `openfile` URL search parameter. Like in `?openfile=some/file`.
diff --git a/design/aseprite/aseprite.png b/design/aseprite/aseprite.png
new file mode 100644
index 000000000..dc4a83e69
Binary files /dev/null and b/design/aseprite/aseprite.png differ
diff --git a/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@1x.tps b/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@1x.tps
index e13437b97..463a7a4ec 100644
--- a/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@1x.tps
+++ b/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@1x.tps
@@ -183,6 +183,7 @@
x1/dark/align-top.png
x1/dark/angle.png
x1/dark/animations.png
+ x1/dark/aseprite.png
x1/dark/asset-pack.png
x1/dark/bitmapfont-type.png
x1/dark/blocks.png
@@ -246,6 +247,7 @@
x1/light/align-top.png
x1/light/angle.png
x1/light/animations.png
+ x1/light/aseprite.png
x1/light/asset-pack.png
x1/light/bitmapfont-type.png
x1/light/blocks.png
diff --git a/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@2x.tps b/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@2x.tps
index 1c40a3809..49e59b1c9 100644
--- a/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@2x.tps
+++ b/design/texture-packer/phasereditor2d.resources/phasereditor2d.resources@2x.tps
@@ -183,6 +183,7 @@
x2/dark/align-top@2x.png
x2/dark/angle@2x.png
x2/dark/animations@2x.png
+ x2/dark/aseprite@2x.png
x2/dark/asset-pack@2x.png
x2/dark/bitmapfont-type@2x.png
x2/dark/blocks@2x.png
@@ -246,6 +247,7 @@
x2/light/align-top@2x.png
x2/light/angle@2x.png
x2/light/animations@2x.png
+ x2/light/aseprite@2x.png
x2/light/asset-pack@2x.png
x2/light/bitmapfont-type@2x.png
x2/light/blocks@2x.png
diff --git a/design/texture-packer/phasereditor2d.resources/x1/dark/aseprite.png b/design/texture-packer/phasereditor2d.resources/x1/dark/aseprite.png
new file mode 100644
index 000000000..e91ae3f5b
Binary files /dev/null and b/design/texture-packer/phasereditor2d.resources/x1/dark/aseprite.png differ
diff --git a/design/texture-packer/phasereditor2d.resources/x1/light/aseprite.png b/design/texture-packer/phasereditor2d.resources/x1/light/aseprite.png
new file mode 100644
index 000000000..e91ae3f5b
Binary files /dev/null and b/design/texture-packer/phasereditor2d.resources/x1/light/aseprite.png differ
diff --git a/design/texture-packer/phasereditor2d.resources/x2/dark/aseprite@2x.png b/design/texture-packer/phasereditor2d.resources/x2/dark/aseprite@2x.png
new file mode 100644
index 000000000..10ef88565
Binary files /dev/null and b/design/texture-packer/phasereditor2d.resources/x2/dark/aseprite@2x.png differ
diff --git a/design/texture-packer/phasereditor2d.resources/x2/light/aseprite@2x.png b/design/texture-packer/phasereditor2d.resources/x2/light/aseprite@2x.png
new file mode 100644
index 000000000..10ef88565
Binary files /dev/null and b/design/texture-packer/phasereditor2d.resources/x2/light/aseprite@2x.png differ
diff --git a/scripts/make-all-help-files.js b/scripts/make-all-help-files.js
index 7bfc38a6d..6bbfbb287 100755
--- a/scripts/make-all-help-files.js
+++ b/scripts/make-all-help-files.js
@@ -8,6 +8,9 @@ utils.makeHelpFile([
"Phaser.Loader.LoaderPlugin.atlas(textureURL)",
"Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig.normalMap",
+ "Phaser.Loader.LoaderPlugin.aseprite(atlasURL)",
+ "Phaser.Loader.LoaderPlugin.aseprite(textureURL)",
+
"Phaser.Loader.LoaderPlugin.atlasXML(atlasURL)",
"Phaser.Loader.LoaderPlugin.atlasXML(textureURL)",
"Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig.normalMap",
@@ -285,7 +288,18 @@ utils.makeHelpFile([
"spine.SkinsAndAnimationBoundsProvider(timeStep)",
"spine.AnimationState.timeScale",
"spine.AnimationStateData.defaultMix",
- "spine.AnimationStateData.setMixWith"
+ "spine.AnimationStateData.setMixWith",
+
+ "Phaser.Types.Animations.PlayAnimationConfig.frameRate",
+ "Phaser.Types.Animations.PlayAnimationConfig.delay",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeat",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeatDelay",
+ "Phaser.Types.Animations.PlayAnimationConfig.yoyo",
+ "Phaser.Types.Animations.PlayAnimationConfig.showOnStart",
+ "Phaser.Types.Animations.PlayAnimationConfig.hideOnComplete",
+ "Phaser.Types.Animations.PlayAnimationConfig.showBeforeDelay",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame",
+ "Phaser.Types.Animations.PlayAnimationConfig.timeScale",
], "../source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.scene/docs/phaser.json");
@@ -300,7 +314,9 @@ utils.makeHelpFile([
"Phaser.Types.Animations.Animation.yoyo",
"Phaser.Types.Animations.Animation.showOnStart",
"Phaser.Types.Animations.Animation.hideOnComplete",
+ "Phaser.Types.Animations.Animation.showBeforeDelay",
"Phaser.Types.Animations.Animation.skipMissedFrames",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame",
], "../source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.animations/docs/phaser-docs.json");
diff --git a/source/editor/plugins/colibri/src/ui/controls/properties/FormBuilder.ts b/source/editor/plugins/colibri/src/ui/controls/properties/FormBuilder.ts
index 3056cfc65..017fcf0de 100644
--- a/source/editor/plugins/colibri/src/ui/controls/properties/FormBuilder.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/properties/FormBuilder.ts
@@ -44,11 +44,20 @@ namespace colibri.ui.controls.properties {
return label;
}
- createButton(parent: HTMLElement, text: string, callback: (e?: MouseEvent) => void) {
+ createButton(parent: HTMLElement, textOrIcon: string | IImage, callback: (e?: MouseEvent) => void) {
const btn = document.createElement("button");
- btn.innerText = text;
+ if (typeof textOrIcon === "string") {
+
+ btn.innerText = textOrIcon;
+
+ } else {
+
+ const iconControl = new controls.IconControl(textOrIcon);
+
+ btn.appendChild(iconControl.getCanvas());
+ }
btn.addEventListener("click", e => callback(e));
diff --git a/source/editor/plugins/colibri/src/ui/controls/properties/PropertyPage.ts b/source/editor/plugins/colibri/src/ui/controls/properties/PropertyPage.ts
index 774448858..fd18797d8 100644
--- a/source/editor/plugins/colibri/src/ui/controls/properties/PropertyPage.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/properties/PropertyPage.ts
@@ -192,6 +192,7 @@ namespace colibri.ui.controls.properties {
const sortedPanes = this._sectionPanes
.map(p => p)
.sort((a, b) =>
+
sectionIdList.indexOf(a.getSection().getId()) - sectionIdList.indexOf(b.getSection().getId())
);
diff --git a/source/editor/plugins/colibri/src/ui/controls/properties/PropertySection.ts b/source/editor/plugins/colibri/src/ui/controls/properties/PropertySection.ts
index 40187eb37..3afefc04d 100644
--- a/source/editor/plugins/colibri/src/ui/controls/properties/PropertySection.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/properties/PropertySection.ts
@@ -81,6 +81,7 @@ namespace colibri.ui.controls.properties {
}
isFillSpace() {
+
return this._fillSpace;
}
diff --git a/source/editor/plugins/colibri/src/ui/controls/properties/PropertySectionProvider.ts b/source/editor/plugins/colibri/src/ui/controls/properties/PropertySectionProvider.ts
index b34d6f6ad..c9415382b 100644
--- a/source/editor/plugins/colibri/src/ui/controls/properties/PropertySectionProvider.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/properties/PropertySectionProvider.ts
@@ -11,6 +11,17 @@ namespace colibri.ui.controls.properties {
abstract addSections(page: PropertyPage, sections: Array>): void;
+ sortSections(sections: controls.properties.PropertySection[]) {
+
+ sections.sort((a, b) => {
+
+ const aa = a.isFillSpace() ? 1 : 0;
+ const bb = b.isFillSpace() ? 1 : 0;
+
+ return aa - bb;
+ });
+ }
+
getEmptySelectionObject() {
return null;
diff --git a/source/editor/plugins/colibri/src/ui/controls/viewers/IconGridCellRenderer.ts b/source/editor/plugins/colibri/src/ui/controls/viewers/IconGridCellRenderer.ts
index 4b90337d3..1a512167d 100644
--- a/source/editor/plugins/colibri/src/ui/controls/viewers/IconGridCellRenderer.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/viewers/IconGridCellRenderer.ts
@@ -41,10 +41,12 @@ namespace colibri.ui.controls.viewers {
}
cellHeight(args: RenderCellArgs): number {
+
return args.viewer.getCellSize();
}
preload(args: PreloadCellArgs): Promise {
+
return this._icon.preload();
}
}
diff --git a/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts b/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts
index b9fb12acd..ac0563c7a 100644
--- a/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts
+++ b/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts
@@ -170,7 +170,7 @@ namespace colibri.ui.controls.viewers {
y += 15;
- } else if (renderer.layout === "full-width") {
+ } else if (renderer.layout === "full-width" && args.h > ROW_HEIGHT * 2) {
args2 = new RenderCellArgs(
args.canvasContext, args.x, args.y, args.w, args.h - 20, args.obj, args.viewer);
diff --git a/source/editor/plugins/colibri/src/ui/ide/ContentTypeEditorFactory.ts b/source/editor/plugins/colibri/src/ui/ide/ContentTypeEditorFactory.ts
index 5228eaaba..89de76b14 100644
--- a/source/editor/plugins/colibri/src/ui/ide/ContentTypeEditorFactory.ts
+++ b/source/editor/plugins/colibri/src/ui/ide/ContentTypeEditorFactory.ts
@@ -6,14 +6,14 @@ namespace colibri.ui.ide {
export class ContentTypeEditorFactory extends EditorFactory {
private _name: string;
- private _contentType: string;
+ private _contentTypeSet: Set;
private _newEditor?: (factory?: ContentTypeEditorFactory) => EditorPart;
- constructor(name: string, contentType: string, newEditor: (factory?: ContentTypeEditorFactory) => EditorPart) {
+ constructor(name: string, contentType: string | string[], newEditor: (factory?: ContentTypeEditorFactory) => EditorPart) {
super();
this._name = name;
- this._contentType = contentType;
+ this._contentTypeSet = new Set(Array.isArray(contentType) ? contentType : [contentType]);
this._newEditor = newEditor;
}
@@ -29,7 +29,7 @@ namespace colibri.ui.ide {
const contentType = colibri.Platform.getWorkbench()
.getContentTypeRegistry().getCachedContentType(input);
- return this._contentType === contentType;
+ return this._contentTypeSet.has(contentType);
}
return false;
diff --git a/source/editor/plugins/colibri/src/ui/ide/properties/BaseManyImagePreviewSection.ts b/source/editor/plugins/colibri/src/ui/ide/properties/BaseManyImagePreviewSection.ts
index 7bf19a05e..0baf2a422 100644
--- a/source/editor/plugins/colibri/src/ui/ide/properties/BaseManyImagePreviewSection.ts
+++ b/source/editor/plugins/colibri/src/ui/ide/properties/BaseManyImagePreviewSection.ts
@@ -11,7 +11,7 @@ namespace colibri.ui.ide.properties {
const viewer = new controls.viewers.TreeViewer("colibri.ui.ide.properties.ManyImagePreviewFormArea");
viewer.setContentProvider(new controls.viewers.ArrayTreeContentProvider());
- viewer.setTreeRenderer(new controls.viewers.GridTreeViewerRenderer(viewer, false, true).setPaintItemShadow(true));
+ viewer.setTreeRenderer(this.createTreeRenderer(viewer));
this.prepareViewer(viewer);
@@ -35,6 +35,11 @@ namespace colibri.ui.ide.properties {
});
}
+ protected createTreeRenderer(viewer: controls.viewers.TreeViewer): controls.viewers.TreeViewerRenderer {
+
+ return new controls.viewers.GridTreeViewerRenderer(viewer, false, true).setPaintItemShadow(true);
+ }
+
protected abstract getViewerInput(): Promise;
protected abstract prepareViewer(viewer: controls.viewers.TreeViewer);
diff --git a/source/editor/plugins/phasereditor2d.animations/src/AnimationsPlugin.ts b/source/editor/plugins/phasereditor2d.animations/src/AnimationsPlugin.ts
index d758e2495..5a8920225 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/AnimationsPlugin.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/AnimationsPlugin.ts
@@ -19,6 +19,23 @@ namespace phasereditor2d.animations {
super("phasereditor2d.animations");
}
+ async openAnimationInEditor(anim: pack.core.AnimationConfigInPackItem) {
+
+ const animationsItem = anim.getParent();
+
+ const file = animationsItem.getAnimationsFile();
+
+ if (file) {
+
+ const editor = colibri.Platform.getWorkbench().openEditor(file);
+
+ if (editor instanceof ui.editors.AnimationsEditor) {
+
+ editor.selectAnimationByKey(anim.getKey());
+ }
+ }
+ }
+
getPhaserDocs() {
if (!this._docs) {
@@ -26,7 +43,7 @@ namespace phasereditor2d.animations {
this._docs = new phasereditor2d.ide.core.PhaserDocs(
resources.ResourcesPlugin.getInstance(), "phasereditor2d.animations/docs/phaser-docs.json");
}
-
+
return this._docs;
}
@@ -48,6 +65,17 @@ namespace phasereditor2d.animations {
reg.addExtension(
new colibri.ui.ide.commands.CommandExtension(manager => this.registerCommands(manager))
);
+
+ // asset pack preview extension
+
+ reg.addExtension(new pack.ui.AssetPackPreviewPropertyProviderExtension(
+ page => new ui.editors.properties.AnimationInfoSection(page),
+ ));
+
+ scene.ScenePlugin.getInstance().openAnimationInEditor = anim => {
+
+ return this.openAnimationInEditor(anim);
+ };
}
private registerCommands(manager: colibri.ui.ide.commands.CommandManager) {
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsEditor.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsEditor.ts
index b0f969036..5bfd3ad96 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsEditor.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsEditor.ts
@@ -21,6 +21,8 @@ namespace phasereditor2d.animations.ui.editors {
private _currentDependenciesHash: string;
private _menuCreator: AnimationsEditorMenuCreator;
private _model: AnimationsModel;
+ private _editorReady = false;
+ private _selectAnimationKeyOnBoot: string;
static getFactory() {
@@ -392,9 +394,9 @@ namespace phasereditor2d.animations.ui.editors {
this._overlayLayer = new AnimationsOverlayLayer(this);
container.appendChild(this._overlayLayer.getCanvas());
- const pool = Phaser.Display.Canvas.CanvasPool;
+ this._gameCanvas = scene.ScenePlugin.getInstance().getCanvasManager().takeCanvas();
+ this._gameCanvas.style.visibility = "hidden";
- this._gameCanvas = pool.create2D(this.getElement(), 100, 100);
this._gameCanvas.style.position = "absolute";
this._gameCanvas.tabIndex = 1;
container.appendChild(this._gameCanvas);
@@ -408,7 +410,11 @@ namespace phasereditor2d.animations.ui.editors {
private registerDropListeners() {
- this._gameCanvas.addEventListener("dragover", e => {
+ // canvas can be reused, don't use it for events
+
+ const eventElement = this._gameCanvas.parentElement;
+
+ eventElement.addEventListener("dragover", e => {
const dataArray = controls.Controls.getApplicationDragData();
@@ -424,7 +430,7 @@ namespace phasereditor2d.animations.ui.editors {
}
});
- this._gameCanvas.addEventListener("drop", e => {
+ eventElement.addEventListener("drop", e => {
e.preventDefault();
@@ -440,7 +446,11 @@ namespace phasereditor2d.animations.ui.editors {
this._menuCreator = new AnimationsEditorMenuCreator(this);
- this._gameCanvas.addEventListener("contextmenu", e => this.onMenu(e));
+ // canvas can be reused, don't use it for events
+
+ const eventElement = this._gameCanvas.parentElement;
+
+ eventElement.addEventListener("contextmenu", e => this.onMenu(e));
}
private onMenu(e: MouseEvent) {
@@ -464,7 +474,7 @@ namespace phasereditor2d.animations.ui.editors {
this._scene = new AnimationsScene(this);
this._game = new Phaser.Game({
- type: Phaser.CANVAS,
+ type: scene.ScenePlugin.DEFAULT_EDITOR_CANVAS_CONTEXT,
canvas: this._gameCanvas,
scale: {
mode: Phaser.Scale.NONE
@@ -493,6 +503,8 @@ namespace phasereditor2d.animations.ui.editors {
this._gameBooted = true;
+ this._gameCanvas.style.visibility = "visible";
+
if (!this._sceneRead) {
await this.readScene();
@@ -502,7 +514,21 @@ namespace phasereditor2d.animations.ui.editors {
this.refreshOutline();
- this.setSelection([]);
+ let selection: Phaser.Animations.Animation[] = [];
+
+ if (this._selectAnimationKeyOnBoot) {
+
+ const anims = this.getAnimations();
+
+ if (anims) {
+
+ selection = anims.filter(a => a.key === this._selectAnimationKeyOnBoot);
+ }
+ }
+
+ this.setSelection(selection);
+
+ this._editorReady = true;
}
private async readScene() {
@@ -744,6 +770,18 @@ namespace phasereditor2d.animations.ui.editors {
return list;
}
+ selectAnimationByKey(animationKey: string) {
+
+ if (this._editorReady) {
+
+ this.setSelection(this.getAnimations().filter(a => a.key === animationKey));
+
+ } else {
+
+ this._selectAnimationKeyOnBoot = animationKey;
+ }
+ }
+
getAnimations() {
return this._scene.anims["anims"].getArray();
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsModel.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsModel.ts
index b4deb8140..f5537eedd 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsModel.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsModel.ts
@@ -73,6 +73,8 @@ namespace phasereditor2d.animations.ui.editors {
if (!a.yoyo) delete a.yoyo;
+ if (!a.showBeforeDelay) delete a.showBeforeDelay;
+
if (!a.showOnStart) delete a.showOnStart;
if (!a.hideOnComplete) delete a.hideOnComplete;
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsScene.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsScene.ts
index 64a0db46a..3ae9d8bca 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsScene.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/AnimationsScene.ts
@@ -207,8 +207,8 @@ namespace phasereditor2d.animations.ui.editors {
sprite.setScale(scale, scale);
- const marginX = size - sprite.width * scale;
- const marginY = size - sprite.height * scale;
+ const marginX = size / 2 - sprite.width * scale / 2;
+ const marginY = size / 2 - sprite.height * scale / 2;
sprite.setData("cell", { x, y, size });
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/EditorAnimationCellRenderer.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/EditorAnimationCellRenderer.ts
index 3942e6db2..600acd09f 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/EditorAnimationCellRenderer.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/EditorAnimationCellRenderer.ts
@@ -37,7 +37,7 @@ namespace phasereditor2d.animations.ui.editors {
ctx.save();
- if (cellSize <= controls.ROW_HEIGHT) {
+ if (cellSize <= controls.ROW_HEIGHT * 2) {
const img = this.getImage(frames[0]);
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationInfoSection.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationInfoSection.ts
new file mode 100644
index 000000000..44ff4d1c5
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationInfoSection.ts
@@ -0,0 +1,92 @@
+namespace phasereditor2d.animations.ui.editors.properties {
+
+ import controls = colibri.ui.controls;
+
+ export class AnimationInfoSection
+ extends controls.properties.PropertySection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.animations.ui.editors.properties", "Animation Info", false);
+ }
+
+ createForm(parent: HTMLDivElement): void {
+
+ const comp = this.createGridElement(parent, 2);
+
+ {
+ // Animation Key
+ this.createLabel(comp, "Animation Key");
+
+ const btn = this.createButton(comp, "", () => {
+
+ const anim = this.getSelectionFirstElement();
+
+ AnimationsPlugin.getInstance().openAnimationInEditor(anim);
+ });
+
+ this.addUpdater(() => {
+
+ const anim = this.getSelectionFirstElement();
+
+ btn.textContent = anim.getKey();
+ });
+ }
+
+ {
+ // Animations File
+ this.createLabel(comp, "Animations File");
+
+ const btn = this.createButton(comp, "", () => {
+
+ const file = this.getSelectionFirstElement().getParent().getAnimationsFile();
+
+ if (file) {
+
+ colibri.Platform.getWorkbench().openEditor(file);
+ }
+ });
+
+ this.addUpdater(() => {
+
+ const anim = this.getSelectionFirstElement();
+
+ const file = anim.getParent().getAnimationsFile();
+
+ btn.textContent = file ?
+ file.getName() + " - " + file.getParent().getProjectRelativeName()
+ : "";
+ });
+ }
+
+ {
+ // preview button
+
+ this.createButton(comp, "Preview Animation", async () => {
+
+ const elem = this.getSelectionFirstElement();
+
+ const animAsset = elem.getParent();
+ const animationKey = elem.getKey();
+
+ const dlg = new scene.ui.sceneobjects.AnimationPreviewDialog(
+ animAsset, {
+ key: animationKey
+ });
+
+ dlg.create();
+
+ }).style.gridColumn = "span 2";
+ }
+ }
+
+ canEdit(obj: any, n: number): boolean {
+
+ return obj instanceof pack.core.AnimationConfigInPackItem;
+ }
+
+ canEditNumber(n: number): boolean {
+
+ return n === 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationSection.ts b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationSection.ts
index 5ba86a9fc..90d6abcc0 100644
--- a/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationSection.ts
+++ b/source/editor/plugins/phasereditor2d.animations/src/ui/editors/properties/AnimationSection.ts
@@ -69,6 +69,8 @@ namespace phasereditor2d.animations.ui.editors.properties {
this.createBooleanProperty(comp, "yoyo", "Yoyo");
+ this.createBooleanProperty(comp, "showBeforeDelay", "Show Before Delay");
+
this.createBooleanProperty(comp, "showOnStart", "Show On Start");
this.createBooleanProperty(comp, "hideOnComplete", "Hide On Complete");
diff --git a/source/editor/plugins/phasereditor2d.files/src/ui/views/FilePropertySectionProvider.ts b/source/editor/plugins/phasereditor2d.files/src/ui/views/FilePropertySectionProvider.ts
index 99bfd2fac..41faae380 100644
--- a/source/editor/plugins/phasereditor2d.files/src/ui/views/FilePropertySectionProvider.ts
+++ b/source/editor/plugins/phasereditor2d.files/src/ui/views/FilePropertySectionProvider.ts
@@ -23,13 +23,7 @@ namespace phasereditor2d.files.ui.views {
}
}
- sections.sort((a, b) => {
-
- const aa = a.isFillSpace() ? 1 : 0;
- const bb = b.isFillSpace() ? 1 : 0;
-
- return aa - bb;
- });
+ this.sortSections(sections);
}
protected acceptSection(section: controls.properties.PropertySection) {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/AssetPackPlugin.ts b/source/editor/plugins/phasereditor2d.pack/src/AssetPackPlugin.ts
index 85ef122e7..dcfa76ab4 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/AssetPackPlugin.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/AssetPackPlugin.ts
@@ -148,6 +148,12 @@ namespace phasereditor2d.pack {
5
));
+ reg.addExtension(
+ new colibri.core.ContentTypeExtension(
+ [new pack.core.contentTypes.AsepriteContentTypeResolver()],
+ 4
+ ));
+
reg.addExtension(
new colibri.core.ContentTypeExtension(
[new pack.core.contentTypes.BitmapFontContentTypeResolver()],
@@ -194,6 +200,10 @@ namespace phasereditor2d.pack {
iconName: resources.ICON_ANIMATIONS,
contentType: core.contentTypes.CONTENT_TYPE_ANIMATIONS
},
+ {
+ iconName: resources.ICON_ASEPRITE,
+ contentType: core.contentTypes.CONTENT_TYPE_ASEPRITE
+ },
{
iconName: resources.ICON_TILEMAP,
contentType: core.contentTypes.CONTENT_TYPE_TILEMAP_TILED_JSON
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationConfigInPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationConfigInPackItem.ts
index f233fdb8f..5df536677 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationConfigInPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationConfigInPackItem.ts
@@ -2,14 +2,21 @@ namespace phasereditor2d.pack.core {
export class AnimationConfigInPackItem {
+ private _parent: BaseAnimationsAssetPackItem;
private _key: string;
private _frames: AnimationFrameConfigInPackItem[];
- constructor() {
+ constructor(parent: BaseAnimationsAssetPackItem) {
+ this._parent = parent;
this._frames = [];
}
+ getParent() {
+
+ return this._parent;
+ }
+
getKey() {
return this._key;
@@ -24,5 +31,27 @@ namespace phasereditor2d.pack.core {
return this._frames;
}
+
+ getPreviewFrame() {
+
+ if (this._frames.length > 0) {
+
+ return this._frames[Math.floor(frames.length / 2)];
+ }
+
+ return null;
+ }
+
+ getPreviewImageAsset() {
+
+ const frame = this.getPreviewFrame();
+
+ if (frame) {
+
+ return frame.getImageAsset();
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationFrameConfigInPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationFrameConfigInPackItem.ts
index 5e38081a3..c8cad091b 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationFrameConfigInPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationFrameConfigInPackItem.ts
@@ -4,6 +4,34 @@ namespace phasereditor2d.pack.core {
private _textureKey: string;
private _frameKey: string | number;
+ private _textureFrame: ImageAssetPackItem | AssetPackImageFrame;
+
+ setTextureFrame(textureFrame: ImageAssetPackItem | AssetPackImageFrame) {
+
+ this._textureFrame = textureFrame;
+ }
+
+ getImageAsset() {
+
+ if (this._textureFrame) {
+
+ if (this._textureFrame instanceof pack.core.ImageAssetPackItem) {
+
+ return this._textureFrame.getFrames()[0];
+
+ } else if (this._textureFrame instanceof pack.core.AssetPackImageFrame) {
+
+ return this._textureFrame;
+ }
+ }
+
+ return null;
+ }
+
+ getTextureFrame() {
+
+ return this._textureFrame;
+ }
getTextureKey() {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationsAssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationsAssetPackItem.ts
index cf0ac5234..a7ac0a8a2 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/AnimationsAssetPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AnimationsAssetPackItem.ts
@@ -1,72 +1,45 @@
-///
+///
namespace phasereditor2d.pack.core {
- import controls = colibri.ui.controls;
+ export class AnimationsAssetPackItem extends BaseAnimationsAssetPackItem {
- export class AnimationsAssetPackItem extends AssetPackItem {
+ override getAnimationsFile() {
- private _animations: AnimationConfigInPackItem[];
-
- constructor(pack: AssetPack, data: any) {
- super(pack, data);
+ const url = this.getData()["url"];
+
+ return this.getFileFromAssetUrl(url);
}
- getUrl() {
-
- return this.getData()["url"];
- }
+ protected override async parseAnimations(animations: AnimationConfigInPackItem[]): Promise {
- getAnimations() {
-
- return this._animations || [];
- }
-
- async preload() {
-
- if (this._animations) {
-
- return controls.PreloadResult.NOTHING_LOADED;
- }
+ const file = this.getAnimationsFile();
- this._animations = [];
+ if (file) {
- try {
+ const content = await colibri.ui.ide.FileUtils.preloadAndGetFileString(file);
- const file = this.getFileFromAssetUrl(this.getUrl());
+ const data = JSON.parse(content) as Phaser.Types.Animations.JSONAnimations;
- if (file) {
+ for (const animData of data.anims) {
- const content = await colibri.ui.ide.FileUtils.preloadAndGetFileString(file);
+ const animConfig = new AnimationConfigInPackItem(this);
- const data = JSON.parse(content) as Phaser.Types.Animations.JSONAnimations;
+ animConfig.setKey(animData.key);
- for (const animData of data.anims) {
+ for (const frameData of animData.frames) {
- const animConfig = new AnimationConfigInPackItem();
+ const frameConfig = new AnimationFrameConfigInPackItem();
- animConfig.setKey(animData.key);
+ frameConfig.setTextureKey(frameData.key);
+ frameConfig.setFrameKey(frameData.frame);
- for (const frameData of animData.frames) {
-
- const frameConfig = new AnimationFrameConfigInPackItem();
-
- frameConfig.setTextureKey(frameData.key);
- frameConfig.setFrameKey(frameData.frame);
-
- animConfig.getFrames().push(frameConfig);
- }
-
- this._animations.push(animConfig);
+ animConfig.getFrames().push(frameConfig);
}
- }
-
- } catch (e) {
- console.error(e);
+ animations.push(animConfig);
+ }
}
-
- return controls.PreloadResult.RESOURCES_LOADED;
}
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AsepriteAssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AsepriteAssetPackItem.ts
new file mode 100644
index 000000000..99584e128
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AsepriteAssetPackItem.ts
@@ -0,0 +1,118 @@
+///
+
+namespace phasereditor2d.pack.core {
+
+ import controls = colibri.ui.controls;
+ import io = colibri.core.io;
+
+ interface IAsepriteData {
+ meta: {
+ frameTags: {
+ name: string,
+ from: number,
+ to: number
+ }[]
+ }
+ }
+
+ export class AsepriteAssetPackItem extends BaseAnimationsAssetPackItem {
+
+ private _atlasItem: AtlasAssetPackItem;
+
+ constructor(pack: AssetPack, data: any) {
+ super(pack, data);
+
+ this._atlasItem = new AtlasAssetPackItem(this.getPack(), this.getData());
+ }
+
+ override getAnimationsFile() {
+
+ const url = this.getData()["atlasURL"];
+
+ return this.getFileFromAssetUrl(url);
+ }
+
+ getAtlasFile() {
+
+ return this.getAnimationsFile();
+ }
+
+ getTextureFile() {
+
+ const url = this.getData()["textureURL"];
+
+ return this.getFileFromAssetUrl(url);
+ }
+
+ preloadImages(): Promise {
+
+ return this._atlasItem.preloadImages();
+ }
+
+ async preload(): Promise {
+
+ await this._atlasItem.preload();
+
+ return super.preload();
+ }
+
+ findFrame(frameName: string | number) {
+
+ return this._atlasItem.findFrame(frameName);
+ }
+
+ getFrames() {
+
+ return this._atlasItem.getFrames();
+ }
+
+ protected async parseAnimations(animations: AnimationConfigInPackItem[]): Promise {
+
+ const atlasURL = this.getData().atlasURL;
+
+ const file = this.getFileFromAssetUrl(atlasURL);
+
+ if (file) {
+
+ const content = await colibri.ui.ide.FileUtils.preloadAndGetFileString(file);
+
+ const data = JSON.parse(content) as IAsepriteData;
+
+ for (const animData of data.meta.frameTags) {
+
+ const animConfig = new AnimationConfigInPackItem(this);
+
+ animConfig.setKey(animData.name);
+
+ for(let i = animData.from; i<= animData.to; i++) {
+
+ const frameKey = i.toString();
+
+ const frameConfig = new AnimationFrameConfigInPackItem();
+
+ frameConfig.setTextureKey(this.getKey());
+ frameConfig.setFrameKey(frameKey);
+
+ animConfig.getFrames().push(frameConfig);
+ }
+
+ animations.push(animConfig);
+ }
+ }
+ }
+
+ addToPhaserCache(game: Phaser.Game, cache: parsers.AssetPackCache): void {
+
+ const parser = new parsers.AtlasParser(this._atlasItem);
+
+ parser.addToPhaserCache(game, cache);
+ }
+
+ computeUsedFiles(files: Set) {
+
+ super.computeUsedFiles(files);
+
+ this.addFilesFromDataKey(files, "atlasURL", "textureURL", "normalMap");
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AssetPack.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AssetPack.ts
index befc68d7f..073adc7b4 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/AssetPack.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AssetPack.ts
@@ -14,6 +14,7 @@ namespace phasereditor2d.pack.core {
export const SPINE_ATLAS_TYPE = "spineAtlas";
export const SPRITESHEET_TYPE = "spritesheet";
export const ANIMATION_TYPE = "animation";
+ export const ASEPRITE_TYPE = "aseprite";
export const AUDIO_TYPE = "audio";
export const AUDIO_SPRITE_TYPE = "audioSprite";
export const BINARY_TYPE = "binary";
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/AssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/AssetPackItem.ts
index ad3bc7cf1..321a7e207 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/AssetPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/AssetPackItem.ts
@@ -99,6 +99,16 @@ namespace phasereditor2d.pack.core {
return controls.Controls.resolveNothingLoaded();
}
+ /**
+ * For building connections with other assets.
+ * It is the case of the frames of the sprite animations.
+ *
+ * @param finder
+ */
+ async build(finder: pack.core.PackFinder) {
+ // empty
+ }
+
resetCache() {
// empty
}
@@ -111,12 +121,12 @@ namespace phasereditor2d.pack.core {
computeHash() {
const files = new Set();
-
+
this.computeUsedFiles(files);
const builder = new ide.core.MultiHashBuilder();
- for(const file of files) {
+ for (const file of files) {
builder.addPartialFileToken(file);
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/BaseAnimationsAssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/BaseAnimationsAssetPackItem.ts
new file mode 100644
index 000000000..faf035c6c
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/BaseAnimationsAssetPackItem.ts
@@ -0,0 +1,62 @@
+///
+
+namespace phasereditor2d.pack.core {
+
+ import controls = colibri.ui.controls;
+ import io = colibri.core.io;
+
+ export abstract class BaseAnimationsAssetPackItem extends AssetPackItem {
+
+ private _animations: AnimationConfigInPackItem[];
+
+ constructor(pack: AssetPack, data: any) {
+ super(pack, data);
+ }
+
+ abstract getAnimationsFile(): io.FilePath;
+
+ getAnimations() {
+
+ return this._animations || [];
+ }
+
+ async preload(): Promise {
+
+ if (this._animations) {
+
+ return controls.PreloadResult.NOTHING_LOADED;
+ }
+
+ this._animations = [];
+
+ try {
+
+ await this.parseAnimations(this._animations);
+
+ } catch (e) {
+
+ console.error(e);
+ }
+
+ return controls.PreloadResult.RESOURCES_LOADED;
+ }
+
+ protected abstract parseAnimations(animations: AnimationConfigInPackItem[]): Promise;
+
+ async build(finder: PackFinder) {
+
+ for (const anim of this._animations) {
+
+ for (const frameConfig of anim.getFrames()) {
+
+ const textureKey = frameConfig.getTextureKey();
+ const frameKey = frameConfig.getFrameKey();
+
+ const textureFrame = finder.getAssetPackItemOrFrame(textureKey, frameKey);
+
+ frameConfig.setTextureFrame(textureFrame);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/BaseAtlasAssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/BaseAtlasAssetPackItem.ts
index 8ffb152f6..d2fee1223 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/BaseAtlasAssetPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/BaseAtlasAssetPackItem.ts
@@ -10,7 +10,7 @@ namespace phasereditor2d.pack.core {
super.computeUsedFiles(files);
- this.addFilesFromDataKey(files, "atlasURL", "textureURL");
+ this.addFilesFromDataKey(files, "atlasURL", "textureURL", "normalMap");
}
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/ImageFrameContainerAssetPackItem.ts b/source/editor/plugins/phasereditor2d.pack/src/core/ImageFrameContainerAssetPackItem.ts
index e0acedeb8..86079fed3 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/ImageFrameContainerAssetPackItem.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/ImageFrameContainerAssetPackItem.ts
@@ -181,8 +181,8 @@ namespace phasereditor2d.pack.core {
protected abstract createParser(): parsers.ImageFrameParser;
- findFrame(frameName: any) {
-
+ findFrame(frameName: string | number) {
+
return this.getFrames().find(f => f.getName() === frameName);
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/PackFinder.ts b/source/editor/plugins/phasereditor2d.pack/src/core/PackFinder.ts
index 471d63248..2d9f9d6d6 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/PackFinder.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/PackFinder.ts
@@ -25,6 +25,7 @@ namespace phasereditor2d.pack.core {
for (const item of items) {
const result2 = await item.preload();
+
result = Math.max(result, result2);
if (monitor) {
@@ -33,6 +34,11 @@ namespace phasereditor2d.pack.core {
}
}
+ for (const item of items) {
+
+ await item.build(this);
+ }
+
return Promise.resolve(result);
}
@@ -49,6 +55,17 @@ namespace phasereditor2d.pack.core {
.filter(i => !filter || filter(i));
}
+ findAnimationByKey(key: string) {
+
+ return this.getAssets()
+
+ .filter(i => i instanceof BaseAnimationsAssetPackItem)
+
+ .flatMap((i: BaseAnimationsAssetPackItem) => i.getAnimations())
+
+ .find(a => a.getKey() === key);
+ }
+
findAssetPackItem(key: string) {
if (!key) {
@@ -60,36 +77,12 @@ namespace phasereditor2d.pack.core {
.find(item => item.getKey() === key);
}
- findPackItemOrFrameWithKey(key: string) {
-
- for (const pack of this._packs) {
-
- for (const item of pack.getItems()) {
-
- if (item.getKey() === key) {
- return item;
- }
-
- if (item instanceof ImageFrameContainerAssetPackItem) {
-
- for (const frame of item.getFrames()) {
-
- if (frame.getName() === key) {
- return frame;
- }
- }
- }
- }
- }
-
- return null;
- }
-
- getAssetPackItemOrFrame(key: string, frame: any) {
+ getAssetPackItemOrFrame(key: string, frame: any): ImageAssetPackItem | AssetPackImageFrame {
const item = this.findAssetPackItem(key);
if (!item) {
+
return null;
}
@@ -97,14 +90,20 @@ namespace phasereditor2d.pack.core {
return item;
- } else if (item instanceof ImageFrameContainerAssetPackItem) {
+ } else if (item instanceof ImageFrameContainerAssetPackItem
+ || item instanceof AsepriteAssetPackItem) {
const imageFrame = item.findFrame(frame);
return imageFrame;
}
- return item;
+ if (item instanceof ImageAssetPackItem) {
+
+ return item;
+ }
+
+ return null;
}
getAssetPackItemImage(key: string, frame: any): AssetPackImageFrame {
@@ -118,7 +117,6 @@ namespace phasereditor2d.pack.core {
} else if (asset instanceof AssetPackImageFrame) {
return asset;
-
}
return null;
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/contentTypes/AsepriteContentTypeResolver.ts b/source/editor/plugins/phasereditor2d.pack/src/core/contentTypes/AsepriteContentTypeResolver.ts
new file mode 100644
index 000000000..0980a70d0
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/contentTypes/AsepriteContentTypeResolver.ts
@@ -0,0 +1,44 @@
+namespace phasereditor2d.pack.core.contentTypes {
+
+ import io = colibri.core.io;
+ import ide = colibri.ui.ide;
+
+ export const CONTENT_TYPE_ASEPRITE = "Aseprite";
+
+ export class AsepriteContentTypeResolver implements colibri.core.IContentTypeResolver {
+
+ getId(): string {
+ return "phasereditor2d.pack.core.AsepriteContentTypeResolver";
+ }
+
+ async computeContentType(file: io.FilePath): Promise {
+
+ if (file.getExtension() === "json") {
+
+ const content = await ide.FileUtils.preloadAndGetFileString(file);
+
+ try {
+
+ const data = JSON.parse(content);
+
+ if (data.meta) {
+
+ const app = data.meta.app || "";
+
+ if (app.indexOf("www.aseprite.org") >= 0) {
+
+ return CONTENT_TYPE_ASEPRITE;
+ }
+ }
+
+ } catch (e) {
+ // nothing
+ }
+ }
+
+ return colibri.core.CONTENT_TYPE_ANY;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/core/parsers/AssetPackCache.ts b/source/editor/plugins/phasereditor2d.pack/src/core/parsers/AssetPackCache.ts
index 1539e38ee..1dc947085 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/core/parsers/AssetPackCache.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/core/parsers/AssetPackCache.ts
@@ -29,11 +29,6 @@ namespace phasereditor2d.pack.core.parsers {
this._assets.add(asset);
}
- getAssets() {
-
- return this._assets;
- }
-
findAsset(key: string) {
for(const asset of this._assets) {
@@ -80,7 +75,7 @@ namespace phasereditor2d.pack.core.parsers {
const files = new Set();
- for (const asset of this.getAssets()) {
+ for (const asset of this._assets) {
files.add(asset.getPack().getFile());
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/DefaultAssetPackExtension.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/DefaultAssetPackExtension.ts
index bada3b0e4..58ab83d6c 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/DefaultAssetPackExtension.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/DefaultAssetPackExtension.ts
@@ -11,6 +11,7 @@ namespace phasereditor2d.pack.ui {
core.MULTI_ATLAS_TYPE,
core.SPRITESHEET_TYPE,
core.ANIMATION_TYPE,
+ core.ASEPRITE_TYPE,
core.BITMAP_FONT_TYPE,
core.TILEMAP_CSV_TYPE,
core.TILEMAP_IMPACT_TYPE,
@@ -45,6 +46,7 @@ namespace phasereditor2d.pack.ui {
multiatlas: "Multiatlas",
spritesheet: "Spritesheet",
animation: "Animation",
+ aseprite: "Aseprite",
bitmapFont: "Bitmap Font",
tilemapCSV: "Tilemap CSV",
tilemapImpact: "Tilemap Impact",
@@ -100,6 +102,9 @@ namespace phasereditor2d.pack.ui {
case core.ANIMATION_TYPE:
return new core.AnimationsAssetPackItem(pack, data);
+ case core.ASEPRITE_TYPE:
+ return new core.AsepriteAssetPackItem(pack, data);
+
case core.BITMAP_FONT_TYPE:
return new core.BitmapFontAssetPackItem(pack, data);
@@ -207,6 +212,8 @@ namespace phasereditor2d.pack.ui {
core.contentTypes.CONTENT_TYPE_ANIMATIONS,
core.ANIMATION_TYPE),
+ new editor.properties.AsepriteSection(page),
+
new editor.properties.BitmapFontSection(page),
new editor.properties.TilemapCSVSection(page),
@@ -320,6 +327,10 @@ namespace phasereditor2d.pack.ui {
new ui.properties.ManyImagePreviewSection(page),
+ new ui.properties.AnimationsPreviewSection(page),
+
+ new ui.properties.AnimationPreviewSection(page),
+
...exts.flatMap(ext => ext.getSections(page))
];
}
@@ -422,7 +433,9 @@ namespace phasereditor2d.pack.ui {
} else if (element instanceof core.AnimationConfigInPackItem) {
- return DefaultAssetPackExtension.getIconRenderer(resources.getIcon(resources.ICON_ANIMATIONS), layout);
+ // return DefaultAssetPackExtension.getIconRenderer(resources.getIcon(resources.ICON_ANIMATIONS), layout);
+
+ return new viewers.AnimationConfigCellRenderer();
}
return undefined;
@@ -467,8 +480,16 @@ namespace phasereditor2d.pack.ui {
new importers.UnityAtlasImporter(),
+ new importers.SpineImporter(core.contentTypes.CONTENT_TYPE_SPINE_JSON, core.SPINE_JSON_TYPE),
+
+ new importers.SpineImporter(core.contentTypes.CONTENT_TYPE_SPINE_BINARY, core.SPINE_BINARY_TYPE),
+
+ new importers.SpineAtlasImporter(),
+
new importers.BitmapFontImporter(),
+ new importers.AsepriteImporter(),
+
new importers.SingleFileImporter(webContentTypes.core.CONTENT_TYPE_IMAGE, core.IMAGE_TYPE),
new importers.SingleFileImporter(webContentTypes.core.CONTENT_TYPE_SVG, core.IMAGE_TYPE),
@@ -480,6 +501,7 @@ namespace phasereditor2d.pack.ui {
scale: 0
}
}),
+
new importers.SpritesheetImporter(),
new importers.SingleFileImporter(core.contentTypes.CONTENT_TYPE_ANIMATIONS, core.ANIMATION_TYPE),
@@ -491,12 +513,6 @@ namespace phasereditor2d.pack.ui {
new importers.SingleFileImporter(core.contentTypes.CONTENT_TYPE_TILEMAP_TILED_JSON,
core.TILEMAP_TILED_JSON_TYPE),
- new importers.SpineImporter(core.contentTypes.CONTENT_TYPE_SPINE_JSON, core.SPINE_JSON_TYPE),
-
- new importers.SpineImporter(core.contentTypes.CONTENT_TYPE_SPINE_BINARY, core.SPINE_BINARY_TYPE),
-
- new importers.SpineAtlasImporter(),
-
new importers.SingleFileImporter(webContentTypes.core.CONTENT_TYPE_JAVASCRIPT, core.PLUGIN_TYPE, false, {
start: false,
mapping: ""
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/dialogs/AssetSelectionDialog.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/dialogs/AssetSelectionDialog.ts
index dba95d3c9..bdf8ed9b5 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/dialogs/AssetSelectionDialog.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/dialogs/AssetSelectionDialog.ts
@@ -7,12 +7,15 @@ namespace phasereditor2d.pack.ui.dialogs {
private _selectionCallback: (selection: any[]) => void;
private _cancelCallback: () => void;
private _viewerLayout: "tree" | "grid";
+ private _selectOnlyOne: boolean;
- constructor(layout: "tree" | "grid" = "grid") {
+ constructor(layout: "tree" | "grid" = "grid", selectOnlyOne = true) {
super(new controls.viewers.TreeViewer("phasereditor2d.pack.ui.dialogs.AssetSelectionDialog"), true);
this._viewerLayout = layout;
+ this._selectOnlyOne = selectOnlyOne;
+
const size = this.getSize();
this.setSize(size.width, size.height * 1.5);
@@ -28,7 +31,7 @@ namespace phasereditor2d.pack.ui.dialogs {
this._cancelCallback = callback;
}
- async getResultPromise(): Promise {
+ async getResultPromise(): Promise {
const promise = new Promise((resolve, reject) => {
@@ -39,7 +42,7 @@ namespace phasereditor2d.pack.ui.dialogs {
this.setCancelCallback(() => {
- reject();
+ resolve(undefined);
})
});
@@ -50,7 +53,7 @@ namespace phasereditor2d.pack.ui.dialogs {
const sel = await this.getResultPromise();
- return sel[0];
+ return sel ?? sel[0];
}
create(hideParentDialog = true) {
@@ -61,7 +64,7 @@ namespace phasereditor2d.pack.ui.dialogs {
if (this._viewerLayout === "tree") {
- viewer.setTreeRenderer(new controls.viewers.GridTreeViewerRenderer(viewer));
+ viewer.setTreeRenderer(new controls.viewers.TreeViewerRenderer(viewer));
} else {
@@ -79,15 +82,18 @@ namespace phasereditor2d.pack.ui.dialogs {
this.setTitle("Select Asset");
- this.enableButtonOnlyWhenOneElementIsSelected(
+ const openBtn = this.addOpenButton("Select", sel => {
- this.addOpenButton("Select", sel => {
+ if (this._selectionCallback) {
- if (this._selectionCallback) {
+ this._selectionCallback(sel);
+ }
+ });
- this._selectionCallback(sel);
- }
- }));
+ if (this._selectOnlyOne) {
+
+ this.enableButtonOnlyWhenOneElementIsSelected(openBtn);
+ }
this.addButton("Cancel", () => {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditor.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditor.ts
index e900cd313..15fef9a24 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditor.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditor.ts
@@ -136,11 +136,24 @@ namespace phasereditor2d.pack.ui.editor {
const content = await ide.FileUtils.preloadAndGetFileString(file);
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
this._pack = new core.AssetPack(file, content);
+ for(const item of this._pack.getItems()) {
+
+ await item.preload();
+
+ await item.build(finder);
+ }
+
this.getViewer().repaint();
- await this.updateBlocks();
+ await this.refreshBlocks();
+
+ this._outlineProvider.repaint();
if (this._revealKey) {
@@ -201,7 +214,7 @@ namespace phasereditor2d.pack.ui.editor {
await this.resetPackCache();
- await this.updateBlocks();
+ await this.refreshBlocks();
}
private async resetPackCache() {
@@ -388,16 +401,20 @@ namespace phasereditor2d.pack.ui.editor {
const items = await importData.importer.autoImport(this._pack, importData.files);
+ const finder = new pack.core.PackFinder(this._pack);
+
for (const item of items) {
await item.preload();
+
+ await item.build(finder);
}
this._viewer.repaint();
this.setDirty(true);
- await this.updateBlocks();
+ await this.refreshBlocks();
this._viewer.setSelection(items);
@@ -408,7 +425,7 @@ namespace phasereditor2d.pack.ui.editor {
this.getUndoManager().add(new undo.AssetPackEditorOperation(this, before, after));
}
- async updateBlocks() {
+ async refreshBlocks() {
if (!this._pack) {
return;
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorContentProvider.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorContentProvider.ts
index 931dbfbfd..127ec2a2c 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorContentProvider.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorContentProvider.ts
@@ -13,6 +13,7 @@ namespace phasereditor2d.pack.ui.editor {
}
getPack() {
+
return this._editor.getPack();
}
@@ -29,6 +30,7 @@ namespace phasereditor2d.pack.ui.editor {
getChildren(parent: any): any[] {
if (typeof (parent) === "string") {
+
const type = parent;
if (this.getPack()) {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorOutlineContentProvider.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorOutlineContentProvider.ts
index 679f76ec4..7cc1c05e2 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorOutlineContentProvider.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/AssetPackEditorOutlineContentProvider.ts
@@ -24,12 +24,17 @@ namespace phasereditor2d.pack.ui.editor {
}
getChildren(parent: any): any[] {
-
+
if (parent instanceof core.SpineAssetPackItem) {
return parent.getGuessSkinItems();
}
+ if (parent instanceof core.BaseAnimationsAssetPackItem) {
+
+ return parent.getAnimations();
+ }
+
return super.getChildren(parent);
}
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/ImportFileSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/ImportFileSection.ts
index 6fcd3d574..319b3c6c2 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/ImportFileSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/ImportFileSection.ts
@@ -16,6 +16,7 @@ namespace phasereditor2d.pack.ui.editor {
this.addUpdater(() => {
while (comp.children.length > 0) {
+
comp.children.item(0).remove();
}
@@ -58,6 +59,7 @@ namespace phasereditor2d.pack.ui.editor {
}
canEditNumber(n: number): boolean {
+
return n > 0;
}
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AsepriteSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AsepriteSection.ts
new file mode 100644
index 000000000..6154484e6
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AsepriteSection.ts
@@ -0,0 +1,34 @@
+///
+
+namespace phasereditor2d.pack.ui.editor.properties {
+
+ import controls = colibri.ui.controls;
+
+ export class AsepriteSection extends BaseSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.pack.ui.editor.properties.AsepriteSection", "Aseprite", core.ASEPRITE_TYPE);
+ }
+
+ canEdit(obj: any, n: number) {
+
+ return super.canEdit(obj, n) && obj instanceof core.AsepriteAssetPackItem;
+ }
+
+ createForm(parent: HTMLDivElement) {
+
+ const comp = this.createGridElement(parent, 3);
+
+ comp.style.gridTemplateColumns = "auto 1fr auto";
+
+ this.createFileField(comp, "Atlas URL", "atlasURL", core.contentTypes.CONTENT_TYPE_ASEPRITE,
+ "Phaser.Loader.LoaderPlugin.aseprite(atlasURL)");
+
+ this.createFileField(comp, "Texture URL", "textureURL", webContentTypes.core.CONTENT_TYPE_IMAGE,
+ "Phaser.Loader.LoaderPlugin.aseprite(textureURL)");
+
+ this.createFileField(comp, "Normal Map", "normalMap", webContentTypes.core.CONTENT_TYPE_IMAGE,
+ "Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig.normalMap");
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AssetPackEditorPropertyProvider.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AssetPackEditorPropertyProvider.ts
index 437d10304..014ce89fd 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AssetPackEditorPropertyProvider.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AssetPackEditorPropertyProvider.ts
@@ -15,6 +15,8 @@ namespace phasereditor2d.pack.ui.editor.properties {
.flatMap(ext => ext.createEditorPropertySections(page));
sections.push(...list);
+
+ this.sortSections(sections);
}
getEmptySelectionObject() {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AtlasSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AtlasSection.ts
index 58941c5d0..ac16680a9 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AtlasSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/AtlasSection.ts
@@ -11,10 +11,12 @@ namespace phasereditor2d.pack.ui.editor.properties {
}
canEdit(obj: any, n: number) {
+
return super.canEdit(obj, n) && obj instanceof core.AtlasAssetPackItem;
}
createForm(parent: HTMLDivElement) {
+
const comp = this.createGridElement(parent, 3);
comp.style.gridTemplateColumns = "auto 1fr auto";
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BaseSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BaseSection.ts
index 2d8f4c086..ea62c07af 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BaseSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BaseSection.ts
@@ -152,7 +152,9 @@ namespace phasereditor2d.pack.ui.editor.properties {
text.value = val === undefined ? "" : val;
});
- this.createButton(comp, "Browse", () => {
+ const icon = colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER);
+
+ this.createButton(comp, icon, () => {
this.browseFile_onlyContentType("Select File", contentType, (files) => {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BlocksSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BlocksSection.ts
index 5b21aa2ad..48baa1a29 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BlocksSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/editor/properties/BlocksSection.ts
@@ -18,7 +18,7 @@ namespace phasereditor2d.pack.ui.editor.properties {
this.getSelectionFirstElement().setShowAllFilesInBlocks(check.checked);
const editor = colibri.Platform.getWorkbench().getActiveEditor() as AssetPackEditor;
- editor.updateBlocks();
+ editor.refreshBlocks();
editor.setDirty(true);
});
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/importers/AsepriteImporter.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/AsepriteImporter.ts
new file mode 100644
index 000000000..fb77da641
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/AsepriteImporter.ts
@@ -0,0 +1,11 @@
+///
+
+namespace phasereditor2d.pack.ui.importers {
+
+ export class AsepriteImporter extends BaseAtlasImporter {
+
+ constructor() {
+ super(core.contentTypes.CONTENT_TYPE_ASEPRITE, core.ASEPRITE_TYPE);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importer.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importer.ts
index 9620e6e46..cdf6fbd41 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importer.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importer.ts
@@ -74,6 +74,11 @@ namespace phasereditor2d.pack.ui.importers {
await item.preload();
+ const finder = new core.PackFinder();
+ await finder.preload();
+
+ await item.build(finder);
+
return item;
}
@@ -99,6 +104,12 @@ namespace phasereditor2d.pack.ui.importers {
await item.preload();
+ const finder = new core.PackFinder();
+
+ await finder.preload();
+
+ await item.build(finder);
+
return item;
}
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importers.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importers.ts
index b678ad245..831c7d6e5 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importers.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/importers/Importers.ts
@@ -27,6 +27,7 @@ namespace phasereditor2d.pack.ui.importers {
}
static getImporter(type: string) {
+
return this.getAll().find(i => i.getType() === type);
}
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AddFileToPackFileSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AddFileToPackFileSection.ts
index c14c74a00..3ff35c285 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AddFileToPackFileSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AddFileToPackFileSection.ts
@@ -29,116 +29,127 @@ namespace phasereditor2d.pack.ui.properties {
this.addUpdater(async () => {
+ comp.innerHTML = "";
+
const finder = new core.PackFinder();
await finder.preload();
- const packItems = await this.getPackItems(finder);
+ await this.buildImportButtons(finder, comp);
- comp.innerHTML = "";
+ await this.buildOpenButtons(finder, comp);
+ });
+ }
- const used = new Set();
+ private async buildOpenButtons(finder: core.PackFinder, comp: HTMLDivElement) {
- for (const item of packItems) {
+ const packItems = await this.getPackItems(finder);
- const btn = document.createElement("button");
+ const used = new Set();
- const key = item.getKey();
- const packPath = item.getPack().getFile().getProjectRelativeName();
- const hash = `${key}@${packPath}`;
+ for (const item of packItems) {
- if (used.has(hash)) {
+ const btn = document.createElement("button");
- continue;
- }
+ const key = item.getKey();
+ const packName = item.getPack().getFile().getName();
+ const packPath = item.getPack().getFile().getProjectRelativeName();
+ const hash = `${key}@${packPath}`;
- used.add(hash);
+ if (used.has(hash)) {
- btn.innerHTML =
- `${key} at ${packPath}`;
+ continue;
+ }
- btn.addEventListener("click", async (e) => {
+ used.add(hash);
- const editor = colibri.Platform.getWorkbench()
- .openEditor(item.getPack().getFile()) as editor.AssetPackEditor;
+ btn.innerHTML =
+ `Open ${key} at ${packName}`;
- editor.revealKey(item.getKey());
- });
+ btn.addEventListener("click", async (e) => {
- comp.appendChild(btn);
- }
+ const editor = colibri.Platform.getWorkbench()
+ .openEditor(item.getPack().getFile()) as editor.AssetPackEditor;
+
+ editor.revealKey(item.getKey());
+ });
- if (packItems.length === 0) {
+ comp.appendChild(btn);
+ }
+ }
- const importList = this.buildImportList();
+ private async buildImportButtons(finder: core.PackFinder, comp: HTMLDivElement) {
- for (const importData of importList) {
+ const importersData = await this.buildImportersData(finder);
- const btn = document.createElement("button");
+ for (const importerData of importersData) {
- btn.innerText = `Import as ${importData.importer.getType()} (${importData.files.length})`;
+ const btn = document.createElement("button");
- btn.addEventListener("click", async (e) => {
+ const importDesc = importerData.files.length === 1 ?
+ importerData.files[0].getName() : importerData.files.length.toString();
- const packs = finder.getPacks();
+ btn.innerText = `Import as ${importerData.importer.getType()} (${importDesc})`;
- const menu = new controls.Menu();
+ btn.addEventListener("click", async (e) => {
- for (const pack of packs) {
+ const packs = finder.getPacks();
- const validFiles = importData.files
- .filter(file => {
+ const menu = new controls.Menu();
- const publicRoot = colibri.ui.ide.FileUtils.getPublicRoot(pack.getFile().getParent());
+ for (const pack of packs) {
- return file.getFullName().startsWith(publicRoot.getFullName())
- });
+ const validFiles = importerData.files
+ .filter(file => {
- menu.add(new controls.Action({
- text: "Add To " + pack.getFile().getProjectRelativeName(),
- enabled: validFiles.length > 0,
- callback: () => {
+ const publicRoot = colibri.ui.ide.FileUtils.getPublicRoot(pack.getFile().getParent());
- this.importWithImporter(importData, pack);
- }
- }));
+ return file.getFullName().startsWith(publicRoot.getFullName());
+ });
+
+ menu.add(new controls.Action({
+ text: "Add To " + pack.getFile().getProjectRelativeName(),
+ enabled: validFiles.length > 0,
+ callback: () => {
+
+ this.importWithImporter(importerData, pack);
}
+ }));
+ }
- menu.add(new controls.Action({
- text: "Add To New Pack File",
- callback: () => {
+ menu.add(new controls.Action({
+ text: "Add To New Pack File",
+ callback: () => {
- const ext = new pack.ui.dialogs.NewAssetPackFileWizardExtension();
+ const ext = new pack.ui.dialogs.NewAssetPackFileWizardExtension();
- const dlg = ext.createDialog({
- initialFileLocation: this.getSelectionFirstElement().getParent()
- });
+ const dlg = ext.createDialog({
+ initialFileLocation: this.getSelectionFirstElement().getParent()
+ });
- dlg.setTitle("New " + ext.getDialogName());
+ dlg.setTitle("New " + ext.getDialogName());
- const callback = dlg.getFileCreatedCallback();
+ const callback = dlg.getFileCreatedCallback();
- dlg.setFileCreatedCallback(async (file) => {
+ dlg.setFileCreatedCallback(async (file) => {
- await callback(file);
+ await callback(file);
- const content = colibri.ui.ide.FileUtils.getFileString(file);
+ const content = colibri.ui.ide.FileUtils.getFileString(file);
- const pack = new core.AssetPack(file, content);
+ const pack = new core.AssetPack(file, content);
- this.importWithImporter(importData, pack);
+ this.importWithImporter(importerData, pack);
- });
- }
- }));
+ });
+ }
+ }));
- menu.createWithEvent(e);
- });
+ menu.createWithEvent(e);
+ });
- comp.appendChild(btn);
- }
- }
- });
+ comp.appendChild(btn);
+ }
}
private async importWithImporter(importData: editor.IImportData, pack: core.AssetPack) {
@@ -158,13 +169,25 @@ namespace phasereditor2d.pack.ui.properties {
blocks.BlocksPlugin.getInstance().refreshBlocksView();
}
- private buildImportList() {
+ private async buildImportersData(finder: core.PackFinder) {
const importList: editor.IImportData[] = [];
+ const selection: io.FilePath[] = [];
+
+ for (const file of this.getSelection()) {
+
+ const items = await finder.findPackItemsFor(file);
+
+ if (items.length === 0) {
+
+ selection.push(file);
+ }
+ }
+
for (const importer of importers.Importers.getAll()) {
- const files = this.getSelection().filter(file => importer.acceptFile(file));
+ const files = selection.filter(file => importer.acceptFile(file));
if (files.length > 0) {
@@ -193,14 +216,16 @@ namespace phasereditor2d.pack.ui.properties {
}
}
- if (n > 0) {
+ return n > 0;
- const list = this.buildImportList();
+ // if (n > 0) {
- return list.length > 0;
- }
+ // const list = this.buildImportList();
+
+ // return list.length > 0;
+ // }
- return false;
+ // return false;
}
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationPreviewSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationPreviewSection.ts
new file mode 100644
index 000000000..9022e7710
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationPreviewSection.ts
@@ -0,0 +1,26 @@
+namespace phasereditor2d.pack.ui.properties {
+
+ import controls = colibri.ui.controls;
+
+ export class AnimationPreviewSection
+ extends colibri.ui.ide.properties.BaseImagePreviewSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.pack.ui.properties.AnimationPreviewSection", "Animation Preview", true);
+ }
+
+ protected getSelectedImage(): controls.IImage {
+
+ const anim = this.getSelection()[0];
+
+ const img = anim.getPreviewImageAsset();
+
+ return img;
+ }
+
+ canEdit(obj: any): boolean {
+
+ return obj instanceof core.AnimationConfigInPackItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationsPreviewSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationsPreviewSection.ts
new file mode 100644
index 000000000..2ce794a4e
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AnimationsPreviewSection.ts
@@ -0,0 +1,48 @@
+namespace phasereditor2d.pack.ui.properties {
+
+ import controls = colibri.ui.controls;
+
+ export class AnimationsPreviewSection extends colibri.ui.ide.properties.BaseManyImagePreviewSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.pack.ui.properties.AnimationsPreviewSection", "Animations Preview", true);
+ }
+
+ protected override async getViewerInput() {
+
+ const frames = this.getSelection().flatMap(obj => {
+
+ return obj.getAnimations();
+ });
+
+ return frames;
+ }
+
+ protected override prepareViewer(viewer: controls.viewers.TreeViewer) {
+
+ viewer.setLabelProvider(new viewers.AssetPackLabelProvider());
+ viewer.setCellRendererProvider(new controls.viewers.EmptyCellRendererProvider(
+ e => new viewers.AnimationConfigCellRenderer("square")));
+
+ viewer.eventOpenItem.addListener((elem: pack.core.AnimationConfigInPackItem) => {
+
+ AnimationsPreviewSection.openPreviewDialog(elem);
+ });
+ }
+
+ static openPreviewDialog(elem: core.AnimationConfigInPackItem) {
+
+ alert("Preview dialog not found.");
+ }
+
+ override canEdit(obj: any, n: number): boolean {
+
+ return obj instanceof core.BaseAnimationsAssetPackItem;
+ }
+
+ override canEditNumber(n: number): boolean {
+
+ return n > 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AssetPackPreviewPropertyProvider.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AssetPackPreviewPropertyProvider.ts
index 27dc015ea..5283460e3 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AssetPackPreviewPropertyProvider.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/AssetPackPreviewPropertyProvider.ts
@@ -11,6 +11,8 @@ namespace phasereditor2d.pack.ui.properties {
sections.push(new pack.ui.properties.AtlasFrameInfoSection(page));
sections.push(new pack.ui.properties.ImagePreviewSection(page));
sections.push(new pack.ui.properties.ManyImagePreviewSection(page));
+ sections.push(new pack.ui.properties.AnimationsPreviewSection(page));
+ sections.push(new pack.ui.properties.AnimationPreviewSection(page));
sections.push(new pack.ui.properties.BitmapFontPreviewSection(page));
sections.push(new pack.ui.properties.ManyBitmapFontPreviewSection(page));
sections.push(new pack.ui.properties.TilemapTiledSection(page));
@@ -25,6 +27,8 @@ namespace phasereditor2d.pack.ui.properties {
sections.push(...ext.getSections(page));
}
+
+ this.sortSections(sections);
}
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/ManyImagePreviewSection.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/ManyImagePreviewSection.ts
index af252ce8d..c2f010ae2 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/properties/ManyImagePreviewSection.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/properties/ManyImagePreviewSection.ts
@@ -1,7 +1,6 @@
namespace phasereditor2d.pack.ui.properties {
import controls = colibri.ui.controls;
- import ide = colibri.ui.ide;
export class ManyImagePreviewSection extends colibri.ui.ide.properties.BaseManyImagePreviewSection {
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationConfigCellRenderer.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationConfigCellRenderer.ts
index 840d27439..8f78662bf 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationConfigCellRenderer.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationConfigCellRenderer.ts
@@ -4,12 +4,12 @@ namespace phasereditor2d.pack.ui.viewers {
export class AnimationConfigCellRenderer implements controls.viewers.ICellRenderer {
- private _finder: pack.core.PackFinder;
- public layout: "square" | "full-width" = "full-width";
+ public layout: "square" | "full-width";
+ private static _finder: pack.core.PackFinder;
- constructor(finder: pack.core.PackFinder) {
+ constructor(layout: "square" | "full-width" = "full-width") {
- this._finder = finder;
+ this.layout = layout;
}
getAnimationConfig(args: controls.viewers.RenderCellArgs | controls.viewers.PreloadCellArgs): pack.core.AnimationConfigInPackItem {
@@ -30,17 +30,13 @@ namespace phasereditor2d.pack.ui.viewers {
const cellSize = args.viewer.getCellSize();
- const len = frames.length;
-
- const indexes = [0, Math.floor(len / 2), len - 1];
-
const ctx = args.canvasContext;
ctx.save();
- if (cellSize <= controls.ROW_HEIGHT) {
+ if (cellSize <= controls.ROW_HEIGHT * 2 || this.layout === "square") {
- const img = this.getImage(frames[0]);
+ const img = anim.getPreviewImageAsset();
if (img) {
@@ -49,12 +45,16 @@ namespace phasereditor2d.pack.ui.viewers {
} else {
+ const len = frames.length;
+
+ const indexes = [0, Math.floor(len / 2), len - 1];
+
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < indexes.length; i++) {
const frame = frames[indexes[i]];
- const img = this.getImage(frame);
+ const img = frame.getImageAsset();
if (img) {
@@ -68,13 +68,6 @@ namespace phasereditor2d.pack.ui.viewers {
ctx.restore();
}
- private getImage(frame: pack.core.AnimationFrameConfigInPackItem) {
-
- const image = this._finder.getAssetPackItemImage(frame.getTextureKey(), frame.getFrameKey());
-
- return image;
- }
-
cellHeight(args: controls.viewers.RenderCellArgs): number {
return args.viewer.getCellSize();
@@ -88,11 +81,11 @@ namespace phasereditor2d.pack.ui.viewers {
for (const frame of anim.getFrames()) {
- const obj = this._finder.getAssetPackItemOrFrame(frame.getTextureKey(), frame.getFrameKey());
+ const asset = frame.getTextureFrame();
- if (obj) {
+ if (asset) {
- const objResult = await obj.preload();
+ const objResult = await asset.preload();
result = Math.max(result, objResult);
}
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationsItemCellRenderer.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationsItemCellRenderer.ts
new file mode 100644
index 000000000..00984872b
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AnimationsItemCellRenderer.ts
@@ -0,0 +1,18 @@
+namespace phasereditor2d.pack.ui.viewers {
+
+ import controls = colibri.ui.controls;
+
+ export class AnimationsItemCellRenderer extends controls.viewers.IconImageCellRenderer {
+
+ constructor() {
+ super(resources.getIcon(resources.ICON_ANIMATIONS));
+ }
+
+ async preload(args: controls.viewers.PreloadCellArgs): Promise {
+
+ super.preload(args);
+
+ return (args.obj as pack.core.BaseAnimationsAssetPackItem).preload();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AsepriteItemCellRenderer.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AsepriteItemCellRenderer.ts
new file mode 100644
index 000000000..e1d59f670
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AsepriteItemCellRenderer.ts
@@ -0,0 +1,18 @@
+namespace phasereditor2d.pack.ui.viewers {
+
+ import controls = colibri.ui.controls;
+
+ export class AsepriteItemCellRenderer extends controls.viewers.IconImageCellRenderer {
+
+ constructor() {
+ super(resources.getIcon(resources.ICON_ASEPRITE));
+ }
+
+ async preload(args: controls.viewers.PreloadCellArgs): Promise {
+
+ super.preload(args);
+
+ return (args.obj as pack.core.AsepriteAssetPackItem).preload();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackCellRendererProvider.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackCellRendererProvider.ts
index 1e3a4bf6d..9fdafc962 100644
--- a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackCellRendererProvider.ts
+++ b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackCellRendererProvider.ts
@@ -11,6 +11,7 @@ namespace phasereditor2d.pack.ui.viewers {
constructor(layout: "grid" | "tree") {
+
this._layout = layout;
this._fileRendererProvider = new files.ui.viewers.FileCellRendererProvider(layout);
@@ -41,6 +42,14 @@ namespace phasereditor2d.pack.ui.viewers {
return this._fileRendererProvider.getCellRenderer(element);
+ } else if (element instanceof pack.core.AnimationsAssetPackItem) {
+
+ return new viewers.AnimationsItemCellRenderer();
+
+ } else if (element instanceof pack.core.AsepriteAssetPackItem) {
+
+ return new viewers.AsepriteItemCellRenderer();
+
} else {
const extensions = AssetPackPlugin.getInstance().getExtensions();
diff --git a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.animations/docs/phaser-docs.json b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.animations/docs/phaser-docs.json
index 71c70a048..a803a7d63 100644
--- a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.animations/docs/phaser-docs.json
+++ b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.animations/docs/phaser-docs.json
@@ -7,5 +7,7 @@
"Phaser.Types.Animations.Animation.yoyo": "Should the animation yoyo? (reverse back down to the start) before repeating?",
"Phaser.Types.Animations.Animation.showOnStart": "Should sprite.visible = true when the animation starts to play? This happens _after_ any delay, if set.",
"Phaser.Types.Animations.Animation.hideOnComplete": "Should sprite.visible = false when the animation finishes?",
- "Phaser.Types.Animations.Animation.skipMissedFrames": "Skip frames if the time lags, or always advanced anyway?"
+ "Phaser.Types.Animations.Animation.showBeforeDelay": "If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false)",
+ "Phaser.Types.Animations.Animation.skipMissedFrames": "Skip frames if the time lags, or always advanced anyway?",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame": "The frame of the animation to start playback from."
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.pack/docs/phaser-docs.json b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.pack/docs/phaser-docs.json
index f8daf0daa..9f18a15f2 100644
--- a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.pack/docs/phaser-docs.json
+++ b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.pack/docs/phaser-docs.json
@@ -2,6 +2,8 @@
"Phaser.Loader.LoaderPlugin.atlas(atlasURL)": "The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `.json`, i.e. if `key` was \"alien\" then the URL will be \"alien.json\". Or, a well formed JSON object.",
"Phaser.Loader.LoaderPlugin.atlas(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig.normalMap": "The filename of an associated normal map. It uses the same path and url to load as the texture image.",
+ "Phaser.Loader.LoaderPlugin.aseprite(atlasURL)": "The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `.json`, i.e. if `key` was \"alien\" then the URL will be \"alien.json\". Or, a well formed JSON object.",
+ "Phaser.Loader.LoaderPlugin.aseprite(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Loader.LoaderPlugin.atlasXML(atlasURL)": "The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was \"alien\" then the URL will be \"alien.xml\".",
"Phaser.Loader.LoaderPlugin.atlasXML(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig.normalMap": "The filename of an associated normal map. It uses the same path and url to load as the texture image.",
diff --git a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.scene/docs/phaser.json b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.scene/docs/phaser.json
index 81444c4bc..c99ab5cfc 100644
--- a/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.scene/docs/phaser.json
+++ b/source/editor/plugins/phasereditor2d.resources/_res/phasereditor2d.scene/docs/phaser.json
@@ -177,5 +177,15 @@
"spine.SkinsAndAnimationBoundsProvider(timeStep)": "The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation.",
"spine.AnimationState.timeScale": "Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower\nor faster. Defaults to 1.\n\nSee TrackEntry {@link TrackEntry#timeScale} for affecting a single animation.",
"spine.AnimationStateData.defaultMix": "The mix duration to use when no mix duration has been defined between two animations.",
- "spine.AnimationStateData.setMixWith": "Sets the mix duration when changing from the specified animation to the other.\n\nSee {@link TrackEntry#mixDuration}."
+ "spine.AnimationStateData.setMixWith": "Sets the mix duration when changing from the specified animation to the other.\n\nSee {@link TrackEntry#mixDuration}.",
+ "Phaser.Types.Animations.PlayAnimationConfig.frameRate": "The frame rate of playback in frames per second (default 24 if duration is null)",
+ "Phaser.Types.Animations.PlayAnimationConfig.delay": "Delay before starting playback. Value given in milliseconds.",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeat": "Number of times to repeat the animation (-1 for infinity)",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeatDelay": "Delay before the animation repeats. Value given in milliseconds.",
+ "Phaser.Types.Animations.PlayAnimationConfig.yoyo": "Should the animation yoyo? (reverse back down to the start) before repeating?",
+ "Phaser.Types.Animations.PlayAnimationConfig.showOnStart": "Should sprite.visible = true when the animation starts to play?",
+ "Phaser.Types.Animations.PlayAnimationConfig.hideOnComplete": "Should sprite.visible = false when the animation finishes?",
+ "Phaser.Types.Animations.PlayAnimationConfig.showBeforeDelay": "If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false)",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame": "The frame of the animation to start playback from.",
+ "Phaser.Types.Animations.PlayAnimationConfig.timeScale": "The time scale to be applied to playback of this animation."
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.json b/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.json
index 89423aa36..7c6d791fb 100644
--- a/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.json
+++ b/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.json
@@ -80,7 +80,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
"sourceSize": {"w":16,"h":16}
},
-"dark/asset-pack.png":
+"dark/aseprite.png":
{
"frame": {"x":1,"y":73,"w":16,"h":16},
"rotated": false,
@@ -88,6 +88,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
"sourceSize": {"w":16,"h":16}
},
+"dark/asset-pack.png":
+{
+ "frame": {"x":19,"y":55,"w":16,"h":16},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
+ "sourceSize": {"w":16,"h":16}
+},
"dark/bitmapfont-type.png":
{
"frame": {"x":37,"y":289,"w":15,"h":16},
@@ -98,7 +106,7 @@
},
"dark/blocks.png":
{
- "frame": {"x":19,"y":55,"w":16,"h":16},
+ "frame": {"x":37,"y":37,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -106,7 +114,7 @@
},
"dark/border-bottom.png":
{
- "frame": {"x":37,"y":37,"w":16,"h":16},
+ "frame": {"x":55,"y":19,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -114,7 +122,7 @@
},
"dark/border-center.png":
{
- "frame": {"x":55,"y":19,"w":16,"h":16},
+ "frame": {"x":73,"y":1,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -122,7 +130,7 @@
},
"dark/border-left.png":
{
- "frame": {"x":73,"y":1,"w":16,"h":16},
+ "frame": {"x":1,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -130,7 +138,7 @@
},
"dark/border-middle.png":
{
- "frame": {"x":1,"y":91,"w":16,"h":16},
+ "frame": {"x":19,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -138,7 +146,7 @@
},
"dark/border-right.png":
{
- "frame": {"x":19,"y":73,"w":16,"h":16},
+ "frame": {"x":37,"y":55,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -146,7 +154,7 @@
},
"dark/border-top.png":
{
- "frame": {"x":37,"y":55,"w":16,"h":16},
+ "frame": {"x":55,"y":37,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -154,7 +162,7 @@
},
"dark/build.png":
{
- "frame": {"x":55,"y":37,"w":16,"h":16},
+ "frame": {"x":73,"y":19,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -162,7 +170,7 @@
},
"dark/collider.png":
{
- "frame": {"x":73,"y":19,"w":16,"h":16},
+ "frame": {"x":91,"y":1,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -170,7 +178,7 @@
},
"dark/column.png":
{
- "frame": {"x":91,"y":1,"w":16,"h":16},
+ "frame": {"x":109,"y":1,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -186,7 +194,7 @@
},
"dark/file-font.png":
{
- "frame": {"x":54,"y":289,"w":13,"h":16},
+ "frame": {"x":91,"y":253,"w":13,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":13,"h":16},
@@ -194,7 +202,7 @@
},
"dark/file-image.png":
{
- "frame": {"x":109,"y":1,"w":16,"h":16},
+ "frame": {"x":1,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -202,7 +210,7 @@
},
"dark/file-movie.png":
{
- "frame": {"x":1,"y":109,"w":16,"h":16},
+ "frame": {"x":19,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -210,7 +218,7 @@
},
"dark/file-new.png":
{
- "frame": {"x":19,"y":91,"w":16,"h":16},
+ "frame": {"x":37,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -218,7 +226,7 @@
},
"dark/file-script.png":
{
- "frame": {"x":37,"y":73,"w":16,"h":16},
+ "frame": {"x":55,"y":55,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -226,7 +234,7 @@
},
"dark/file-sound.png":
{
- "frame": {"x":55,"y":55,"w":16,"h":16},
+ "frame": {"x":73,"y":37,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -234,7 +242,7 @@
},
"dark/file-text.png":
{
- "frame": {"x":73,"y":37,"w":16,"h":16},
+ "frame": {"x":91,"y":19,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -242,7 +250,7 @@
},
"dark/grid.png":
{
- "frame": {"x":91,"y":19,"w":16,"h":16},
+ "frame": {"x":109,"y":19,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -250,7 +258,7 @@
},
"dark/group.png":
{
- "frame": {"x":109,"y":19,"w":16,"h":16},
+ "frame": {"x":1,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -258,7 +266,7 @@
},
"dark/image-type.png":
{
- "frame": {"x":109,"y":268,"w":14,"h":14},
+ "frame": {"x":91,"y":271,"w":14,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":14,"h":14},
@@ -266,7 +274,7 @@
},
"dark/inspector.png":
{
- "frame": {"x":1,"y":127,"w":16,"h":16},
+ "frame": {"x":19,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -274,7 +282,7 @@
},
"dark/keyboard-key.png":
{
- "frame": {"x":19,"y":109,"w":16,"h":16},
+ "frame": {"x":37,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -282,7 +290,7 @@
},
"dark/layer.png":
{
- "frame": {"x":37,"y":91,"w":16,"h":16},
+ "frame": {"x":55,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -290,7 +298,7 @@
},
"dark/list.png":
{
- "frame": {"x":109,"y":217,"w":16,"h":15},
+ "frame": {"x":55,"y":271,"w":16,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":15},
@@ -298,7 +306,7 @@
},
"dark/locked.png":
{
- "frame": {"x":112,"y":284,"w":11,"h":13},
+ "frame": {"x":107,"y":287,"w":11,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":11,"h":13},
@@ -306,7 +314,7 @@
},
"dark/origin-bottomcenter.png":
{
- "frame": {"x":55,"y":73,"w":16,"h":16},
+ "frame": {"x":73,"y":55,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -314,7 +322,7 @@
},
"dark/origin-bottomleft.png":
{
- "frame": {"x":73,"y":55,"w":16,"h":16},
+ "frame": {"x":91,"y":37,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -322,7 +330,7 @@
},
"dark/origin-bottomright.png":
{
- "frame": {"x":91,"y":37,"w":16,"h":16},
+ "frame": {"x":109,"y":37,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -330,7 +338,7 @@
},
"dark/origin-middlecenter.png":
{
- "frame": {"x":109,"y":37,"w":16,"h":16},
+ "frame": {"x":1,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -338,7 +346,7 @@
},
"dark/origin-middleleft.png":
{
- "frame": {"x":1,"y":145,"w":16,"h":16},
+ "frame": {"x":19,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -346,7 +354,7 @@
},
"dark/origin-middleright.png":
{
- "frame": {"x":19,"y":127,"w":16,"h":16},
+ "frame": {"x":37,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -354,7 +362,7 @@
},
"dark/origin-topcenter.png":
{
- "frame": {"x":37,"y":109,"w":16,"h":16},
+ "frame": {"x":55,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -362,7 +370,7 @@
},
"dark/origin-topleft.png":
{
- "frame": {"x":55,"y":91,"w":16,"h":16},
+ "frame": {"x":73,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -370,7 +378,7 @@
},
"dark/origin-topright.png":
{
- "frame": {"x":73,"y":73,"w":16,"h":16},
+ "frame": {"x":91,"y":55,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -378,7 +386,7 @@
},
"dark/origin.png":
{
- "frame": {"x":91,"y":55,"w":16,"h":16},
+ "frame": {"x":109,"y":55,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -386,7 +394,7 @@
},
"dark/outline.png":
{
- "frame": {"x":109,"y":55,"w":16,"h":16},
+ "frame": {"x":1,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -394,7 +402,7 @@
},
"dark/play.png":
{
- "frame": {"x":84,"y":284,"w":12,"h":14},
+ "frame": {"x":107,"y":271,"w":12,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":12,"h":14},
@@ -402,7 +410,7 @@
},
"dark/project.png":
{
- "frame": {"x":109,"y":234,"w":16,"h":15},
+ "frame": {"x":73,"y":253,"w":16,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":15},
@@ -418,7 +426,7 @@
},
"dark/scale.png":
{
- "frame": {"x":1,"y":163,"w":16,"h":16},
+ "frame": {"x":19,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -426,7 +434,7 @@
},
"dark/select-region.png":
{
- "frame": {"x":19,"y":145,"w":16,"h":16},
+ "frame": {"x":37,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -434,7 +442,7 @@
},
"dark/spine.png":
{
- "frame": {"x":37,"y":127,"w":16,"h":16},
+ "frame": {"x":55,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -442,7 +450,7 @@
},
"dark/sprite-type.png":
{
- "frame": {"x":55,"y":109,"w":16,"h":16},
+ "frame": {"x":73,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -450,7 +458,7 @@
},
"dark/text-type.png":
{
- "frame": {"x":73,"y":91,"w":16,"h":16},
+ "frame": {"x":91,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -458,7 +466,7 @@
},
"dark/tilemap-layer.png":
{
- "frame": {"x":91,"y":73,"w":16,"h":16},
+ "frame": {"x":109,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -466,7 +474,7 @@
},
"dark/tilemap.png":
{
- "frame": {"x":109,"y":73,"w":16,"h":16},
+ "frame": {"x":1,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -474,7 +482,7 @@
},
"dark/tilesprite.png":
{
- "frame": {"x":91,"y":252,"w":16,"h":14},
+ "frame": {"x":55,"y":288,"w":16,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":14},
@@ -482,7 +490,7 @@
},
"dark/translate.png":
{
- "frame": {"x":1,"y":181,"w":16,"h":16},
+ "frame": {"x":19,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -490,7 +498,7 @@
},
"dark/unlocked.png":
{
- "frame": {"x":73,"y":269,"w":16,"h":13},
+ "frame": {"x":54,"y":304,"w":16,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":13},
@@ -498,7 +506,7 @@
},
"dark/user-component.png":
{
- "frame": {"x":19,"y":163,"w":16,"h":16},
+ "frame": {"x":37,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -506,7 +514,7 @@
},
"light/3slice.png":
{
- "frame": {"x":37,"y":145,"w":16,"h":16},
+ "frame": {"x":55,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -514,7 +522,7 @@
},
"light/9slice.png":
{
- "frame": {"x":55,"y":127,"w":16,"h":16},
+ "frame": {"x":73,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -522,7 +530,7 @@
},
"light/align-bottom.png":
{
- "frame": {"x":73,"y":109,"w":16,"h":16},
+ "frame": {"x":91,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -530,7 +538,7 @@
},
"light/align-center.png":
{
- "frame": {"x":91,"y":91,"w":16,"h":16},
+ "frame": {"x":109,"y":91,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -538,7 +546,7 @@
},
"light/align-left.png":
{
- "frame": {"x":109,"y":91,"w":16,"h":16},
+ "frame": {"x":1,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -546,7 +554,7 @@
},
"light/align-middle.png":
{
- "frame": {"x":1,"y":199,"w":16,"h":16},
+ "frame": {"x":19,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -554,7 +562,7 @@
},
"light/align-right.png":
{
- "frame": {"x":19,"y":181,"w":16,"h":16},
+ "frame": {"x":37,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -562,7 +570,7 @@
},
"light/align-top.png":
{
- "frame": {"x":37,"y":163,"w":16,"h":16},
+ "frame": {"x":55,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -570,7 +578,7 @@
},
"light/angle.png":
{
- "frame": {"x":55,"y":145,"w":16,"h":16},
+ "frame": {"x":73,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -578,7 +586,15 @@
},
"light/animations.png":
{
- "frame": {"x":73,"y":127,"w":16,"h":16},
+ "frame": {"x":91,"y":109,"w":16,"h":16},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
+ "sourceSize": {"w":16,"h":16}
+},
+"light/aseprite.png":
+{
+ "frame": {"x":1,"y":73,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -586,7 +602,7 @@
},
"light/asset-pack.png":
{
- "frame": {"x":91,"y":109,"w":16,"h":16},
+ "frame": {"x":109,"y":109,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -594,7 +610,7 @@
},
"light/bitmapfont-type.png":
{
- "frame": {"x":55,"y":271,"w":15,"h":16},
+ "frame": {"x":91,"y":235,"w":15,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":15,"h":16},
@@ -602,7 +618,7 @@
},
"light/blocks.png":
{
- "frame": {"x":109,"y":109,"w":16,"h":16},
+ "frame": {"x":1,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -610,7 +626,7 @@
},
"light/border-bottom.png":
{
- "frame": {"x":1,"y":217,"w":16,"h":16},
+ "frame": {"x":19,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -618,7 +634,7 @@
},
"light/border-center.png":
{
- "frame": {"x":19,"y":199,"w":16,"h":16},
+ "frame": {"x":37,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -626,7 +642,7 @@
},
"light/border-left.png":
{
- "frame": {"x":37,"y":181,"w":16,"h":16},
+ "frame": {"x":55,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -634,7 +650,7 @@
},
"light/border-middle.png":
{
- "frame": {"x":55,"y":163,"w":16,"h":16},
+ "frame": {"x":73,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -642,7 +658,7 @@
},
"light/border-right.png":
{
- "frame": {"x":73,"y":145,"w":16,"h":16},
+ "frame": {"x":91,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -658,7 +674,7 @@
},
"light/border-top.png":
{
- "frame": {"x":91,"y":127,"w":16,"h":16},
+ "frame": {"x":109,"y":127,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -666,7 +682,7 @@
},
"light/build.png":
{
- "frame": {"x":109,"y":127,"w":16,"h":16},
+ "frame": {"x":1,"y":235,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -674,7 +690,7 @@
},
"light/collider.png":
{
- "frame": {"x":1,"y":235,"w":16,"h":16},
+ "frame": {"x":19,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -682,7 +698,7 @@
},
"light/column.png":
{
- "frame": {"x":19,"y":217,"w":16,"h":16},
+ "frame": {"x":37,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -698,7 +714,7 @@
},
"light/file-font.png":
{
- "frame": {"x":69,"y":289,"w":13,"h":16},
+ "frame": {"x":106,"y":253,"w":13,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":13,"h":16},
@@ -706,7 +722,7 @@
},
"light/file-image.png":
{
- "frame": {"x":37,"y":199,"w":16,"h":16},
+ "frame": {"x":55,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -714,7 +730,7 @@
},
"light/file-movie.png":
{
- "frame": {"x":55,"y":181,"w":16,"h":16},
+ "frame": {"x":73,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -722,7 +738,7 @@
},
"light/file-new.png":
{
- "frame": {"x":73,"y":163,"w":16,"h":16},
+ "frame": {"x":91,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -730,7 +746,7 @@
},
"light/file-script.png":
{
- "frame": {"x":91,"y":145,"w":16,"h":16},
+ "frame": {"x":109,"y":145,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -738,7 +754,7 @@
},
"light/file-sound.png":
{
- "frame": {"x":109,"y":145,"w":16,"h":16},
+ "frame": {"x":1,"y":253,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -746,7 +762,7 @@
},
"light/file-text.png":
{
- "frame": {"x":1,"y":253,"w":16,"h":16},
+ "frame": {"x":19,"y":235,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -754,7 +770,7 @@
},
"light/grid.png":
{
- "frame": {"x":19,"y":235,"w":16,"h":16},
+ "frame": {"x":37,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -762,7 +778,7 @@
},
"light/group.png":
{
- "frame": {"x":37,"y":217,"w":16,"h":16},
+ "frame": {"x":55,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -770,7 +786,7 @@
},
"light/image-type.png":
{
- "frame": {"x":84,"y":300,"w":14,"h":14},
+ "frame": {"x":91,"y":287,"w":14,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":14,"h":14},
@@ -778,7 +794,7 @@
},
"light/inspector.png":
{
- "frame": {"x":55,"y":199,"w":16,"h":16},
+ "frame": {"x":73,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -786,7 +802,7 @@
},
"light/keyboard-key.png":
{
- "frame": {"x":73,"y":181,"w":16,"h":16},
+ "frame": {"x":91,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -794,7 +810,7 @@
},
"light/layer.png":
{
- "frame": {"x":91,"y":163,"w":16,"h":16},
+ "frame": {"x":109,"y":163,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -802,7 +818,7 @@
},
"light/list.png":
{
- "frame": {"x":91,"y":235,"w":16,"h":15},
+ "frame": {"x":73,"y":270,"w":16,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":15},
@@ -810,7 +826,7 @@
},
"light/locked.png":
{
- "frame": {"x":100,"y":300,"w":11,"h":13},
+ "frame": {"x":104,"y":303,"w":11,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":11,"h":13},
@@ -818,7 +834,7 @@
},
"light/origin-bottomcenter.png":
{
- "frame": {"x":109,"y":163,"w":16,"h":16},
+ "frame": {"x":1,"y":271,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -826,7 +842,7 @@
},
"light/origin-bottomleft.png":
{
- "frame": {"x":1,"y":271,"w":16,"h":16},
+ "frame": {"x":19,"y":253,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -834,7 +850,7 @@
},
"light/origin-bottomright.png":
{
- "frame": {"x":19,"y":253,"w":16,"h":16},
+ "frame": {"x":37,"y":235,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -842,7 +858,7 @@
},
"light/origin-middlecenter.png":
{
- "frame": {"x":37,"y":235,"w":16,"h":16},
+ "frame": {"x":55,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -850,7 +866,7 @@
},
"light/origin-middleleft.png":
{
- "frame": {"x":55,"y":217,"w":16,"h":16},
+ "frame": {"x":73,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -858,7 +874,7 @@
},
"light/origin-middleright.png":
{
- "frame": {"x":73,"y":199,"w":16,"h":16},
+ "frame": {"x":91,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -866,7 +882,7 @@
},
"light/origin-topcenter.png":
{
- "frame": {"x":91,"y":181,"w":16,"h":16},
+ "frame": {"x":109,"y":181,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -874,7 +890,7 @@
},
"light/origin-topleft.png":
{
- "frame": {"x":109,"y":181,"w":16,"h":16},
+ "frame": {"x":1,"y":289,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -882,7 +898,7 @@
},
"light/origin-topright.png":
{
- "frame": {"x":1,"y":289,"w":16,"h":16},
+ "frame": {"x":19,"y":271,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -890,7 +906,7 @@
},
"light/origin.png":
{
- "frame": {"x":19,"y":271,"w":16,"h":16},
+ "frame": {"x":37,"y":253,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -898,7 +914,7 @@
},
"light/outline.png":
{
- "frame": {"x":37,"y":253,"w":16,"h":16},
+ "frame": {"x":55,"y":235,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -906,7 +922,7 @@
},
"light/play.png":
{
- "frame": {"x":98,"y":284,"w":12,"h":14},
+ "frame": {"x":90,"y":303,"w":12,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":12,"h":14},
@@ -914,7 +930,7 @@
},
"light/project.png":
{
- "frame": {"x":109,"y":251,"w":16,"h":15},
+ "frame": {"x":108,"y":235,"w":16,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":15},
@@ -930,7 +946,7 @@
},
"light/scale.png":
{
- "frame": {"x":55,"y":235,"w":16,"h":16},
+ "frame": {"x":73,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -938,7 +954,7 @@
},
"light/select-region.png":
{
- "frame": {"x":73,"y":217,"w":16,"h":16},
+ "frame": {"x":91,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -946,7 +962,7 @@
},
"light/spine.png":
{
- "frame": {"x":91,"y":199,"w":16,"h":16},
+ "frame": {"x":109,"y":199,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -954,7 +970,7 @@
},
"light/sprite-type.png":
{
- "frame": {"x":109,"y":199,"w":16,"h":16},
+ "frame": {"x":19,"y":289,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -962,7 +978,7 @@
},
"light/text-type.png":
{
- "frame": {"x":19,"y":289,"w":16,"h":16},
+ "frame": {"x":37,"y":271,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -970,7 +986,7 @@
},
"light/tilemap-layer.png":
{
- "frame": {"x":37,"y":271,"w":16,"h":16},
+ "frame": {"x":55,"y":253,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -978,7 +994,7 @@
},
"light/tilemap.png":
{
- "frame": {"x":55,"y":253,"w":16,"h":16},
+ "frame": {"x":73,"y":235,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -986,7 +1002,7 @@
},
"light/tilesprite.png":
{
- "frame": {"x":73,"y":253,"w":16,"h":14},
+ "frame": {"x":73,"y":287,"w":16,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":14},
@@ -994,7 +1010,7 @@
},
"light/translate.png":
{
- "frame": {"x":73,"y":235,"w":16,"h":16},
+ "frame": {"x":91,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -1002,7 +1018,7 @@
},
"light/unlocked.png":
{
- "frame": {"x":91,"y":268,"w":16,"h":13},
+ "frame": {"x":72,"y":304,"w":16,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":16,"h":13},
@@ -1010,7 +1026,7 @@
},
"light/user-component.png":
{
- "frame": {"x":91,"y":217,"w":16,"h":16},
+ "frame": {"x":109,"y":217,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
@@ -1021,8 +1037,8 @@
"version": "1.0",
"image": "atlas@1x.png",
"format": "RGBA8888",
- "size": {"w":126,"h":315},
+ "size": {"w":126,"h":318},
"scale": "1",
- "smartupdate": "$TexturePacker:SmartUpdate:1d7560dab3bc8230de7b90d61fae75cd:0a0072a306be10c3e37a3d7445f0513b:a6f74b55a90107bc4ae6d23dde1c2d9e$"
+ "smartupdate": "$TexturePacker:SmartUpdate:8f7e6fa8c50e6e4a1a10036e7c58450f:5241bfccae5d16a07ca49ffa984ca94e:a6f74b55a90107bc4ae6d23dde1c2d9e$"
}
}
diff --git a/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.png b/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.png
index 9485ae8ba..e34775b8a 100644
Binary files a/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.png and b/source/editor/plugins/phasereditor2d.resources/icons/atlas@1x.png differ
diff --git a/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.json b/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.json
index d0b4ee4a3..49205b0aa 100644
--- a/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.json
+++ b/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.json
@@ -2,7 +2,7 @@
"dark/3slice@2x.png":
{
- "frame": {"x":137,"y":228,"w":32,"h":26},
+ "frame": {"x":170,"y":228,"w":32,"h":26},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":32,"h":26},
@@ -18,7 +18,7 @@
},
"dark/align-bottom@2x.png":
{
- "frame": {"x":457,"y":159,"w":28,"h":30},
+ "frame": {"x":427,"y":191,"w":28,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":28,"h":30},
@@ -26,7 +26,7 @@
},
"dark/align-center@2x.png":
{
- "frame": {"x":235,"y":33,"w":32,"h":28},
+ "frame": {"x":235,"y":1,"w":32,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":32,"h":28},
@@ -34,7 +34,7 @@
},
"dark/align-left@2x.png":
{
- "frame": {"x":199,"y":97,"w":32,"h":29},
+ "frame": {"x":201,"y":1,"w":32,"h":29},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":32,"h":29},
@@ -42,7 +42,7 @@
},
"dark/align-middle@2x.png":
{
- "frame": {"x":35,"y":205,"w":32,"h":31},
+ "frame": {"x":68,"y":171,"w":32,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":31},
@@ -50,7 +50,7 @@
},
"dark/align-right@2x.png":
{
- "frame": {"x":102,"y":135,"w":32,"h":30},
+ "frame": {"x":102,"y":168,"w":32,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":30},
@@ -58,7 +58,7 @@
},
"dark/align-top@2x.png":
{
- "frame": {"x":68,"y":137,"w":32,"h":31},
+ "frame": {"x":68,"y":204,"w":32,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":31},
@@ -66,7 +66,7 @@
},
"dark/angle@2x.png":
{
- "frame": {"x":135,"y":34,"w":31,"h":30},
+ "frame": {"x":136,"y":34,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -74,15 +74,23 @@
},
"dark/animations@2x.png":
{
- "frame": {"x":69,"y":1,"w":31,"h":31},
+ "frame": {"x":69,"y":67,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
"sourceSize": {"w":32,"h":32}
},
+"dark/aseprite@2x.png":
+{
+ "frame": {"x":1,"y":35,"w":32,"h":32},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
+ "sourceSize": {"w":32,"h":32}
+},
"dark/asset-pack@2x.png":
{
- "frame": {"x":233,"y":1,"w":30,"h":30},
+ "frame": {"x":202,"y":32,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -90,7 +98,7 @@
},
"dark/bitmapfont-type@2x.png":
{
- "frame": {"x":426,"y":159,"w":29,"h":30},
+ "frame": {"x":457,"y":95,"w":29,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":29,"h":30},
@@ -98,7 +106,7 @@
},
"dark/blocks@2x.png":
{
- "frame": {"x":201,"y":64,"w":30,"h":30},
+ "frame": {"x":201,"y":96,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -106,7 +114,7 @@
},
"dark/border-bottom@2x.png":
{
- "frame": {"x":202,"y":128,"w":30,"h":30},
+ "frame": {"x":232,"y":128,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -114,7 +122,7 @@
},
"dark/border-center@2x.png":
{
- "frame": {"x":202,"y":160,"w":30,"h":30},
+ "frame": {"x":203,"y":64,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -122,7 +130,7 @@
},
"dark/border-left@2x.png":
{
- "frame": {"x":167,"y":1,"w":31,"h":30},
+ "frame": {"x":168,"y":1,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -130,7 +138,7 @@
},
"dark/border-middle@2x.png":
{
- "frame": {"x":203,"y":192,"w":30,"h":30},
+ "frame": {"x":234,"y":32,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -138,7 +146,7 @@
},
"dark/border-right@2x.png":
{
- "frame": {"x":35,"y":137,"w":31,"h":32},
+ "frame": {"x":35,"y":171,"w":31,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":31,"h":32},
@@ -146,7 +154,7 @@
},
"dark/border-top@2x.png":
{
- "frame": {"x":205,"y":224,"w":30,"h":30},
+ "frame": {"x":233,"y":96,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -154,7 +162,7 @@
},
"dark/build@2x.png":
{
- "frame": {"x":233,"y":64,"w":30,"h":30},
+ "frame": {"x":235,"y":64,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -162,7 +170,7 @@
},
"dark/collider@2x.png":
{
- "frame": {"x":136,"y":132,"w":31,"h":30},
+ "frame": {"x":136,"y":165,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -170,7 +178,7 @@
},
"dark/column@2x.png":
{
- "frame": {"x":489,"y":1,"w":10,"h":30},
+ "frame": {"x":495,"y":1,"w":10,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":1,"w":10,"h":30},
@@ -178,7 +186,7 @@
},
"dark/dot@2x.png":
{
- "frame": {"x":65,"y":238,"w":10,"h":10},
+ "frame": {"x":65,"y":239,"w":10,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":11,"w":10,"h":10},
@@ -186,7 +194,7 @@
},
"dark/file-font@2x.png":
{
- "frame": {"x":458,"y":191,"w":24,"h":30},
+ "frame": {"x":457,"y":191,"w":24,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":1,"w":24,"h":30},
@@ -194,7 +202,7 @@
},
"dark/file-image@2x.png":
{
- "frame": {"x":265,"y":1,"w":30,"h":30},
+ "frame": {"x":266,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -202,7 +210,7 @@
},
"dark/file-movie@2x.png":
{
- "frame": {"x":233,"y":96,"w":30,"h":30},
+ "frame": {"x":235,"y":160,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -210,7 +218,7 @@
},
"dark/file-new@2x.png":
{
- "frame": {"x":234,"y":128,"w":30,"h":30},
+ "frame": {"x":264,"y":128,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -218,7 +226,7 @@
},
"dark/file-script@2x.png":
{
- "frame": {"x":166,"y":99,"w":31,"h":30},
+ "frame": {"x":166,"y":132,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -226,7 +234,7 @@
},
"dark/file-sound@2x.png":
{
- "frame": {"x":234,"y":160,"w":30,"h":30},
+ "frame": {"x":265,"y":96,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -234,7 +242,7 @@
},
"dark/file-text@2x.png":
{
- "frame": {"x":102,"y":167,"w":32,"h":30},
+ "frame": {"x":102,"y":200,"w":32,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":32,"h":30},
@@ -242,7 +250,7 @@
},
"dark/grid@2x.png":
{
- "frame": {"x":235,"y":192,"w":30,"h":30},
+ "frame": {"x":267,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -250,7 +258,7 @@
},
"dark/group@2x.png":
{
- "frame": {"x":237,"y":224,"w":30,"h":30},
+ "frame": {"x":298,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -258,7 +266,7 @@
},
"dark/image-type@2x.png":
{
- "frame": {"x":457,"y":85,"w":24,"h":24},
+ "frame": {"x":460,"y":223,"w":24,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":24,"h":24},
@@ -266,7 +274,7 @@
},
"dark/inspector@2x.png":
{
- "frame": {"x":134,"y":99,"w":30,"h":31},
+ "frame": {"x":134,"y":132,"w":30,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":31},
@@ -274,7 +282,7 @@
},
"dark/keyboard-key@2x.png":
{
- "frame": {"x":1,"y":35,"w":32,"h":32},
+ "frame": {"x":1,"y":69,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -282,7 +290,7 @@
},
"dark/layer@2x.png":
{
- "frame": {"x":265,"y":63,"w":30,"h":30},
+ "frame": {"x":235,"y":192,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -290,7 +298,7 @@
},
"dark/list@2x.png":
{
- "frame": {"x":303,"y":33,"w":30,"h":28},
+ "frame": {"x":303,"y":1,"w":30,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":28},
@@ -298,7 +306,7 @@
},
"dark/locked@2x.png":
{
- "frame": {"x":485,"y":219,"w":20,"h":24},
+ "frame": {"x":488,"y":91,"w":20,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":3,"w":20,"h":24},
@@ -306,7 +314,7 @@
},
"dark/origin-bottomcenter@2x.png":
{
- "frame": {"x":297,"y":1,"w":30,"h":30},
+ "frame": {"x":238,"y":224,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -314,7 +322,7 @@
},
"dark/origin-bottomleft@2x.png":
{
- "frame": {"x":265,"y":95,"w":30,"h":30},
+ "frame": {"x":267,"y":160,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -322,7 +330,7 @@
},
"dark/origin-bottomright@2x.png":
{
- "frame": {"x":266,"y":127,"w":30,"h":30},
+ "frame": {"x":296,"y":128,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -330,7 +338,7 @@
},
"dark/origin-middlecenter@2x.png":
{
- "frame": {"x":266,"y":159,"w":30,"h":30},
+ "frame": {"x":297,"y":95,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -338,7 +346,7 @@
},
"dark/origin-middleleft@2x.png":
{
- "frame": {"x":267,"y":191,"w":30,"h":30},
+ "frame": {"x":299,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -346,7 +354,7 @@
},
"dark/origin-middleright@2x.png":
{
- "frame": {"x":269,"y":223,"w":30,"h":30},
+ "frame": {"x":330,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -354,7 +362,7 @@
},
"dark/origin-topcenter@2x.png":
{
- "frame": {"x":297,"y":63,"w":30,"h":30},
+ "frame": {"x":267,"y":192,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -362,7 +370,7 @@
},
"dark/origin-topleft@2x.png":
{
- "frame": {"x":329,"y":1,"w":30,"h":30},
+ "frame": {"x":270,"y":224,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -370,7 +378,7 @@
},
"dark/origin-topright@2x.png":
{
- "frame": {"x":297,"y":95,"w":30,"h":30},
+ "frame": {"x":299,"y":160,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -378,7 +386,7 @@
},
"dark/origin@2x.png":
{
- "frame": {"x":69,"y":34,"w":31,"h":31},
+ "frame": {"x":69,"y":100,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
@@ -386,7 +394,7 @@
},
"dark/outline@2x.png":
{
- "frame": {"x":298,"y":127,"w":30,"h":30},
+ "frame": {"x":328,"y":127,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -394,7 +402,7 @@
},
"dark/play@2x.png":
{
- "frame": {"x":484,"y":191,"w":22,"h":26},
+ "frame": {"x":485,"y":159,"w":22,"h":26},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":22,"h":26},
@@ -402,7 +410,7 @@
},
"dark/project@2x.png":
{
- "frame": {"x":335,"y":33,"w":30,"h":28},
+ "frame": {"x":335,"y":1,"w":30,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":3,"w":30,"h":28},
@@ -418,7 +426,7 @@
},
"dark/scale@2x.png":
{
- "frame": {"x":136,"y":164,"w":31,"h":30},
+ "frame": {"x":168,"y":99,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -426,7 +434,7 @@
},
"dark/select-region@2x.png":
{
- "frame": {"x":137,"y":196,"w":31,"h":30},
+ "frame": {"x":136,"y":197,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -434,7 +442,7 @@
},
"dark/spine@2x.png":
{
- "frame": {"x":1,"y":69,"w":32,"h":32},
+ "frame": {"x":1,"y":103,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -442,7 +450,7 @@
},
"dark/sprite-type@2x.png":
{
- "frame": {"x":69,"y":67,"w":31,"h":31},
+ "frame": {"x":69,"y":133,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
@@ -450,7 +458,7 @@
},
"dark/text-type@2x.png":
{
- "frame": {"x":298,"y":159,"w":30,"h":30},
+ "frame": {"x":329,"y":95,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -458,7 +466,7 @@
},
"dark/tilemap-layer@2x.png":
{
- "frame": {"x":1,"y":103,"w":32,"h":32},
+ "frame": {"x":1,"y":137,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -466,7 +474,7 @@
},
"dark/tilemap@2x.png":
{
- "frame": {"x":1,"y":137,"w":32,"h":32},
+ "frame": {"x":1,"y":171,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -474,7 +482,7 @@
},
"dark/tilesprite@2x.png":
{
- "frame": {"x":171,"y":227,"w":32,"h":24},
+ "frame": {"x":136,"y":229,"w":32,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":32,"h":24},
@@ -482,7 +490,7 @@
},
"dark/translate@2x.png":
{
- "frame": {"x":299,"y":191,"w":30,"h":30},
+ "frame": {"x":331,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -490,7 +498,7 @@
},
"dark/unlocked@2x.png":
{
- "frame": {"x":457,"y":59,"w":30,"h":24},
+ "frame": {"x":431,"y":1,"w":30,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":3,"w":30,"h":24},
@@ -498,7 +506,7 @@
},
"dark/user-component@2x.png":
{
- "frame": {"x":102,"y":67,"w":30,"h":32},
+ "frame": {"x":102,"y":100,"w":30,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":30,"h":32},
@@ -506,7 +514,7 @@
},
"light/3slice@2x.png":
{
- "frame": {"x":1,"y":171,"w":32,"h":32},
+ "frame": {"x":1,"y":205,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -514,7 +522,7 @@
},
"light/9slice@2x.png":
{
- "frame": {"x":1,"y":205,"w":32,"h":32},
+ "frame": {"x":35,"y":1,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -522,7 +530,7 @@
},
"light/align-bottom@2x.png":
{
- "frame": {"x":429,"y":223,"w":28,"h":30},
+ "frame": {"x":430,"y":223,"w":28,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":28,"h":30},
@@ -530,7 +538,7 @@
},
"light/align-center@2x.png":
{
- "frame": {"x":269,"y":33,"w":32,"h":28},
+ "frame": {"x":269,"y":1,"w":32,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":32,"h":28},
@@ -538,7 +546,7 @@
},
"light/align-left@2x.png":
{
- "frame": {"x":201,"y":33,"w":32,"h":29},
+ "frame": {"x":169,"y":65,"w":32,"h":29},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":32,"h":29},
@@ -546,7 +554,7 @@
},
"light/align-middle@2x.png":
{
- "frame": {"x":68,"y":170,"w":32,"h":31},
+ "frame": {"x":69,"y":1,"w":32,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":31},
@@ -554,7 +562,7 @@
},
"light/align-right@2x.png":
{
- "frame": {"x":103,"y":199,"w":32,"h":30},
+ "frame": {"x":134,"y":100,"w":32,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":30},
@@ -562,7 +570,7 @@
},
"light/align-top@2x.png":
{
- "frame": {"x":69,"y":203,"w":32,"h":31},
+ "frame": {"x":69,"y":34,"w":32,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":31},
@@ -570,7 +578,7 @@
},
"light/angle@2x.png":
{
- "frame": {"x":169,"y":131,"w":31,"h":30},
+ "frame": {"x":169,"y":164,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -578,15 +586,23 @@
},
"light/animations@2x.png":
{
- "frame": {"x":69,"y":100,"w":31,"h":31},
+ "frame": {"x":102,"y":67,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
"sourceSize": {"w":32,"h":32}
},
+"light/aseprite@2x.png":
+{
+ "frame": {"x":1,"y":35,"w":32,"h":32},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
+ "sourceSize": {"w":32,"h":32}
+},
"light/asset-pack@2x.png":
{
- "frame": {"x":301,"y":223,"w":30,"h":30},
+ "frame": {"x":362,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -594,7 +610,7 @@
},
"light/bitmapfont-type@2x.png":
{
- "frame": {"x":427,"y":191,"w":29,"h":30},
+ "frame": {"x":459,"y":59,"w":29,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":29,"h":30},
@@ -602,7 +618,7 @@
},
"light/blocks@2x.png":
{
- "frame": {"x":329,"y":63,"w":30,"h":30},
+ "frame": {"x":299,"y":192,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -610,7 +626,7 @@
},
"light/border-bottom@2x.png":
{
- "frame": {"x":361,"y":1,"w":30,"h":30},
+ "frame": {"x":302,"y":224,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -618,7 +634,7 @@
},
"light/border-center@2x.png":
{
- "frame": {"x":329,"y":95,"w":30,"h":30},
+ "frame": {"x":331,"y":159,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -626,7 +642,7 @@
},
"light/border-left@2x.png":
{
- "frame": {"x":169,"y":163,"w":31,"h":30},
+ "frame": {"x":199,"y":131,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -634,7 +650,7 @@
},
"light/border-middle@2x.png":
{
- "frame": {"x":330,"y":127,"w":30,"h":30},
+ "frame": {"x":360,"y":127,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -642,7 +658,7 @@
},
"light/border-right@2x.png":
{
- "frame": {"x":35,"y":171,"w":31,"h":32},
+ "frame": {"x":35,"y":205,"w":31,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":31,"h":32},
@@ -658,7 +674,7 @@
},
"light/border-top@2x.png":
{
- "frame": {"x":330,"y":159,"w":30,"h":30},
+ "frame": {"x":361,"y":95,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -666,7 +682,7 @@
},
"light/build@2x.png":
{
- "frame": {"x":331,"y":191,"w":30,"h":30},
+ "frame": {"x":363,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -674,7 +690,7 @@
},
"light/collider@2x.png":
{
- "frame": {"x":170,"y":195,"w":31,"h":30},
+ "frame": {"x":169,"y":196,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -682,7 +698,7 @@
},
"light/column@2x.png":
{
- "frame": {"x":487,"y":139,"w":10,"h":30},
+ "frame": {"x":490,"y":33,"w":10,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":1,"w":10,"h":30},
@@ -690,7 +706,7 @@
},
"light/dot@2x.png":
{
- "frame": {"x":77,"y":236,"w":10,"h":10},
+ "frame": {"x":77,"y":237,"w":10,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":11,"w":10,"h":10},
@@ -698,7 +714,7 @@
},
"light/file-font@2x.png":
{
- "frame": {"x":459,"y":223,"w":24,"h":30},
+ "frame": {"x":459,"y":159,"w":24,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":1,"w":24,"h":30},
@@ -706,7 +722,7 @@
},
"light/file-image@2x.png":
{
- "frame": {"x":333,"y":223,"w":30,"h":30},
+ "frame": {"x":394,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -714,7 +730,7 @@
},
"light/file-movie@2x.png":
{
- "frame": {"x":361,"y":63,"w":30,"h":30},
+ "frame": {"x":331,"y":191,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -722,7 +738,7 @@
},
"light/file-new@2x.png":
{
- "frame": {"x":393,"y":1,"w":30,"h":30},
+ "frame": {"x":334,"y":223,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -730,7 +746,7 @@
},
"light/file-script@2x.png":
{
- "frame": {"x":168,"y":33,"w":31,"h":30},
+ "frame": {"x":202,"y":163,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -738,7 +754,7 @@
},
"light/file-sound@2x.png":
{
- "frame": {"x":361,"y":95,"w":30,"h":30},
+ "frame": {"x":363,"y":159,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -746,7 +762,7 @@
},
"light/file-text@2x.png":
{
- "frame": {"x":134,"y":67,"w":32,"h":30},
+ "frame": {"x":135,"y":67,"w":32,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":32,"h":30},
@@ -754,7 +770,7 @@
},
"light/grid@2x.png":
{
- "frame": {"x":362,"y":127,"w":30,"h":30},
+ "frame": {"x":392,"y":127,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -762,7 +778,7 @@
},
"light/group@2x.png":
{
- "frame": {"x":362,"y":159,"w":30,"h":30},
+ "frame": {"x":393,"y":95,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -770,7 +786,7 @@
},
"light/image-type@2x.png":
{
- "frame": {"x":480,"y":113,"w":24,"h":24},
+ "frame": {"x":483,"y":191,"w":24,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":24,"h":24},
@@ -778,7 +794,7 @@
},
"light/inspector@2x.png":
{
- "frame": {"x":135,"y":1,"w":30,"h":31},
+ "frame": {"x":136,"y":1,"w":30,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":31},
@@ -786,7 +802,7 @@
},
"light/keyboard-key@2x.png":
{
- "frame": {"x":35,"y":1,"w":32,"h":32},
+ "frame": {"x":35,"y":35,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -794,7 +810,7 @@
},
"light/layer@2x.png":
{
- "frame": {"x":363,"y":191,"w":30,"h":30},
+ "frame": {"x":395,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -802,7 +818,7 @@
},
"light/list@2x.png":
{
- "frame": {"x":367,"y":33,"w":30,"h":28},
+ "frame": {"x":367,"y":1,"w":30,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":28},
@@ -810,7 +826,7 @@
},
"light/locked@2x.png":
{
- "frame": {"x":458,"y":111,"w":20,"h":24},
+ "frame": {"x":488,"y":117,"w":20,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":3,"w":20,"h":24},
@@ -818,7 +834,7 @@
},
"light/origin-bottomcenter@2x.png":
{
- "frame": {"x":365,"y":223,"w":30,"h":30},
+ "frame": {"x":426,"y":31,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -826,7 +842,7 @@
},
"light/origin-bottomleft@2x.png":
{
- "frame": {"x":393,"y":63,"w":30,"h":30},
+ "frame": {"x":363,"y":191,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -834,7 +850,7 @@
},
"light/origin-bottomright@2x.png":
{
- "frame": {"x":425,"y":1,"w":30,"h":30},
+ "frame": {"x":366,"y":223,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -842,7 +858,7 @@
},
"light/origin-middlecenter@2x.png":
{
- "frame": {"x":393,"y":95,"w":30,"h":30},
+ "frame": {"x":395,"y":159,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -850,7 +866,7 @@
},
"light/origin-middleleft@2x.png":
{
- "frame": {"x":394,"y":127,"w":30,"h":30},
+ "frame": {"x":424,"y":127,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -858,7 +874,7 @@
},
"light/origin-middleright@2x.png":
{
- "frame": {"x":394,"y":159,"w":30,"h":30},
+ "frame": {"x":425,"y":95,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -866,7 +882,7 @@
},
"light/origin-topcenter@2x.png":
{
- "frame": {"x":395,"y":191,"w":30,"h":30},
+ "frame": {"x":427,"y":63,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -874,7 +890,7 @@
},
"light/origin-topleft@2x.png":
{
- "frame": {"x":397,"y":223,"w":30,"h":30},
+ "frame": {"x":458,"y":27,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -882,7 +898,7 @@
},
"light/origin-topright@2x.png":
{
- "frame": {"x":425,"y":63,"w":30,"h":30},
+ "frame": {"x":395,"y":191,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -890,7 +906,7 @@
},
"light/origin@2x.png":
{
- "frame": {"x":102,"y":1,"w":31,"h":31},
+ "frame": {"x":103,"y":1,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
@@ -898,7 +914,7 @@
},
"light/outline@2x.png":
{
- "frame": {"x":457,"y":1,"w":30,"h":30},
+ "frame": {"x":398,"y":223,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -906,7 +922,7 @@
},
"light/play@2x.png":
{
- "frame": {"x":483,"y":85,"w":22,"h":26},
+ "frame": {"x":486,"y":217,"w":22,"h":26},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":22,"h":26},
@@ -914,7 +930,7 @@
},
"light/project@2x.png":
{
- "frame": {"x":399,"y":33,"w":30,"h":28},
+ "frame": {"x":399,"y":1,"w":30,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":3,"w":30,"h":28},
@@ -930,7 +946,7 @@
},
"light/scale@2x.png":
{
- "frame": {"x":200,"y":1,"w":31,"h":30},
+ "frame": {"x":202,"y":195,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":31,"h":30},
@@ -938,7 +954,7 @@
},
"light/select-region@2x.png":
{
- "frame": {"x":168,"y":65,"w":31,"h":30},
+ "frame": {"x":169,"y":33,"w":31,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":30},
@@ -946,7 +962,7 @@
},
"light/spine@2x.png":
{
- "frame": {"x":35,"y":35,"w":32,"h":32},
+ "frame": {"x":35,"y":69,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -954,7 +970,7 @@
},
"light/sprite-type@2x.png":
{
- "frame": {"x":102,"y":34,"w":31,"h":31},
+ "frame": {"x":103,"y":34,"w":31,"h":31},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":31,"h":31},
@@ -962,7 +978,7 @@
},
"light/text-type@2x.png":
{
- "frame": {"x":425,"y":95,"w":30,"h":30},
+ "frame": {"x":427,"y":159,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -970,7 +986,7 @@
},
"light/tilemap-layer@2x.png":
{
- "frame": {"x":35,"y":69,"w":32,"h":32},
+ "frame": {"x":35,"y":103,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -978,7 +994,7 @@
},
"light/tilemap@2x.png":
{
- "frame": {"x":35,"y":103,"w":32,"h":32},
+ "frame": {"x":35,"y":137,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@@ -986,7 +1002,7 @@
},
"light/tilesprite@2x.png":
{
- "frame": {"x":431,"y":33,"w":32,"h":24},
+ "frame": {"x":204,"y":227,"w":32,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":32,"h":24},
@@ -994,7 +1010,7 @@
},
"light/translate@2x.png":
{
- "frame": {"x":426,"y":127,"w":30,"h":30},
+ "frame": {"x":456,"y":127,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":30,"h":30},
@@ -1002,7 +1018,7 @@
},
"light/unlocked@2x.png":
{
- "frame": {"x":465,"y":33,"w":30,"h":24},
+ "frame": {"x":463,"y":1,"w":30,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":3,"w":30,"h":24},
@@ -1010,7 +1026,7 @@
},
"light/user-component@2x.png":
{
- "frame": {"x":102,"y":101,"w":30,"h":32},
+ "frame": {"x":102,"y":134,"w":30,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":30,"h":32},
@@ -1021,8 +1037,8 @@
"version": "1.0",
"image": "atlas@2x.png",
"format": "RGBA8888",
- "size": {"w":507,"h":255},
+ "size": {"w":509,"h":255},
"scale": "1",
- "smartupdate": "$TexturePacker:SmartUpdate:5e67f5a1c8c9329ba77181c49fe873a7:f3bdf3a9c6869b70fb67e0931571668d:9eb1a82ac620c259737931966d4495d0$"
+ "smartupdate": "$TexturePacker:SmartUpdate:83f3fa35535afce5b5ea39c0ff8c8dd2:e9b9cbf5df6beb15642e03aafee2eb0b:9eb1a82ac620c259737931966d4495d0$"
}
}
diff --git a/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.png b/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.png
index 17d3c6359..1ddbcc945 100644
Binary files a/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.png and b/source/editor/plugins/phasereditor2d.resources/icons/atlas@2x.png differ
diff --git a/source/editor/plugins/phasereditor2d.resources/res.json b/source/editor/plugins/phasereditor2d.resources/res.json
index 5117320ca..f0071b57b 100644
--- a/source/editor/plugins/phasereditor2d.resources/res.json
+++ b/source/editor/plugins/phasereditor2d.resources/res.json
@@ -8,12 +8,16 @@
"Phaser.Types.Animations.Animation.yoyo": "Should the animation yoyo? (reverse back down to the start) before repeating?",
"Phaser.Types.Animations.Animation.showOnStart": "Should sprite.visible = true when the animation starts to play? This happens _after_ any delay, if set.",
"Phaser.Types.Animations.Animation.hideOnComplete": "Should sprite.visible = false when the animation finishes?",
- "Phaser.Types.Animations.Animation.skipMissedFrames": "Skip frames if the time lags, or always advanced anyway?"
+ "Phaser.Types.Animations.Animation.showBeforeDelay": "If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false)",
+ "Phaser.Types.Animations.Animation.skipMissedFrames": "Skip frames if the time lags, or always advanced anyway?",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame": "The frame of the animation to start playback from."
},
"phasereditor2d.pack/docs/phaser-docs.json": {
"Phaser.Loader.LoaderPlugin.atlas(atlasURL)": "The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `.json`, i.e. if `key` was \"alien\" then the URL will be \"alien.json\". Or, a well formed JSON object.",
"Phaser.Loader.LoaderPlugin.atlas(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig.normalMap": "The filename of an associated normal map. It uses the same path and url to load as the texture image.",
+ "Phaser.Loader.LoaderPlugin.aseprite(atlasURL)": "The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `.json`, i.e. if `key` was \"alien\" then the URL will be \"alien.json\". Or, a well formed JSON object.",
+ "Phaser.Loader.LoaderPlugin.aseprite(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Loader.LoaderPlugin.atlasXML(atlasURL)": "The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was \"alien\" then the URL will be \"alien.xml\".",
"Phaser.Loader.LoaderPlugin.atlasXML(textureURL)": "The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was \"alien\" then the URL will be \"alien.png\".",
"Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig.normalMap": "The filename of an associated normal map. It uses the same path and url to load as the texture image.",
@@ -500,6 +504,16 @@
"spine.SkinsAndAnimationBoundsProvider(timeStep)": "The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation.",
"spine.AnimationState.timeScale": "Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower\nor faster. Defaults to 1.\n\nSee TrackEntry {@link TrackEntry#timeScale} for affecting a single animation.",
"spine.AnimationStateData.defaultMix": "The mix duration to use when no mix duration has been defined between two animations.",
- "spine.AnimationStateData.setMixWith": "Sets the mix duration when changing from the specified animation to the other.\n\nSee {@link TrackEntry#mixDuration}."
+ "spine.AnimationStateData.setMixWith": "Sets the mix duration when changing from the specified animation to the other.\n\nSee {@link TrackEntry#mixDuration}.",
+ "Phaser.Types.Animations.PlayAnimationConfig.frameRate": "The frame rate of playback in frames per second (default 24 if duration is null)",
+ "Phaser.Types.Animations.PlayAnimationConfig.delay": "Delay before starting playback. Value given in milliseconds.",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeat": "Number of times to repeat the animation (-1 for infinity)",
+ "Phaser.Types.Animations.PlayAnimationConfig.repeatDelay": "Delay before the animation repeats. Value given in milliseconds.",
+ "Phaser.Types.Animations.PlayAnimationConfig.yoyo": "Should the animation yoyo? (reverse back down to the start) before repeating?",
+ "Phaser.Types.Animations.PlayAnimationConfig.showOnStart": "Should sprite.visible = true when the animation starts to play?",
+ "Phaser.Types.Animations.PlayAnimationConfig.hideOnComplete": "Should sprite.visible = false when the animation finishes?",
+ "Phaser.Types.Animations.PlayAnimationConfig.showBeforeDelay": "If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false)",
+ "Phaser.Types.Animations.PlayAnimationConfig.startFrame": "The frame of the animation to start playback from.",
+ "Phaser.Types.Animations.PlayAnimationConfig.timeScale": "The time scale to be applied to playback of this animation."
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.resources/src/ResourcesPlugin.ts b/source/editor/plugins/phasereditor2d.resources/src/ResourcesPlugin.ts
index f25863e4b..1d879cb5a 100644
--- a/source/editor/plugins/phasereditor2d.resources/src/ResourcesPlugin.ts
+++ b/source/editor/plugins/phasereditor2d.resources/src/ResourcesPlugin.ts
@@ -9,6 +9,7 @@ namespace phasereditor2d.resources {
// phasereditor2d.blocks
export const ICON_ASSET_PACK = "asset-pack";
export const ICON_ANIMATIONS = "animations";
+ export const ICON_ASEPRITE = "aseprite";
export const ICON_TILEMAP = "tilemap";
export const ICON_TILEMAP_LAYER = "tilemap-layer";
export const ICON_SPINE = "spine";
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts b/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts
index a4ab6930e..d3e53a1fa 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts
@@ -43,6 +43,7 @@ namespace phasereditor2d.scene {
private _docs: phasereditor2d.ide.core.PhaserDocs;
private _eventsDocs: phasereditor2d.ide.core.PhaserDocs;
private _spineThumbnailCache: ui.SpineThumbnailCache;
+ private _canvasManager: ui.CanvasManager;
static getInstance() {
@@ -54,6 +55,11 @@ namespace phasereditor2d.scene {
super("phasereditor2d.scene");
}
+ getCanvasManager() {
+
+ return this._canvasManager;
+ }
+
async starting() {
const type = window.localStorage.getItem("phasereditor2d.scene.RENDER_TYPE");
@@ -67,6 +73,8 @@ namespace phasereditor2d.scene {
this.setDefaultRenderPixelArt(pixelArt);
console.log("ScenePlugin: default pixelArt: " + pixelArt);
+
+ this._canvasManager = new ui.CanvasManager();
}
setDefaultRenderType(type?: "canvas" | "webgl") {
@@ -113,6 +121,8 @@ namespace phasereditor2d.scene {
this._sceneFinder = new core.json.SceneFinder();
+ this.registerAnimationsPreviewDialogInAssetPack();
+
// migrations
reg.addExtension(new core.migrations.OriginMigration_v2_to_v3());
@@ -245,6 +255,10 @@ namespace phasereditor2d.scene {
ui.sceneobjects.TilemapExtension.getInstance()
);
+ reg.addExtension(
+ new ui.codesnippets.CreateFromAsepriteCodeSnippetExtension()
+ );
+
// align extensions
reg.addExtension(...ui.editor.layout.DefaultLayoutExtensions.ALL);
@@ -289,6 +303,8 @@ namespace phasereditor2d.scene {
page => new ui.sceneobjects.ArcadeGeometrySection(page),
page => new ui.sceneobjects.ArcadeBodyMovementSection(page),
page => new ui.sceneobjects.ArcadeBodyCollisionSection(page),
+ page => new ui.sceneobjects.SpriteAnimationSection(page),
+ page => new ui.sceneobjects.SpriteAnimationConfigSection(page),
page => new ui.sceneobjects.TextContentSection(page),
page => new ui.sceneobjects.TextSection(page),
page => new ui.sceneobjects.BitmapTextSection(page),
@@ -307,7 +323,8 @@ namespace phasereditor2d.scene {
page => new ui.sceneobjects.TextureSection(page),
page => new ui.sceneobjects.SpineSection(page),
page => new ui.sceneobjects.SpineBoundsProviderSection(page),
- page => new ui.sceneobjects.SpineAnimationSection(page)
+ page => new ui.sceneobjects.SpineAnimationSection(page),
+ page => new ui.codesnippets.CreateFromAsepriteCodeSnippetSection(page)
));
// scene tools
@@ -352,6 +369,22 @@ namespace phasereditor2d.scene {
));
}
+ private registerAnimationsPreviewDialogInAssetPack() {
+
+ pack.ui.properties.AnimationsPreviewSection.openPreviewDialog = elem => {
+
+ const dlg = new ui.sceneobjects.AnimationPreviewDialog(elem.getParent(), {
+ key: elem.getKey()
+ });
+
+ dlg.create();
+ };
+ }
+
+ async openAnimationInEditor(anim: pack.core.AnimationConfigInPackItem) {
+ // nothing, it is injected in the AnimationsPlugin.
+ }
+
getTools() {
return colibri.Platform.getExtensions
(ui.editor.tools.SceneToolExtension.POINT_ID)
@@ -438,6 +471,17 @@ namespace phasereditor2d.scene {
return !file.isFolder() && colibri.Platform.getWorkbench().getContentTypeRegistry().getCachedContentType(file) === core.CONTENT_TYPE_SCENE;
}
+ getCodeSnippetExtensions() {
+
+ return colibri.Platform
+ .getExtensions(ui.codesnippets.CodeSnippetExtension.POINT_ID);
+ }
+
+ getCodeSnippetExtensionByType(type: string) {
+
+ return this.getCodeSnippetExtensions().find(e => e.getType() === type);
+ }
+
getPlainObjectExtensions() {
return colibri.Platform
diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts
index 8e7fe1f90..9fa992bef 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts
@@ -418,11 +418,25 @@ namespace phasereditor2d.scene.core.code {
this.join(args);
if (this.isTypeScript()
- && call.getExplicitType()
+ && (call.getExplicitType() || call.isNonNullAssertion())
&& call.isDeclareReturnToVar()
&& call.getReturnToVar()) {
- this.line(`) as ${call.getExplicitType()};`);
+ let line = ")";
+
+ if (call.isNonNullAssertion()) {
+
+ line += "!";
+ }
+
+ if (call.getExplicitType()) {
+
+ line += ` as ${call.getExplicitType()}`;
+ }
+
+ line += ";";
+
+ this.line(line);
} else {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts
index 0effa31fe..58b81fa2a 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts
@@ -10,6 +10,7 @@ namespace phasereditor2d.scene.core.code {
private _isConstructor: boolean;
private _explicitType: string;
private _optionalContext: boolean;
+ private _nonNullAssertion: boolean;
constructor(methodName: string, contextExpr = "") {
super();
@@ -19,6 +20,17 @@ namespace phasereditor2d.scene.core.code {
this._args = [];
this._declareReturnToVar = false;
this._isConstructor = false;
+ this._nonNullAssertion = false;
+ }
+
+ setNonNullAssertion(nonNullAssertion: boolean) {
+
+ this._nonNullAssertion = nonNullAssertion;
+ }
+
+ isNonNullAssertion() {
+
+ return this._nonNullAssertion;
}
setOptionalContext(optionalContext: boolean) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts
index b7b490292..82b274716 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts
@@ -382,6 +382,8 @@ namespace phasereditor2d.scene.core.code {
varname: "this"
});
+ this.buildCodeSnippets(result.statements);
+
lazyStatements.push(...result.lazyStatements);
body.push(...result.statements);
@@ -420,6 +422,24 @@ namespace phasereditor2d.scene.core.code {
return ctrDecl;
}
+ buildCodeSnippets(statements: CodeDOM[]) {
+
+ const snippets = this._scene.getCodeSnippets().getSnippets();
+
+ if (snippets.length > 0) {
+
+ statements.push(new code.RawCodeDOM(""));
+ statements.push(new code.RawCodeDOM("// snippets"));
+
+ for (const codeSnippet of snippets) {
+
+ const code = codeSnippet.buildCodeDOM();
+
+ statements.push(...code);
+ }
+ }
+ }
+
private buildPrefabTypeScriptDefinitionsCodeDOM(prefabObj: ISceneGameObject, objBuilder: ui.sceneobjects.GameObjectCodeDOMBuilder) {
for (const comp of prefabObj.getEditorSupport().getActiveComponents()) {
@@ -479,8 +499,11 @@ namespace phasereditor2d.scene.core.code {
}
const body = createMethodDecl.getBody();
+
const lazyStatements: CodeDOM[] = [];
+ this.buildCodeSnippets(body);
+
this.addCreateAllPlainObjectCode(body, lazyStatements);
for (const obj of this._scene.getGameObjects()) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/ISceneData.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/ISceneData.ts
index 9e8316326..ff393756c 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/core/json/ISceneData.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/ISceneData.ts
@@ -15,6 +15,7 @@ namespace phasereditor2d.scene.core.json {
plainObjects?: IScenePlainObjectData[];
displayList: IObjectData[];
prefabProperties?: any[];
+ codeSnippets?: ui.codesnippets.ICodeSnippetData[];
meta: {
app: string,
url: string,
diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts
index 14cd95380..6c4e87fc1 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts
@@ -81,6 +81,15 @@ namespace phasereditor2d.scene.core.json {
sceneData.prefabProperties = prefabProperties;
}
+ // code snippets
+
+ const codeSnippets = this._scene.getCodeSnippets();
+
+ if (codeSnippets.getSnippets().length > 0) {
+
+ sceneData.codeSnippets = codeSnippets.toJSON();
+ }
+
return sceneData;
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/CanvasManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/CanvasManager.ts
new file mode 100644
index 000000000..ec21fa5d2
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/CanvasManager.ts
@@ -0,0 +1,48 @@
+namespace phasereditor2d.scene.ui {
+
+ export class CanvasManager {
+
+ private _freeCanvases: HTMLCanvasElement[];
+ private _count: number;
+
+ constructor() {
+
+ this._freeCanvases = [];
+ this._count = 0;
+ }
+
+ takeCanvas() {
+
+ if (this._freeCanvases.length === 0) {
+
+ this._count++;
+
+ console.log("CanvasManager: create new canvas. Count new: " + this._count);
+
+ const canvas = document.createElement("canvas");
+
+ return canvas;
+
+ } else {
+
+ console.log("CanvasManager: reuse canvas. Total available: " + (this._freeCanvases.length - 1));
+
+ return this._freeCanvases.pop();
+ }
+ }
+
+ releaseCanvas(canvas: HTMLCanvasElement) {
+
+ if (this._freeCanvases.indexOf(canvas) < 0) {
+
+ console.log("CanvasManager: release canvas. Total available: " + (this._freeCanvases.length + 1));
+
+ this._freeCanvases.push(canvas);
+
+ } else {
+
+ console.log("CanvasManager: Hey, releasing a released canvas?");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts
index 46a65da88..6c085c498 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts
@@ -3,7 +3,7 @@ namespace phasereditor2d.scene.ui {
export class Scene extends BaseScene {
- static CURRENT_VERSION = 4;
+ static CURRENT_VERSION = 5;
private _id: string;
private _sceneType: core.json.SceneType;
@@ -12,6 +12,7 @@ namespace phasereditor2d.scene.ui {
private _prefabProperties: sceneobjects.PrefabUserProperties;
private _objectLists: sceneobjects.ObjectLists;
private _plainObjects: sceneobjects.IScenePlainObject[];
+ private _codeSnippets: codesnippets.CodeSnippets;
private _version: number;
constructor(editor?: editor.SceneEditor) {
@@ -27,6 +28,8 @@ namespace phasereditor2d.scene.ui {
this._plainObjects = [];
+ this._codeSnippets = new codesnippets.CodeSnippets();
+
this._prefabProperties = new sceneobjects.PrefabUserProperties();
this._version = Scene.CURRENT_VERSION;
@@ -146,6 +149,16 @@ namespace phasereditor2d.scene.ui {
this.children.addAt(obj, index, skipCallback);
}
+ getCodeSnippets() {
+
+ return this._codeSnippets;
+ }
+
+ addCodeSnippet(codeSnippet: codesnippets.CodeSnippet) {
+
+ this._codeSnippets.add(codeSnippet);
+ }
+
addPlainObject(obj: sceneobjects.IScenePlainObject) {
this._plainObjects.push(obj);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts
index 68e307866..59bbd3f2a 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts
@@ -377,6 +377,11 @@ namespace phasereditor2d.scene.ui {
this._editorScene.getPrefabUserProperties().readJSON(sceneData.prefabProperties);
}
+ if (sceneData.codeSnippets) {
+
+ this._editorScene.getCodeSnippets().readJSON(sceneData.codeSnippets);
+ }
+
this._editorScene.setSceneType(sceneData.sceneType || core.json.SceneType.SCENE);
// removes this condition, it is used temporal for compatibility
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts
index 754c0b188..14f31709c 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts
@@ -54,7 +54,7 @@ namespace phasereditor2d.scene.ui {
if (singleObject) {
- if (singleObject instanceof sceneobjects.Container) {
+ if (singleObject instanceof sceneobjects.Container || singleObject instanceof sceneobjects.Layer) {
const container = singleObject as sceneobjects.Container;
@@ -80,7 +80,10 @@ namespace phasereditor2d.scene.ui {
const cx = s.borderX + s.borderWidth / 2 + dx;
const cy = s.borderY + s.borderHeight / 2 + dy;
- sprite.setPosition(cx, cy);
+ if (sprite.setPosition) {
+
+ sprite.setPosition(cx, cy);
+ }
}
} else {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/ThumbnailCache.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/ThumbnailCache.ts
index 19679b710..c76006a4a 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/ThumbnailCache.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/ThumbnailCache.ts
@@ -11,7 +11,7 @@ namespace phasereditor2d.scene.ui {
async clearCache() {
- await this._database.clear();
+ await this._database?.clear();
}
constructor(dbName: string) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts
index aa7dabd62..f13f46206 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts
@@ -7,7 +7,6 @@ namespace phasereditor2d.scene.ui.blocks {
constructor() {
super("grid");
-
}
getCellRenderer(element: any) {
@@ -42,6 +41,10 @@ namespace phasereditor2d.scene.ui.blocks {
} else if (element instanceof viewers.PhaserTypeSymbol) {
return new controls.viewers.IconImageCellRenderer(colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER));
+
+ } else if (element instanceof pack.core.AnimationConfigInPackItem) {
+
+ return new pack.ui.viewers.AnimationConfigCellRenderer("square");
}
return super.getCellRenderer(element);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts
index 97e796c44..0f3b19a7c 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts
@@ -11,6 +11,8 @@ namespace phasereditor2d.scene.ui.blocks {
pack.core.MULTI_ATLAS_TYPE,
pack.core.UNITY_ATLAS_TYPE,
pack.core.SPRITESHEET_TYPE,
+ pack.core.ANIMATION_TYPE,
+ pack.core.ASEPRITE_TYPE,
pack.core.BITMAP_FONT_TYPE,
pack.core.SPINE_JSON_TYPE,
pack.core.SPINE_BINARY_TYPE,
@@ -156,6 +158,11 @@ namespace phasereditor2d.scene.ui.blocks {
return parent.getItems().filter(i => SCENE_EDITOR_BLOCKS_PACK_ITEM_TYPES.has(i.getType()));
}
+ if (parent instanceof pack.core.BaseAnimationsAssetPackItem) {
+
+ return parent.getAnimations();
+ }
+
if (typeof (parent) === "string") {
if (SCENE_OBJECT_CATEGORY_SET.has(parent)) {
@@ -188,6 +195,10 @@ namespace phasereditor2d.scene.ui.blocks {
return this.getPackItems()
.filter(item => item instanceof pack.core.BitmapFontAssetPackItem);
+ case pack.core.ANIMATION_TYPE:
+ return this.getPackItems()
+ .filter(item => item instanceof pack.core.BaseAnimationsAssetPackItem);
+
case BUILTIN_SECTION:
return SCENE_OBJECT_CATEGORIES;
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts
index 407e8d0a1..d74f7da5d 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts
@@ -128,6 +128,20 @@ namespace phasereditor2d.scene.ui.blocks {
}
}
+ } else if (obj instanceof pack.core.AnimationConfigInPackItem) {
+
+ const item = this.getFreshItem(obj.getParent()) as pack.core.BaseAnimationsAssetPackItem;
+
+ if (item) {
+
+ const found = item.getAnimations().find(a => a.getKey() === obj.getKey());
+
+ if (found) {
+
+ set.add(found);
+ }
+ }
+
} else {
set.add(obj);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts
index 3c9f49f01..dd981420f 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts
@@ -12,6 +12,7 @@ namespace phasereditor2d.scene.ui.blocks {
pack.core.SVG_TYPE,
pack.core.ATLAS_TYPE,
pack.core.SPRITESHEET_TYPE,
+ pack.core.ANIMATION_TYPE,
pack.core.BITMAP_FONT_TYPE,
pack.core.SPINE_JSON_TYPE,
pack.core.SPINE_BINARY_TYPE
@@ -69,6 +70,11 @@ namespace phasereditor2d.scene.ui.blocks {
return true;
}
+ if (obj instanceof pack.core.AnimationConfigInPackItem) {
+
+ return true;
+ }
+
return super.isShadowAsChild(obj);
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippet.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippet.ts
new file mode 100644
index 000000000..c79734dc9
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippet.ts
@@ -0,0 +1,44 @@
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ export interface ICodeSnippetData {
+ type: string;
+ id: string;
+ }
+
+ export abstract class CodeSnippet {
+
+ private _type: string;
+ private _id: string;
+
+ constructor(type: string) {
+
+ this._type = type;
+ this._id = Phaser.Utils.String.UUID();
+ }
+
+ getId() {
+
+ return this._id;
+ }
+
+ getType() {
+
+ return this._type;
+ }
+
+ abstract buildCodeDOM(): core.code.CodeDOM[];
+
+ abstract getDisplayName(): string;
+
+ writeJSON(data: ICodeSnippetData): void {
+
+ data.type = this._type;
+ data.id = this._id;
+ }
+
+ readJSON(data: ICodeSnippetData) {
+
+ this._id = data.id;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetExtension.ts
new file mode 100644
index 000000000..81751cf4e
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetExtension.ts
@@ -0,0 +1,34 @@
+
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ export abstract class CodeSnippetExtension extends colibri.Extension {
+
+ static POINT_ID = "phasereditor2d.scene.ui.codesnippets.CodeSnippetExtension";
+
+ private _name: string;
+ private _type: string;
+
+ constructor(type: string, name: string) {
+ super(CodeSnippetExtension.POINT_ID);
+
+ this._type = type;
+ this._name = name;
+ }
+
+ getType() {
+
+ return this._type;
+ }
+
+ getName() {
+
+ return this._name;
+ }
+
+ abstract isEnabledFor(_editor: editor.SceneEditor): boolean;
+
+ abstract createAndConfigureCodeSnippets(): Promise;
+
+ abstract createEmptyCodeSnippet(): CodeSnippet;
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetOrderOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetOrderOperation.ts
new file mode 100644
index 000000000..75af7fb3d
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetOrderOperation.ts
@@ -0,0 +1,127 @@
+///
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ import SceneEditor = editor.SceneEditor;
+ import DepthMove = editor.undo.DepthMove;
+
+ export class CodeSnippetOrderOperation extends CodeSnippetsSnapshotOperation {
+
+ private _depthMove: editor.undo.DepthMove;
+
+ constructor(editor: SceneEditor, depthMove: DepthMove) {
+ super(editor);
+
+ this._depthMove = depthMove;
+ }
+
+ static allow(editor: SceneEditor, move: DepthMove) {
+
+ // sort the selection and filter off non-game-objects
+ let sel = this.sortedSelection(editor);
+
+ // if the sorted selection contains all the selected objects
+ if (sel.length !== editor.getSelection().length) {
+
+ return false;
+ }
+
+ const siblings = editor.getScene().getCodeSnippets().getSnippets();
+
+ for (const obj of sel) {
+
+ const index = siblings.indexOf(obj);
+
+ let bottomIndex = 0;
+ const len = siblings.length;
+
+ if (move === "Bottom" || move === "Down") {
+
+ if (index === len - 1) {
+
+ return false;
+ }
+
+ } else { // Top || Up
+
+ if (index === bottomIndex) {
+
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected async performModification() {
+
+ const editor = this.getEditor();
+
+ const sel = CodeSnippetOrderOperation.sortedSelection(editor);
+
+ const siblings = editor.getScene().getCodeSnippets().getSnippets();
+
+ switch (this._depthMove) {
+
+ case "Bottom":
+
+ for (const obj of sel) {
+
+ Phaser.Utils.Array.BringToTop(siblings, obj);
+ }
+
+ break;
+
+ case "Top":
+
+ for (let i = 0; i < sel.length; i++) {
+
+ const obj = sel[sel.length - i - 1];
+
+ Phaser.Utils.Array.SendToBack(siblings, obj);
+ }
+
+ break;
+
+ case "Down":
+
+ for (let i = 0; i < sel.length; i++) {
+
+ const obj = sel[sel.length - i - 1];
+
+ Phaser.Utils.Array.MoveUp(siblings, obj);
+ }
+
+ break;
+
+ case "Up":
+
+ for (const obj of sel) {
+
+ Phaser.Utils.Array.MoveDown(siblings, obj);
+ }
+
+ break;
+ }
+
+ this.getEditor().repaint();
+ }
+
+ private static sortedSelection(editor: SceneEditor) {
+
+ const sel = editor.getSelectedCodeSnippets();
+
+ const siblings = editor.getScene().getCodeSnippets().getSnippets();
+
+ sel.sort((a, b) => {
+
+ const aa = siblings.indexOf(a);
+ const bb = siblings.indexOf(b);
+
+ return aa - bb;
+ });
+
+ return sel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippets.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippets.ts
new file mode 100644
index 000000000..ebc5c29cf
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippets.ts
@@ -0,0 +1,59 @@
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ export class CodeSnippets {
+
+ private _list: CodeSnippet[] = [];
+
+ add(snippet: CodeSnippet) {
+
+ this._list.push(snippet);
+ }
+
+ removeByIds(ids: string[]) {
+
+ const removeSet = new Set(ids);
+
+ this._list = this._list.filter(s => !removeSet.has(s.getId()));
+ }
+
+ getSnippets() {
+
+ return this._list;
+ }
+
+ readJSON(codeSnippets: ICodeSnippetData[]) {
+
+ this._list = [];
+
+ for (const snippetData of codeSnippets) {
+
+ const ext = ScenePlugin.getInstance().getCodeSnippetExtensionByType(snippetData.type);
+
+ if (ext) {
+
+ const snippet = ext.createEmptyCodeSnippet();
+
+ snippet.readJSON(snippetData);
+
+ this.add(snippet);
+ }
+ }
+ }
+
+ toJSON(): ICodeSnippetData[] {
+
+ const result: ICodeSnippetData[] = [];
+
+ for (const snippet of this._list) {
+
+ const data: ICodeSnippetData = {} as any;
+
+ snippet.writeJSON(data);
+
+ result.push(data);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetsSnapshotOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetsSnapshotOperation.ts
new file mode 100644
index 000000000..445d90472
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/CodeSnippetsSnapshotOperation.ts
@@ -0,0 +1,79 @@
+///
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ import json = core.json;
+
+ export interface ICodeSnippetSnapshot {
+
+ selection: string[];
+ codeSnippets: ICodeSnippetData[];
+ }
+
+ export class CodeSnippetsSnapshotOperation extends editor.undo.SceneEditorOperation {
+
+ private _before: ICodeSnippetSnapshot;
+ private _after: ICodeSnippetSnapshot;
+ private _operation: () => Promise;
+
+ constructor(editor: editor.SceneEditor, operation?: () => Promise) {
+ super(editor);
+
+ this._operation = operation;
+ }
+
+ async execute() {
+
+ this._before = this.takeSnapshot();
+
+ await this.performModification();
+
+ this._after = this.takeSnapshot();
+
+ this._editor.setDirty(true);
+ this._editor.refreshOutline();
+ this._editor.repaint();
+ this._editor.dispatchSelectionChanged();
+ }
+
+ protected async performModification(): Promise {
+
+ if (this._operation) {
+
+ await this._operation();
+ }
+ }
+
+ private takeSnapshot(): ICodeSnippetSnapshot {
+
+ const scene = this.getScene();
+
+ return {
+ selection: this.getEditor().getSelectedCodeSnippets().map(s => s.getId()),
+ codeSnippets: scene.getCodeSnippets().toJSON()
+ };
+ }
+
+ protected loadSnapshot(snapshot: ICodeSnippetSnapshot) {
+
+ const editor = this.getEditor();
+ const scene = this.getScene();
+
+ scene.getCodeSnippets().readJSON(snapshot.codeSnippets);
+
+ editor.setDirty(true);
+ editor.repaint();
+ editor.refreshOutline();
+ editor.getSelectionManager().setSelectionByIds(snapshot.selection);
+ }
+
+ undo(): void {
+
+ this.loadSnapshot(this._before);
+ }
+
+ redo(): void {
+
+ this.loadSnapshot(this._after);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippet.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippet.ts
new file mode 100644
index 000000000..a4a4019e1
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippet.ts
@@ -0,0 +1,43 @@
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ export interface ICreateFromAsepriteCodeSnippetData extends ICodeSnippetData {
+ key: string;
+ }
+
+ export class CreateFromAsepriteCodeSnippet extends CodeSnippet {
+
+ public assetKey: string;
+
+ constructor() {
+ super(CreateFromAsepriteCodeSnippetExtension.TYPE);
+ }
+
+ buildCodeDOM(): core.code.CodeDOM[] {
+
+ const dom = new core.code.MethodCallCodeDOM("createFromAseprite", "this.anims");
+
+ dom.argLiteral(this.assetKey);
+
+ return [dom];
+ }
+
+ getDisplayName(): string {
+
+ return `${this.assetKey} - anims.createFromAseprite`;
+ }
+
+ writeJSON(data: ICreateFromAsepriteCodeSnippetData): void {
+
+ super.writeJSON(data);
+
+ data.key = this.assetKey;
+ }
+
+ readJSON(data: ICreateFromAsepriteCodeSnippetData): void {
+
+ super.readJSON(data);
+
+ this.assetKey = data.key;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetExtension.ts
new file mode 100644
index 000000000..69ada74f2
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetExtension.ts
@@ -0,0 +1,51 @@
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ export class CreateFromAsepriteCodeSnippetExtension extends CodeSnippetExtension {
+
+ static TYPE = "animsCreateFromAseprite";
+
+ constructor() {
+ super(CreateFromAsepriteCodeSnippetExtension.TYPE, "Create Animations From Aseprite");
+ }
+
+ isEnabledFor(_editor: editor.SceneEditor): boolean {
+
+ return !_editor.getScene().isPrefabSceneType();
+ }
+
+ createEmptyCodeSnippet(): CodeSnippet {
+
+ return new CreateFromAsepriteCodeSnippet();
+ }
+
+ async createAndConfigureCodeSnippets(): Promise {
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const input = finder.getAssets()
+ .filter(i => i instanceof pack.core.AsepriteAssetPackItem);
+
+ const dlg = new pack.ui.dialogs.AssetSelectionDialog("tree", false);
+
+ dlg.create();
+
+ dlg.setTitle("Select Aseprite File Key");
+
+ dlg.getViewer().setInput(input);
+
+ const result = await dlg.getResultPromise() as pack.core.AnimationConfigInPackItem[];
+
+ const snippets = (result || []).map(a => {
+
+ const snippet = new CreateFromAsepriteCodeSnippet();
+ snippet.assetKey = a.getKey();
+
+ return snippet;
+ });
+
+ return snippets;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetSection.ts
new file mode 100644
index 000000000..4bc439531
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/codesnippets/aseprite/CreateFromAsepriteCodeSnippetSection.ts
@@ -0,0 +1,81 @@
+///
+namespace phasereditor2d.scene.ui.codesnippets {
+
+ import controls = colibri.ui.controls;
+
+ export class CreateFromAsepriteCodeSnippetSection extends ui.editor.properties.BaseSceneSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.scene.ui.codesnippets.CreateFromAsepriteCodeSnippetSection", "Create From Aseprite")
+ }
+
+ createForm(parent: HTMLDivElement): void {
+
+ const comp = this.createGridElement(parent, 3);
+ comp.style.gridTemplateColumns = "auto 1fr auto";
+
+ this.createLabel(comp, "Aseprite File Key", "The Aseprite animations file key.");
+
+ {
+ const text = this.createText(comp, false);
+
+ this.addUpdater(() => {
+
+ text.value = this.getSelectionFirstElement().assetKey;
+ });
+ }
+
+ const btnUI = this.createButtonDialog({
+ dialogTittle: "Select Animation File Key",
+ createDialogViewer: async (revealValue: string) => {
+
+ const viewer = new controls.viewers.TreeViewer("phasereditor2d.scene.ui.sceneobjects.CreateFromAsepriteCodeSnippetSection." + this.getId());
+
+ viewer.setCellRendererProvider(new controls.viewers.EmptyCellRendererProvider(e => new pack.ui.viewers.AnimationsItemCellRenderer()));
+ viewer.setLabelProvider(new pack.ui.viewers.AssetPackLabelProvider());
+ viewer.setTreeRenderer(new controls.viewers.TreeViewerRenderer(viewer));
+ viewer.setContentProvider(new controls.viewers.ArrayTreeContentProvider());
+
+ const finder = new pack.core.PackFinder();
+ await finder.preload();
+
+ const assetItems = finder
+ .getAssets(i => i instanceof pack.core.AsepriteAssetPackItem);
+
+ viewer.setInput(assetItems);
+
+ viewer.revealAndSelect(assetItems.find(a => a.getKey() === revealValue));
+
+ return viewer;
+ },
+ getValue: () => {
+
+ return this.getSelectionFirstElement().assetKey || "";
+ },
+ onValueSelected: (value: string) => {
+
+ this.getEditor().getUndoManager().add(new CodeSnippetsSnapshotOperation(this.getEditor(), async () => {
+
+ this.getSelectionFirstElement().assetKey = value;
+ }));
+ },
+ dialogElementToString: (viewer: controls.viewers.TreeViewer, value: pack.core.AsepriteAssetPackItem): string => {
+
+ return value.getKey();
+ }
+ });
+
+ comp.appendChild(btnUI.buttonElement);
+ }
+
+ canEdit(obj: any, n: number): boolean {
+
+ return obj instanceof codesnippets.CreateFromAsepriteCodeSnippet;
+ }
+
+ canEditNumber(n: number): boolean {
+
+ return n === 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts
index 45ade5977..9e1a76629 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts
@@ -293,11 +293,12 @@ namespace phasereditor2d.scene.ui.editor {
const b = camera.getScreenPoint(borderX + borderWidth, borderY + borderHeight);
ctx.save();
ctx.strokeStyle = theme.dark ? "#0a0a0a" : "#404040";
- ctx.strokeRect(a.x + 2, a.y + 2, b.x - a.x, b.y - a.y);
+ ctx.strokeRect(a.x - 2, a.y - 2, b.x - a.x + 4, b.y - a.y + 4);
ctx.restore();
ctx.lineWidth = 1;
- ctx.strokeRect(a.x, a.y, b.x - a.x, b.y - a.y);
+ ctx.strokeStyle = theme.dark ? "#a0a0a0" : "#f0f0f0";
+ ctx.strokeRect(a.x - 1, a.y - 1, b.x - a.x + 2, b.y - a.y + 2);
ctx.restore();
}
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts
index 7337633fc..d50012887 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts
@@ -275,13 +275,8 @@ namespace phasereditor2d.scene.ui.editor {
this.getElement().appendChild(container);
- const pool = Phaser.Display.Canvas.CanvasPool;
-
- this._gameCanvas = ScenePlugin.DEFAULT_EDITOR_CANVAS_CONTEXT === Phaser.CANVAS
-
- ? pool.create2D(this.getElement(), 100, 100)
-
- : pool.createWebGL(this.getElement(), 100, 100);
+ this._gameCanvas = ScenePlugin.getInstance().getCanvasManager().takeCanvas();
+ this._gameCanvas.style.visibility = "hidden";
this._gameCanvas.classList.add("GameCanvas");
@@ -595,6 +590,12 @@ namespace phasereditor2d.scene.ui.editor {
return this.getSelection().filter(obj => sceneobjects.ScenePlainObjectEditorSupport.hasEditorSupport(obj));
}
+ getSelectedCodeSnippets(): codesnippets.CodeSnippet[] {
+
+ return this.getSelection()
+ .filter(obj => obj instanceof codesnippets.CodeSnippet);
+ }
+
getSelectedUserComponentNodes(): sceneobjects.UserComponentNode[] {
return this.getSelection().filter(obj => obj instanceof sceneobjects.UserComponentNode);
@@ -640,11 +641,6 @@ namespace phasereditor2d.scene.ui.editor {
return this._overlayLayer;
}
- getGameCanvas() {
-
- return this._gameCanvas;
- }
-
getScene() {
return this._scene;
@@ -724,6 +720,8 @@ namespace phasereditor2d.scene.ui.editor {
if (this._scene) {
this._scene.destroyGame();
+
+ ScenePlugin.getInstance().getCanvasManager().releaseCanvas(this._game.canvas);
}
this._cellRendererCache.clear();
@@ -866,10 +864,12 @@ namespace phasereditor2d.scene.ui.editor {
}
getOutlineProvider() {
+
return this._outlineProvider;
}
refreshOutline() {
+
this._outlineProvider.repaint();
}
@@ -877,6 +877,8 @@ namespace phasereditor2d.scene.ui.editor {
this._gameBooted = true;
+ this._gameCanvas.style.visibility = "visible";
+
if (!this._sceneRead) {
await this.readScene();
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts
index ff4167fe9..192d007f3 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts
@@ -23,6 +23,8 @@ namespace phasereditor2d.scene.ui.editor {
menu.addMenu(this.createAddObjectMenu())
+ menu.addMenu(this.createAddCodeSnippetMenu())
+
menu.addSeparator();
menu.addMenu(this.createPrefabMenu());
@@ -52,7 +54,40 @@ namespace phasereditor2d.scene.ui.editor {
menu.addMenu(this.createCompilerMenu());
}
- createScriptingMenu(): controls.Menu {
+ private createAddCodeSnippetMenu(): controls.Menu {
+
+ const menu = new controls.Menu("Code Snippets");
+
+ for (const ext of ScenePlugin.getInstance().getCodeSnippetExtensions()) {
+
+ menu.addAction({
+ text: "Add " + ext.getName(),
+ icon: resources.getIcon(resources.ICON_BUILD),
+ enabled: ext.isEnabledFor(this._editor),
+ callback: async () => {
+
+ const snippets = await ext.createAndConfigureCodeSnippets();
+
+ if (snippets) {
+
+ this._editor.getUndoManager().add(new codesnippets.CodeSnippetsSnapshotOperation(this._editor, async () => {
+
+ for (const snippet of snippets) {
+
+ this._editor.getScene().addCodeSnippet(snippet);
+ }
+
+ this._editor.setSelection(snippets);
+ }));
+ }
+ }
+ });
+ }
+
+ return menu;
+ }
+
+ private createScriptingMenu(): controls.Menu {
const menu = new controls.Menu("Scripting");
@@ -68,7 +103,7 @@ namespace phasereditor2d.scene.ui.editor {
}
createArcadePhysicsMenu(): controls.Menu {
-
+
const menu = new controls.Menu("Arcade Physics");
menu.addCommand(editor.commands.CMD_ARCADE_ENABLE_BODY, {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts
index af2280d1a..b6838e4da 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts
@@ -18,12 +18,16 @@ namespace phasereditor2d.scene.ui.editor {
const selection = this._editor.getSelection();
const selectedObjects = this._editor.getSelectedGameObjects();
const selectedPlainObjects = this._editor.getSelectedPlainObjects();
+ const selectedCodeSnippets = this._editor.getSelectedCodeSnippets();
list.push(...selectedObjects
.map(obj => obj.getEditorSupport().getId()));
list.push(...selectedPlainObjects
- .map(obj => obj.getEditorSupport().getId()))
+ .map(obj => obj.getEditorSupport().getId()));
+
+ list.push(...selectedCodeSnippets
+ .map((s: codesnippets.CodeSnippet) => s.getId()));
list.push(...selection
.filter(obj => obj instanceof sceneobjects.ObjectList)
@@ -31,7 +35,7 @@ namespace phasereditor2d.scene.ui.editor {
list.push(...selection
.filter(obj => obj instanceof sceneobjects.ObjectListItem)
- .map(obj => (obj as sceneobjects.ObjectListItem).getId()))
+ .map(obj => (obj as sceneobjects.ObjectListItem).getId()));
list.push(...selection
.filter(i => i instanceof sceneobjects.UserComponentNode)
@@ -39,7 +43,7 @@ namespace phasereditor2d.scene.ui.editor {
list.push(...selection
.filter(obj => obj instanceof sceneobjects.UserProperty)
- .map((p: sceneobjects.UserProperty) => `prefabProperty#${p.getName()}`))
+ .map((p: sceneobjects.UserProperty) => `prefabProperty#${p.getName()}`));
return list;
}
@@ -70,17 +74,22 @@ namespace phasereditor2d.scene.ui.editor {
map.set(list.getId(), list);
- for(const item of list.getItems()) {
+ for (const item of list.getItems()) {
map.set(item.getId(), item);
}
}
- for(const prop of scene.getPrefabUserProperties().getProperties()) {
+ for (const prop of scene.getPrefabUserProperties().getProperties()) {
map.set(`prefabProperty#${prop.getName()}`, prop);
}
+ for (const snippet of scene.getCodeSnippets().getSnippets()) {
+
+ map.set(snippet.getId(), snippet);
+ }
+
const sel = selectionIds
.map(id => map.get(id))
.filter(obj => obj !== undefined);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts
index c519f7791..255af7b4e 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts
@@ -196,6 +196,33 @@ namespace phasereditor2d.scene.ui.editor.commands {
this.registerPropertiesCommands(manager);
this.registerSpineCommands(manager);
+
+ this.registerCodeSnippetOrderCommands(manager);
+ }
+
+ static registerCodeSnippetOrderCommands(manager: colibri.ui.ide.commands.CommandManager) {
+
+ const moves: [undo.DepthMove, string][] = [
+ ["Up", CMD_SORT_OBJ_UP],
+ ["Down", CMD_SORT_OBJ_DOWN],
+ ["Top", CMD_SORT_OBJ_TOP],
+ ["Bottom", CMD_SORT_OBJ_BOTTOM]
+ ];
+
+ for (const tuple of moves) {
+
+ const move = tuple[0];
+ const cmd = tuple[1];
+
+ manager.addHandlerHelper(cmd,
+ // testFunc
+ args => isSceneScope(args) && args.activeEditor.getSelection().length > 0
+ && codesnippets.CodeSnippetOrderOperation.allow(args.activeEditor as any, move),
+ // execFunc
+ args => args.activeEditor.getUndoManager().add(
+ new codesnippets.CodeSnippetOrderOperation(args.activeEditor as editor.SceneEditor, move)
+ ));
+ }
}
static registerPlainObjectOrderCommands(manager: colibri.ui.ide.commands.CommandManager) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts
index a00a8a16b..50f59ebf9 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts
@@ -44,6 +44,12 @@ namespace phasereditor2d.scene.ui.editor.outline {
}));
}
+ if (!scene.isPrefabSceneType()
+ && scene.getCodeSnippets().getSnippets().length > 0) {
+
+ roots.push(scene.getCodeSnippets());
+ }
+
if (scene.isPrefabSceneType()) {
roots.push(scene.getPrefabUserProperties());
@@ -54,6 +60,11 @@ namespace phasereditor2d.scene.ui.editor.outline {
getChildren(parent: any): any[] {
+ if (parent instanceof codesnippets.CodeSnippets) {
+
+ return parent.getSnippets();
+ }
+
if (parent instanceof sceneobjects.PrefabUserProperties) {
return parent.getProperties();
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineRendererProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineRendererProvider.ts
index 8577a69c8..7a284c860 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineRendererProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineRendererProvider.ts
@@ -35,6 +35,14 @@ namespace phasereditor2d.scene.ui.editor.outline {
} else if (element instanceof sceneobjects.UserProperty) {
return new controls.viewers.IconImageCellRenderer(resources.getIcon(resources.ICON_USER_PROPERTY));
+
+ } else if (element instanceof codesnippets.CodeSnippets) {
+
+ return new controls.viewers.IconImageCellRenderer(colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER));
+
+ } else if (element instanceof codesnippets.CodeSnippet) {
+
+ return new controls.viewers.IconImageCellRenderer(resources.getIcon(resources.ICON_BUILD));
}
const extensions = ScenePlugin.getInstance().getSceneEditorOutlineExtensions();
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts
index 6a4d4c346..b07872de4 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts
@@ -52,6 +52,14 @@ namespace phasereditor2d.scene.ui.editor.outline {
} else if (obj instanceof sceneobjects.UserProperty) {
return obj.getLabel();
+
+ } else if (obj instanceof codesnippets.CodeSnippets) {
+
+ return "Code Snippets";
+
+ } else if (obj instanceof codesnippets.CodeSnippet) {
+
+ return obj.getDisplayName();
}
const extensions = ScenePlugin.getInstance().getSceneEditorOutlineExtensions();
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DeleteOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DeleteOperation.ts
index 8103fc6c0..a6c03739e 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DeleteOperation.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DeleteOperation.ts
@@ -45,6 +45,10 @@ namespace phasereditor2d.scene.ui.editor.undo {
scene.removePlainObjects(editor.getSelectedPlainObjects());
+ const codeSnippetIds = editor.getSelectedCodeSnippets().map(s => s.getId());
+
+ editor.getScene().getCodeSnippets().removeByIds(codeSnippetIds);
+
const nodes = editor.getSelectedUserComponentNodes();
for (const node of nodes) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts
index 724a3db36..11192633f 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts
@@ -9,6 +9,7 @@ namespace phasereditor2d.scene.ui.editor.undo {
lists: json.IObjectListData[];
plainObjects: json.IScenePlainObjectData[],
prefabUserProperties: any[];
+ codeSnippets: codesnippets.ICodeSnippetData[];
}
export class SceneSnapshotOperation extends SceneEditorOperation {
@@ -81,7 +82,9 @@ namespace phasereditor2d.scene.ui.editor.undo {
prefabUserProperties: scene.getPrefabUserProperties().toJSON(),
- selection: this.getEditor().getSelectionManager().getSelectionIds()
+ codeSnippets: scene.getCodeSnippets().toJSON(),
+
+ selection: this.getEditor().getSelectionManager().getSelectionIds(),
};
}
@@ -102,6 +105,8 @@ namespace phasereditor2d.scene.ui.editor.undo {
scene.getObjectLists().readJSON_lists(snapshot.lists);
+ scene.getCodeSnippets().readJSON(snapshot.codeSnippets);
+
scene.getPrefabUserProperties().readJSON(snapshot.prefabUserProperties);
editor.setDirty(true);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ImageLoaderExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ImageLoaderExtension.ts
index b74ce90e4..f7e717e54 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ImageLoaderExtension.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ImageLoaderExtension.ts
@@ -29,29 +29,45 @@ namespace phasereditor2d.scene.ui.sceneobjects {
acceptAsset(asset: any): boolean {
return asset instanceof pack.core.ImageFrameContainerAssetPackItem
- || asset instanceof pack.core.AssetPackImageFrame;
+ || asset instanceof pack.core.AsepriteAssetPackItem
+ || asset instanceof pack.core.AssetPackImageFrame
+ || asset instanceof pack.core.AnimationConfigInPackItem;
}
async updateLoader(scene: BaseScene, asset: any) {
- let imageFrameContainerPackItem: pack.core.ImageFrameContainerAssetPackItem = null;
+ if (asset instanceof pack.core.AnimationConfigInPackItem) {
- if (asset instanceof pack.core.ImageFrameContainerAssetPackItem) {
+ for(const animFrame of asset.getFrames()) {
- imageFrameContainerPackItem = asset;
+ const textureFrame = animFrame.getTextureFrame();
+
+ if (textureFrame) {
+
+ await this.updateLoader(scene, textureFrame);
+ }
+ }
+ }
+
+ let framesContainer: pack.core.ImageFrameContainerAssetPackItem | pack.core.AsepriteAssetPackItem = null;
+
+ if (asset instanceof pack.core.ImageFrameContainerAssetPackItem
+ || asset instanceof pack.core.AsepriteAssetPackItem) {
+
+ framesContainer = asset;
} else if (asset instanceof pack.core.AssetPackImageFrame) {
- imageFrameContainerPackItem = (asset.getPackItem() as pack.core.ImageFrameContainerAssetPackItem);
+ framesContainer = (asset.getPackItem() as pack.core.ImageFrameContainerAssetPackItem);
}
- if (imageFrameContainerPackItem !== null) {
+ if (framesContainer !== null) {
- await imageFrameContainerPackItem.preload();
+ await framesContainer.preload();
- await imageFrameContainerPackItem.preloadImages();
+ await framesContainer.preloadImages();
- imageFrameContainerPackItem.addToPhaserCache(scene.game, scene.getPackCache());
+ framesContainer.addToPhaserCache(scene.game, scene.getPackCache());
}
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts
index 05bdbcede..f44282ec9 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts
@@ -99,7 +99,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
this.createLock(parent, prop);
this.createLabel(parent, prop.label, PhaserHelp(prop.tooltip))
- .style.gridColumn = "2/ span 2";
+ .style.gridColumn = "2 / span 2";
this.createFloatField(parent, prop)
.style.gridColumn = fullWidth ? "4 / span 3" : "4";
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts
index ef11fe665..a225ffad4 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts
@@ -105,7 +105,6 @@ namespace phasereditor2d.scene.ui.sceneobjects {
text.readOnly = forceReadOnly || checkUnlock && !this.isUnlocked(property);
-
if (readOnlyOnMultiple) {
text.readOnly = text.readOnly || readOnlyOnMultiple && this.getSelection().length > 1;
@@ -389,8 +388,6 @@ namespace phasereditor2d.scene.ui.sceneobjects {
this.addUpdater(() => {
- console.log("update button man!");
-
result.updateDialogButtonIcon();
});
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/spine/SpinePreviewManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/spine/SpinePreviewManager.ts
index 6911f224d..3619a0b3e 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/spine/SpinePreviewManager.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/spine/SpinePreviewManager.ts
@@ -14,6 +14,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
if (this._game) {
+ ScenePlugin.getInstance().getCanvasManager().releaseCanvas(this._game.canvas);
+
this._game.destroy(true);
}
}
@@ -52,8 +54,14 @@ namespace phasereditor2d.scene.ui.sceneobjects {
const { width, height } = this._parent.getBoundingClientRect();
+ const canvas = ScenePlugin.getInstance().getCanvasManager().takeCanvas();
+
+ canvas.style.visibility = "hidden";
+
this._game = new Phaser.Game({
+ type: ScenePlugin.DEFAULT_EDITOR_CANVAS_CONTEXT,
width, height,
+ canvas,
parent: this._parent,
transparent: true,
fps: {
@@ -75,7 +83,13 @@ namespace phasereditor2d.scene.ui.sceneobjects {
this._game.scene.add("PreviewScene", PreviewScene, true, data);
this._game.scene.add("EventScene", EventScene);
- setTimeout(() => this._game.scale.refresh(), 10);
+ setTimeout(() => {
+
+ canvas.style.visibility = "visible";
+
+ this._game.scale.refresh();
+
+ }, 10);
}
}
@@ -90,6 +104,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
class PreviewScene extends Phaser.Scene {
private _data: IPreviewSceneData;
+ private _wheelListener: (e: WheelEvent) => void;
init(data: IPreviewSceneData) {
@@ -174,7 +189,9 @@ namespace phasereditor2d.scene.ui.sceneobjects {
obj.animationState.addListener(eventScene);
- this.input.on("wheel", (pointer: any, over: any, deltaX: number, deltaY: number, deltaZ: number) => {
+ this._wheelListener = (e: WheelEvent) => {
+
+ const deltaY = e.deltaY;
const scrollWidth = Math.abs(deltaY) * 2;
@@ -185,8 +202,10 @@ namespace phasereditor2d.scene.ui.sceneobjects {
const zoomFactor = (deltaY > 0 ? 1 - zoomDelta : 1 + zoomDelta);
camera.zoom *= zoomFactor;
- camera.zoom = Math.min(4, Math.max(0.2, camera.zoom));
- });
+ camera.zoom = Math.min(100, Math.max(0.2, camera.zoom));
+ };
+
+ this.game.canvas.addEventListener("wheel", this._wheelListener);
this.game.events.on("updateAnimation", (track: number, animationName: string, loop: boolean) => {
@@ -227,6 +246,13 @@ namespace phasereditor2d.scene.ui.sceneobjects {
obj.animationStateData.setMix(from, to, duration);
}
});
+
+ this.game.events.once(Phaser.Core.Events.DESTROY, () => this.removeListeners());
+ }
+
+ private removeListeners() {
+
+ this.game.canvas.removeEventListener("wheel", this._wheelListener);
}
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewDialog.ts
new file mode 100644
index 000000000..ffc675c41
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewDialog.ts
@@ -0,0 +1,75 @@
+namespace phasereditor2d.scene.ui.sceneobjects {
+
+ import controls = colibri.ui.controls;
+
+ export class AnimationPreviewDialog extends controls.dialogs.Dialog {
+ private _previewManager: AnimationPreviewManager;
+ private _animationAsset: pack.core.BaseAnimationsAssetPackItem;
+ private _config: Phaser.Types.Animations.PlayAnimationConfig;
+
+ constructor(animationAsset: pack.core.BaseAnimationsAssetPackItem, config: Phaser.Types.Animations.PlayAnimationConfig) {
+ super();
+
+ const size = Math.min(window.innerWidth * 0.5, window.innerHeight * 0.5);
+
+ this.setSize(size, size);
+
+ this._animationAsset = animationAsset;
+ this._config = config;
+ }
+
+ protected createDialogArea(): void {
+
+ const clientArea = document.createElement("div")
+
+ clientArea.classList.add("DialogClientArea");
+
+ this.getElement().appendChild(clientArea);
+
+ this._previewManager = new AnimationPreviewManager(clientArea);
+ }
+
+ createUI() {
+
+ const finder = new pack.core.PackFinder();
+
+ finder.preload().then(() => {
+
+ setTimeout(() => {
+
+ this._previewManager.createGame({
+ animationAsset: this._animationAsset,
+ config: this._config,
+ finder
+ });
+ }, 10);
+ });
+ }
+
+ create(hideParentDialog?: boolean): void {
+
+ super.create(hideParentDialog);
+
+ this.createUI();
+
+ this.setTitle("Animation Preview");
+
+ this.addButton("Close", () => this.close());
+
+ this.addButton("Play", () => {
+
+ this._previewManager.play(false);
+ });
+
+ this.addButton("Play Repeat", () => {
+
+ this._previewManager.play(true);
+ });
+
+ this.eventDialogClose.addListener(() => {
+
+ this._previewManager.dispose();
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewManager.ts
new file mode 100644
index 000000000..ffee35296
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/AnimationPreviewManager.ts
@@ -0,0 +1,180 @@
+namespace phasereditor2d.scene.ui.sceneobjects {
+
+ export class AnimationPreviewManager {
+
+ private _parent: HTMLElement;
+ private _game: Phaser.Game;
+
+ constructor(parent: HTMLElement) {
+
+ this._parent = parent;
+ }
+
+ dispose() {
+
+ if (this._game) {
+
+ ScenePlugin.getInstance().getCanvasManager().releaseCanvas(this._game.canvas);
+
+ this._game.destroy(false);
+ }
+ }
+
+ play(forceRepeat: boolean) {
+
+ this._game.events.emit("play", forceRepeat);
+ }
+
+ createGame(data: IAnimationPreviewSceneData) {
+
+ const { width, height } = this._parent.getBoundingClientRect();
+
+ const canvas = ScenePlugin.getInstance().getCanvasManager().takeCanvas();
+
+ this._game = new Phaser.Game({
+ width, height: height - 5,
+ parent: this._parent,
+ canvas,
+ type: ScenePlugin.DEFAULT_EDITOR_CANVAS_CONTEXT,
+ transparent: true,
+ pixelArt: true,
+ fps: {
+ target: 30,
+ },
+ scale: {
+ mode: Phaser.Scale.ScaleModes.NONE,
+ resizeInterval: 10
+ }
+ });
+
+ canvas.style.visibility = "hidden";
+
+ this._game.scene.add("PreviewScene", PreviewScene, true, data);
+
+ setTimeout(() => {
+
+ canvas.style.visibility = "visible";
+
+ this._game.scale.refresh();
+
+ }, 10);
+ }
+ }
+
+ export interface IAnimationPreviewSceneData {
+ animationAsset: pack.core.BaseAnimationsAssetPackItem;
+ config: Phaser.Types.Animations.PlayAnimationConfig,
+ finder: pack.core.PackFinder
+ }
+
+ class PreviewScene extends Phaser.Scene {
+
+ private _data: IAnimationPreviewSceneData;
+ private _wheelListener: (e: WheelEvent) => void;
+
+ init(data: IAnimationPreviewSceneData) {
+
+ this._data = data;
+ }
+
+ preload() {
+
+ const asset = this._data.animationAsset;
+
+ if (asset instanceof pack.core.AnimationsAssetPackItem) {
+
+ const cache = new pack.core.parsers.AssetPackCache();
+
+ for (const item of this._data.finder.getAssets()) {
+
+ item.addToPhaserCache(this.game, cache);
+ }
+
+ this.load.animation(asset.getKey(), asset.getAnimationsFile().getExternalUrl());
+
+ } else {
+
+ const asset2 = asset as pack.core.AsepriteAssetPackItem;
+
+ const textureURL = asset2.getTextureFile().getExternalUrl();
+ const atlasURL = asset2.getAnimationsFile().getExternalUrl();
+
+ this.load.aseprite(asset2.getKey(), textureURL, atlasURL);
+ }
+ }
+
+ create() {
+
+ this.anims.createFromAseprite(this._data.animationAsset.getKey());
+
+ const obj = this.add.sprite(400, 400, null);
+
+ obj.play(this._data.config);
+
+ obj.on("drag", (pointer: any, dragX: number, dragY: number) => {
+
+ obj.setPosition(dragX, dragY);
+ });
+
+ const w = 100000;
+
+ obj.setInteractive({
+ draggable: true,
+ hitArea: new Phaser.Geom.Rectangle(-w, -w, w * 2, w * 2),
+ hitAreaCallback: Phaser.Geom.Rectangle.Contains
+ });
+
+ const camera = this.cameras.main;
+
+ const gameWidth = camera.width;
+ const gameHeight = camera.height;
+
+ const fx = gameWidth / obj.width;
+ const fy = gameHeight / obj.height;
+
+ const z = Math.min(fx, fy);
+
+ obj.setOrigin(0.5, 0.5);
+ obj.setPosition(this.game.scale.width / 2, this.game.scale.height / 2);
+
+ camera.zoom = z;
+
+ this._wheelListener = (e: WheelEvent) => {
+
+ const deltaY = e.deltaY;
+
+ const scrollWidth = Math.abs(deltaY) * 2;
+
+ const screenWidth = camera.width;
+
+ const zoomDelta = scrollWidth / (screenWidth + scrollWidth);
+
+ const zoomFactor = (deltaY > 0 ? 1 - zoomDelta : 1 + zoomDelta);
+
+ camera.zoom *= zoomFactor;
+ camera.zoom = Math.min(100, Math.max(0.2, camera.zoom));
+ };
+
+ this.game.canvas.addEventListener("wheel", this._wheelListener);
+
+ this.game.events.on("play", (forceRepeat: boolean) => {
+
+ if (forceRepeat) {
+
+ obj.play({ ...this._data.config, repeat: -1 });
+
+ } else {
+
+ obj.play(this._data.config);
+ }
+ });
+
+ this.game.events.once(Phaser.Core.Events.DESTROY, () => this.removeListeners());
+ }
+
+ private removeListeners() {
+
+ this.game.canvas.removeEventListener("wheel", this._wheelListener);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/Sprite.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/Sprite.ts
index 10a504f77..5156df3c8 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/Sprite.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/Sprite.ts
@@ -1,9 +1,29 @@
namespace phasereditor2d.scene.ui.sceneobjects {
+ export enum AnimationPlayMethod {
+ NONE = 0,
+ PLAY = 1,
+ PLAY_REVERSE = 2
+ }
+
export class Sprite extends Phaser.GameObjects.Image implements ISceneGameObject {
private _editorSupport: SpriteEditorSupport;
+ public animationPlayMethod: AnimationPlayMethod = AnimationPlayMethod.NONE;
+ public animationKey = "";
+ public animationCustomConfig = false;
+ public animationFrameRate = 24;
+ public animationDelay = 0;
+ public animationRepeat = 0;
+ public animationRepeatDelay = 0;
+ public animationYoyo = false;
+ public animationShowBeforeDelay = false;
+ public animationShowOnStart = false;
+ public animationHideOnComplete = false;
+ public animationStartFrame = 0;
+ public animationTimeScale = 1;
+
constructor(
scene: Scene, x: number, y: number, texture: string, frame?: string | number) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationConfigSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationConfigSection.ts
new file mode 100644
index 000000000..0a62d7e90
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationConfigSection.ts
@@ -0,0 +1,55 @@
+namespace phasereditor2d.scene.ui.sceneobjects {
+
+ import controls = colibri.ui.controls;
+
+ export class SpriteAnimationConfigSection extends SceneGameObjectSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.scene.ui.sceneobjects.SpriteAnimationConfigSection", "Animation Configuration");
+ }
+
+ protected getSectionHelpPath() {
+
+ return "scene-editor/animations-properties.html";
+ }
+
+ createForm(parent: HTMLDivElement) {
+
+ const comp = this.createGridElement(parent, 3);
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationFrameRate);
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationDelay);
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationRepeat);
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationRepeatDelay);
+
+ this.createPropertyBoolean(comp, SpriteComponent.animationYoyo)
+ .labelElement.style.gridColumn = "2 / span 2";
+
+ this.createPropertyBoolean(comp, SpriteComponent.animationShowBeforeDelay)
+ .labelElement.style.gridColumn = "2 / span 2";
+
+ this.createPropertyBoolean(comp, SpriteComponent.animationShowOnStart)
+ .labelElement.style.gridColumn = "2 / span 2";
+
+ this.createPropertyBoolean(comp, SpriteComponent.animationHideOnComplete)
+ .labelElement.style.gridColumn = "2 / span 2"
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationStartFrame);
+
+ this.createNumberPropertyRow(comp, SpriteComponent.animationTimeScale);
+ }
+
+ canEdit(obj: any, n: number): boolean {
+
+ return obj instanceof Sprite && obj.animationCustomConfig;
+ }
+
+ canEditNumber(n: number): boolean {
+
+ return n > 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationSection.ts
new file mode 100644
index 000000000..05e87f579
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteAnimationSection.ts
@@ -0,0 +1,178 @@
+namespace phasereditor2d.scene.ui.sceneobjects {
+
+ import controls = colibri.ui.controls;
+
+ export class SpriteAnimationSection extends SceneGameObjectSection {
+
+ constructor(page: controls.properties.PropertyPage) {
+ super(page, "phasereditor2d.scene.ui.sceneobjects.SpriteAnimationSection", "Animation");
+ }
+
+ protected getSectionHelpPath() {
+
+ return "scene-editor/animations-properties.html";
+ }
+
+ createMenu(menu: controls.Menu): void {
+
+ menu.addAction({
+ text: "Open Animation File",
+ callback: async () => {
+
+ const sprite = this.getSelectionFirstElement();
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const anim = finder.findAnimationByKey(sprite.animationKey);
+
+ if (anim) {
+
+ ScenePlugin.getInstance().openAnimationInEditor(anim);
+ }
+ }
+ });
+
+ super.createMenu(menu);
+ }
+
+ createForm(parent: HTMLDivElement) {
+
+ const comp = this.createGridElement(parent, 4);
+ comp.style.gridTemplateColumns = "auto auto 1fr auto";
+
+ {
+ const btn = this.createPropertyEnumRow(comp, SpriteComponent.animationPlayMethod);
+ btn.style.gridColumn = "3 / span 2";
+ }
+
+ const animationToolbar = document.createElement("div");
+ animationToolbar.style.display = "flex";
+ animationToolbar.style.gap = "5px";
+
+ // play animation
+
+ this.createPropertyStringRow(comp, SpriteComponent.animationKey);
+
+ comp.appendChild(animationToolbar);
+
+ this.createAnimationKeyDialogButton(comp, animationToolbar);
+
+ this.createPreviewDialogButton(animationToolbar);
+
+ // enable config
+ this.createPropertyBoolean(comp, SpriteComponent.animationCustomConfig);
+ }
+
+ private createPreviewDialogButton(animationToolbar: HTMLDivElement) {
+
+ const btn = this.createButton(animationToolbar, resources.getIcon(resources.ICON_PLAY), async () => {
+
+ const sprite = this.getSelectionFirstElement();
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const anim = finder.findAnimationByKey(sprite.animationKey);
+
+ if (anim) {
+
+ const config: Phaser.Types.Animations.PlayAnimationConfig = {
+ key: anim.getKey()
+ };
+
+ if (sprite.animationCustomConfig) {
+
+ SpriteComponent.buildPlayConfig(sprite, config);
+ }
+
+ const dlg = new AnimationPreviewDialog(anim.getParent(), config);
+
+ dlg.create();
+
+ } else {
+
+ alert("Animation not found.");
+ }
+ });
+
+ btn.style.gridColumn = "1 / span 4";
+ }
+
+ private createAnimationKeyDialogButton(comp: HTMLDivElement, animationToolbar: HTMLDivElement) {
+
+ const btnUI = this.createButtonDialog({
+ dialogTittle: "Select Animation Key",
+ createDialogViewer: async (revealValue: string) => {
+
+ const viewer = new controls.viewers.TreeViewer("phasereditor2d.scene.ui.sceneobjects.AnimationSection." + this.getId());
+
+ viewer.setCellRendererProvider(new controls.viewers.EmptyCellRendererProvider(e => new pack.ui.viewers.AnimationConfigCellRenderer()));
+ viewer.setLabelProvider(new pack.ui.viewers.AssetPackLabelProvider());
+ viewer.setTreeRenderer(new controls.viewers.TreeViewerRenderer(viewer));
+ viewer.setContentProvider(new controls.viewers.ArrayTreeContentProvider());
+
+ const finder = new pack.core.PackFinder();
+ await finder.preload();
+
+ const animations = finder
+ .getAssets(i => i instanceof pack.core.BaseAnimationsAssetPackItem)
+ .flatMap((i: pack.core.BaseAnimationsAssetPackItem) => i.getAnimations());
+
+ viewer.setInput(animations);
+
+ viewer.revealAndSelect(animations.find(a => a.getKey() === revealValue));
+
+ return viewer;
+ },
+ getValue: () => {
+
+ return this.getSelection()[0].animationKey || "";
+ },
+ onValueSelected: (value: string) => {
+
+ this.getEditor().getUndoManager().add(
+ new SimpleOperation(this.getEditor(), this.getSelection(), SpriteComponent.animationKey, value));
+ },
+ dialogElementToString: (viewer: controls.viewers.TreeViewer, value: pack.core.AnimationConfigInPackItem): string => {
+
+ return value.getKey();
+ },
+ updateIconCallback: async (iconControl, value) => {
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const image = AnimationKeyPropertyType.getAnimationIcon(finder, value);
+
+ iconControl.setIcon(image);
+ },
+ });
+
+ animationToolbar.appendChild(btnUI.buttonElement);
+
+ this.addUpdater(() => {
+
+ btnUI.buttonElement.disabled = this.getSelection()
+ .filter(sprite => !sprite.getEditorSupport()
+ .isUnlockedProperty(SpriteComponent.animationKey))
+ .length > 0;
+
+ btnUI.updateDialogButtonIcon();
+ });
+ }
+
+ canEdit(obj: any, n: number): boolean {
+
+ return obj instanceof Sprite;
+ }
+
+ canEditNumber(n: number): boolean {
+
+ return n > 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteComponent.ts
new file mode 100644
index 000000000..2a6bf8df1
--- /dev/null
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteComponent.ts
@@ -0,0 +1,110 @@
+namespace phasereditor2d.scene.ui.sceneobjects {
+
+ export class SpriteComponent extends Component {
+
+ static animationPlayMethod: IEnumProperty = {
+ name: "animationPlayMethod",
+ label: "Action",
+ defValue: AnimationPlayMethod.NONE,
+ getValue: obj => obj.animationPlayMethod,
+ setValue: (obj: Sprite, val: AnimationPlayMethod) => { obj.animationPlayMethod = val; },
+ getValueLabel: val => {
+ switch (val) {
+
+ case AnimationPlayMethod.NONE:
+ return "NONE";
+
+ case AnimationPlayMethod.PLAY:
+ return "PLAY";
+
+ case AnimationPlayMethod.PLAY_REVERSE:
+ return "PLAY_REVERSE";
+ }
+ },
+ values: [AnimationPlayMethod.NONE, AnimationPlayMethod.PLAY, AnimationPlayMethod.PLAY_REVERSE],
+ };
+
+ static animationKey = SimpleProperty({ name: "animationKey", codeName: "key" }, "", "Animation Key", "The animation key to auto-play.");
+ static animationCustomConfig = SimpleProperty("animationCustomConfig", false, "Custom Config", "Set a new configuration?");
+ static animationFrameRate = SimpleProperty({ name: "animationFrameRate", codeName: "frameRate" }, 24, "Frame Rate", "phaser:Phaser.Types.Animations.PlayAnimationConfig.frameRate");
+ static animationDelay = SimpleProperty({ name: "animationDelay", codeName: "delay" }, 0, "Delay", "phaser:Phaser.Types.Animations.PlayAnimationConfig.delay");
+ static animationRepeat = SimpleProperty({ name: "animationRepeat", codeName: "repeat" }, 0, "Repeat", "phaser:Phaser.Types.Animations.PlayAnimationConfig.repeat");
+ static animationRepeatDelay = SimpleProperty({ name: "animationRepeatDelay", codeName: "repeatDelay" }, 0, "Repeat Delay", "phaser:Phaser.Types.Animations.PlayAnimationConfig.repeatDelay");
+ static animationYoyo = SimpleProperty({ name: "animationYoyo", codeName: "yoyo" }, false, "Yoyo", "phaser:Phaser.Types.Animations.PlayAnimationConfig.yoyo");
+ static animationShowBeforeDelay = SimpleProperty({ name: "animationShowBeforeDelay", codeName: "showBeforeDelay" }, false, "Show Before Delay", "phaser:Phaser.Types.Animations.PlayAnimationConfig.showBeforeDelay");
+ static animationShowOnStart = SimpleProperty({ name: "animationShowOnStart", codeName: "showOnStart" }, false, "Show Before Start", "phaser:Phaser.Types.Animations.PlayAnimationConfig.showBeforeStart");
+ static animationHideOnComplete = SimpleProperty({ name: "animationHideOnComplete", codeName: "hideOnComplete" }, false, "Hide On Complete", "phaser:Phaser.Types.Animations.PlayAnimationConfig.hideOnComplete");
+ static animationStartFrame = SimpleProperty({ name: "animationStartFrame", codeName: "startFrame" }, 0, "Start Frame", "phaser:Phaser.Types.Animations.PlayAnimationConfig.startFrame");
+ static animationTimeScale = SimpleProperty({ name: "animationTimeScale", codeName: "timeScale" }, 1, "Time Scale", "phaser:Phaser.Types.Animations.PlayAnimationConfig.timeScale");
+
+ constructor(obj: Sprite) {
+ super(obj, [
+ SpriteComponent.animationPlayMethod,
+ SpriteComponent.animationKey,
+ SpriteComponent.animationCustomConfig,
+ SpriteComponent.animationFrameRate,
+ SpriteComponent.animationDelay,
+ SpriteComponent.animationRepeat,
+ SpriteComponent.animationRepeatDelay,
+ SpriteComponent.animationYoyo,
+ SpriteComponent.animationShowBeforeDelay,
+ SpriteComponent.animationShowOnStart,
+ SpriteComponent.animationHideOnComplete,
+ SpriteComponent.animationStartFrame,
+ SpriteComponent.animationTimeScale,
+ ]);
+ }
+
+ buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs): void {
+
+ this.buildSetObjectPropertyCodeDOM([SpriteComponent.animationPlayMethod], args2 => {
+
+ const sprite = args.obj as Sprite;
+
+ const method = sprite.animationPlayMethod;
+
+ if (method === AnimationPlayMethod.PLAY || method === AnimationPlayMethod.PLAY_REVERSE) {
+
+ const name = method === AnimationPlayMethod.PLAY ? "play" : "playReverse";
+
+ const call = new core.code.MethodCallCodeDOM(name, args.objectVarName);
+
+ if (sprite.animationCustomConfig) {
+
+ const config: Phaser.Types.Animations.PlayAnimationConfig = {} as any;
+
+ SpriteComponent.buildPlayConfig(sprite, config);
+
+ call.arg(JSON.stringify(config));
+
+ } else {
+
+ call.argLiteral(sprite.animationKey);
+ }
+
+ args.statements.push(call);
+ }
+ });
+ }
+
+ public static buildPlayConfig(sprite: Sprite, config: Phaser.Types.Animations.PlayAnimationConfig) {
+
+ for (const prop of [
+ SpriteComponent.animationKey,
+ SpriteComponent.animationFrameRate,
+ SpriteComponent.animationDelay,
+ SpriteComponent.animationRepeat,
+ SpriteComponent.animationRepeatDelay,
+ SpriteComponent.animationYoyo,
+ SpriteComponent.animationShowBeforeDelay,
+ SpriteComponent.animationShowOnStart,
+ SpriteComponent.animationHideOnComplete,
+ SpriteComponent.animationStartFrame,
+ SpriteComponent.animationTimeScale
+ ]) {
+
+ colibri.core.json.write(config, prop.codeName, prop.getValue(sprite), prop.defValue);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteEditorSupport.ts
index 56311c348..b456c0219 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteEditorSupport.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteEditorSupport.ts
@@ -6,6 +6,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
constructor(obj: Sprite, scene: Scene) {
super(SpriteExtension.getInstance(), obj, scene);
+
+ this.addComponent(new SpriteComponent(obj));
}
}
}
\ No newline at end of file
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteExtension.ts
index b7c690ab5..aefb022df 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteExtension.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/sprite/SpriteExtension.ts
@@ -17,12 +17,45 @@ namespace phasereditor2d.scene.ui.sceneobjects {
});
}
- getCodeDOMBuilder(): GameObjectCodeDOMBuilder {
+ override getCodeDOMBuilder(): GameObjectCodeDOMBuilder {
return new BaseImageCodeDOMBuilder("sprite");
}
- protected newObject(scene: Scene, x: number, y: number, key?: string, frame?: string | number): ISceneGameObject {
+ override acceptsDropData(data: any): boolean {
+
+ if (data instanceof pack.core.AnimationConfigInPackItem) {
+
+ return data.getFrames().length > 0;
+ }
+
+ return super.acceptsDropData(data);
+ }
+
+ override createSceneObjectWithAsset(args: ICreateWithAssetArgs): ISceneGameObject {
+
+ const animConfig = args.asset as pack.core.AnimationConfigInPackItem;
+
+ const frames = animConfig.getFrames();
+
+ const frame = frames[0];
+
+ const args2: ICreateWithAssetArgs = {
+ ...args,
+ asset: frame.getTextureFrame()
+ }
+
+ const sprite = super.createSceneObjectWithAsset(args2) as Sprite;
+
+ sprite.getEditorSupport().setLabel(animConfig.getKey());
+
+ sprite.animationPlayMethod = AnimationPlayMethod.PLAY;
+ sprite.animationKey = animConfig.getKey();
+
+ return sprite;
+ }
+
+ protected override newObject(scene: Scene, x: number, y: number, key?: string, frame?: string | number): ISceneGameObject {
return new Sprite(scene, x, y, key || null, frame);
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureSelectionDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureSelectionDialog.ts
index db3415e6b..803c9cc10 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureSelectionDialog.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureSelectionDialog.ts
@@ -8,7 +8,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
pack.core.IMAGE_TYPE,
pack.core.SVG_TYPE,
pack.core.ATLAS_TYPE,
- pack.core.SPRITESHEET_TYPE
+ pack.core.SPRITESHEET_TYPE,
+ pack.core.ASEPRITE_TYPE
];
export class TextureSelectionDialog extends controls.dialogs.ViewerDialog {
@@ -73,7 +74,19 @@ namespace phasereditor2d.scene.ui.sceneobjects {
viewer.setLabelProvider(new pack.ui.viewers.AssetPackLabelProvider());
viewer.setTreeRenderer(new pack.ui.viewers.AssetPackTreeViewerRenderer(viewer, false));
- viewer.setCellRendererProvider(new pack.ui.viewers.AssetPackCellRendererProvider("grid"));
+
+ viewer.setCellRendererProvider(new class extends pack.ui.viewers.AssetPackCellRendererProvider {
+
+ getCellRenderer(element: any): controls.viewers.ICellRenderer {
+
+ if (element instanceof pack.core.AnimationConfigInPackItem) {
+
+ return new pack.ui.viewers.AnimationConfigCellRenderer("square");
+ }
+
+ return super.getCellRenderer(element);
+ }
+ }("grid"));
viewer.setContentProvider(new (class extends ui.blocks.SceneEditorBlocksContentProvider {
@@ -81,6 +94,17 @@ namespace phasereditor2d.scene.ui.sceneobjects {
return input;
}
+
+ getChildren(parent: any): any[] {
+
+ if (parent instanceof pack.core.AsepriteAssetPackItem) {
+
+ return parent.getFrames();
+ }
+
+ return super.getChildren(parent);
+ }
+
})(this._editor, () => this._editor.getPackFinder().getPacks()));
viewer.setCellSize(64, true);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerCodeDOMBuilder.ts
index 0318d5d3e..634fbde86 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerCodeDOMBuilder.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerCodeDOMBuilder.ts
@@ -29,6 +29,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
call.arg(tilesetArray);
call.argInt(tilemapLayer.x);
call.argInt(tilemapLayer.y);
+ call.setNonNullAssertion(true);
return call;
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerEditorSupport.ts
index 54c12a4fa..2c9f5634e 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerEditorSupport.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tilemap/TilemapLayerEditorSupport.ts
@@ -15,7 +15,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
this.addComponent(
new TransformComponent(obj as unknown as ITransformLikeObject),
- new VisibleComponent(obj as unknown as IVisibleLikeObject),
+ new VisibleComponent(obj as unknown as IVisibleLikeObject)
);
this.setLabel(obj.layer.name);
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractAssetKeyPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractAssetKeyPropertyType.ts
index 26257d98f..23b9c4c79 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractAssetKeyPropertyType.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractAssetKeyPropertyType.ts
@@ -94,7 +94,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
if (element instanceof pack.core.AnimationConfigInPackItem) {
- return new pack.ui.viewers.AnimationConfigCellRenderer(this._finder);
+ return new pack.ui.viewers.AnimationConfigCellRenderer();
}
return super.getCellRenderer(element);
@@ -125,7 +125,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
return parent.getFrames();
}
- if (parent instanceof pack.core.AnimationsAssetPackItem) {
+ if (parent instanceof pack.core.BaseAnimationsAssetPackItem) {
return parent.getAnimations();
}
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts
index e64147273..7406a1ef7 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts
@@ -35,7 +35,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
}
createInspectorPropertyEditor(
- section: SceneGameObjectSection, parent: HTMLElement, userProp: UserProperty, lockIcon: boolean): void {
+ section: SceneGameObjectSection, parent: HTMLElement, userProp: UserProperty, lockIcon: boolean, previewAction?: () => void): void {
const prop = userProp.getComponentProperty();
@@ -47,7 +47,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
const label = section.createLabel(parent, prop.label, PhaserHelp(prop.tooltip));
label.style.gridColumn = "2";
- const comp = this.createEditorComp();
+ const comp = this.createEditorComp(Boolean(previewAction));
parent.appendChild(comp);
const text = section.createStringField(comp, prop);
@@ -72,13 +72,21 @@ namespace phasereditor2d.scene.ui.sceneobjects {
});
comp.appendChild(buttonElement);
+
+ if (previewAction) {
+
+ section.createButton(comp, resources.getIcon(resources.ICON_PLAY), () => {
+
+ previewAction();
+ });
+ }
}
- private createEditorComp() {
+ private createEditorComp(withPreviewButton = false) {
const comp = document.createElement("div");
comp.style.display = "grid";
- comp.style.gridTemplateColumns = "1fr auto";
+ comp.style.gridTemplateColumns = withPreviewButton ? "1fr auto auto" : "1fr auto";
comp.style.gap = "5px";
comp.style.alignItems = "center";
@@ -188,14 +196,13 @@ namespace phasereditor2d.scene.ui.sceneobjects {
}
}
- createEditorElement(getValue: () => any, setValue: (value: any) => void): IPropertyEditor {
+ createEditorElement(getValue: () => any, setValue: (value: any) => void, previewAction?: () => void): IPropertyEditor {
+
+ const comp = this.createEditorComp(Boolean(previewAction));
- const comp = this.createEditorComp();
+ const formBuilder = new controls.properties.FormBuilder();
- const inputElement = document.createElement("input");
- comp.appendChild(inputElement);
- inputElement.type = "text";
- inputElement.classList.add("formText");
+ const inputElement = formBuilder.createText(comp, false);
inputElement.addEventListener("change", e => {
@@ -215,6 +222,16 @@ namespace phasereditor2d.scene.ui.sceneobjects {
this.updateIcon(iconControl, value);
};
+ if (previewAction) {
+
+ formBuilder.createButton(comp, resources.getIcon(resources.ICON_PLAY), () => {
+
+ console.log("here");
+
+ previewAction();
+ });
+ }
+
return {
element: comp,
update
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AnimationKeyPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AnimationKeyPropertyType.ts
index 12bd4d0ed..b142f976f 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AnimationKeyPropertyType.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AnimationKeyPropertyType.ts
@@ -16,29 +16,24 @@ namespace phasereditor2d.scene.ui.sceneobjects {
protected getIcon(finder: pack.core.PackFinder, value: string): controls.IImage {
+ return AnimationKeyPropertyType.getAnimationIcon(finder, value);
+ }
+
+ static getAnimationIcon(finder: pack.core.PackFinder, value: string): controls.IImage {
+
const animation = finder.getPacks()
.flatMap(pack => pack.getItems())
- .filter(item => item instanceof pack.core.AnimationsAssetPackItem)
+ .filter(item => item instanceof pack.core.BaseAnimationsAssetPackItem)
- .flatMap((item: pack.core.AnimationsAssetPackItem) => item.getAnimations())
+ .flatMap((item: pack.core.BaseAnimationsAssetPackItem) => item.getAnimations())
.find(anim => anim.getKey() === value);
if (animation) {
- const frames = animation.getFrames();
-
- if (frames.length > 0) {
-
- const frame = frames[Math.floor(frames.length / 2)];
-
- if (frame) {
-
- return finder.getAssetPackItemImage(frame.getTextureKey(), frame.getFrameKey());
- }
- }
+ return animation.getPreviewImageAsset();
}
return null;
@@ -52,6 +47,64 @@ namespace phasereditor2d.scene.ui.sceneobjects {
return viewer;
}
+
+ createInspectorPropertyEditor(section: SceneGameObjectSection, parent: HTMLElement, userProp: UserProperty, lockIcon: boolean): void {
+
+ super.createInspectorPropertyEditor(section, parent, userProp, lockIcon, async () => {
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const values = section.getSelection()
+ .map(o => userProp.getComponentProperty().getValue(o));
+
+ const key = section.flatValues_StringOneOrNothing(
+ values);
+
+ const anim = finder.findAnimationByKey(key);
+
+ if (anim) {
+
+ const dlg = new AnimationPreviewDialog(anim.getParent(), {
+ key
+ });
+
+ dlg.create();
+
+ } else {
+
+ alert("Animation key not found.");
+ }
+ });
+ }
+
+ createEditorElement(getValue: () => any, setValue: (value: any) => void): IPropertyEditor {
+
+ return super.createEditorElement(getValue, setValue, async () => {
+
+ const finder = new pack.core.PackFinder();
+
+ await finder.preload();
+
+ const key = getValue() as string;
+
+ const anim = finder.findAnimationByKey(key);
+
+ if (anim) {
+
+ const dlg = new AnimationPreviewDialog(anim.getParent(), {
+ key
+ });
+
+ dlg.create();
+
+ } else {
+
+ alert("Animation key not found.");
+ }
+ });
+ }
}
class AnimationKeyContentProvider implements controls.viewers.ITreeContentProvider {
@@ -64,9 +117,9 @@ namespace phasereditor2d.scene.ui.sceneobjects {
.flatMap(pack => pack.getItems())
- .filter(item => item instanceof pack.core.AnimationsAssetPackItem)
+ .filter(item => item instanceof pack.core.BaseAnimationsAssetPackItem)
- .flatMap((item: pack.core.AnimationsAssetPackItem) => item.getAnimations());
+ .flatMap((item: pack.core.BaseAnimationsAssetPackItem) => item.getAnimations());
}
getChildren(parent: any): any[] {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/EventPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/EventPropertyType.ts
index 36c9debec..9a16002f3 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/EventPropertyType.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/EventPropertyType.ts
@@ -64,11 +64,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
protected async createViewer() {
- const finder = new pack.core.PackFinder();
- await finder.preload();
-
const viewer = new controls.viewers.TreeViewer("phasereditor2d.scene.editor.EventPropertyType.Dialog");
- viewer.setCellRendererProvider(new EventCellRendererProvider(finder));
+ viewer.setCellRendererProvider(new EventCellRendererProvider());
viewer.setLabelProvider(new EventLabelProvider());
viewer.setStyledLabelProvider(new EventPropertyStyleLabelProvider());
viewer.setContentProvider(new controls.viewers.ArrayTreeContentProvider());
@@ -103,8 +100,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
await packFinder.preload();
const animEvents = packFinder
- .getAssets(i => i instanceof pack.core.AnimationsAssetPackItem)
- .map(i => i as pack.core.AnimationsAssetPackItem)
+ .getAssets(i => i instanceof pack.core.BaseAnimationsAssetPackItem)
+ .map(i => i as pack.core.BaseAnimationsAssetPackItem)
.flatMap(i => i.getAnimations())
.map(anim => new AnimationEventItem(`animationcomplete-${anim.getKey()}`, anim));
@@ -257,7 +254,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
class EventCellRendererProvider implements controls.viewers.ICellRendererProvider {
- constructor(private _finder: pack.core.PackFinder) {
+ constructor() {
}
@@ -265,7 +262,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
if (element instanceof AnimationEventItem) {
- return new AnimationEventCellRenderer(this._finder);
+ return new AnimationEventCellRenderer();
}
else if (element instanceof SkeletonEventItem) {
diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/TextureConfigPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/TextureConfigPropertyType.ts
index 613aee117..fb5e3fa8c 100644
--- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/TextureConfigPropertyType.ts
+++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/TextureConfigPropertyType.ts
@@ -92,7 +92,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
const finder = new pack.core.PackFinder();
await finder.preload();
-
+
const viewer = await super.createViewer();
viewer.setContentProvider(new TextureContentProvider(finder));
viewer.setTreeRenderer(new pack.ui.viewers.AssetPackTreeViewerRenderer(viewer, false));
@@ -114,6 +114,7 @@ namespace phasereditor2d.scene.ui.sceneobjects {
pack.core.IMAGE_TYPE,
pack.core.SVG_TYPE,
pack.core.ATLAS_TYPE,
+ pack.core.ASEPRITE_TYPE,
pack.core.SPRITESHEET_TYPE];
}
@@ -132,7 +133,8 @@ namespace phasereditor2d.scene.ui.sceneobjects {
return this.getItems(parent);
}
- if (parent instanceof pack.core.ImageFrameContainerAssetPackItem) {
+ if (parent instanceof pack.core.ImageFrameContainerAssetPackItem
+ || parent instanceof pack.core.AsepriteAssetPackItem) {
if (!(parent instanceof pack.core.ImageAssetPackItem)) {
diff --git a/source/editor/product.json b/source/editor/product.json
index f92235f0f..ef6973ed9 100644
--- a/source/editor/product.json
+++ b/source/editor/product.json
@@ -1,4 +1,4 @@
{
"title": "Phaser Editor 2D",
- "version": "3.63.0"
+ "version": "3.64.0"
}
\ No newline at end of file