Tiled Plugin improvements.

* Support animated tiles (Sprite and Spine animation)
* Improve UI
* Support custom cursors
* Bug fixes
This commit is contained in:
fgnm
2021-04-29 01:01:27 +02:00
parent 061dc8999b
commit 01b9756eb8
31 changed files with 766 additions and 177 deletions
+6
View File
@@ -1,3 +1,9 @@
[0.0.7]
= Editor =
- Huge improvements to Tiled Plugin:
* Sprite and Spine animated Tiles
* UI improvements and general refactoring
[0.0.6]
- Update libGDX to 1.10.0
- Add flipX and flipY flag
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+6 -19
View File
@@ -2,29 +2,16 @@ tiled.png
size: 512, 128
filter: Linear, Linear
image-Box-active
bounds: 87, 22, 4, 4
bounds: 25, 20, 4, 4
split: 1, 1, 1, 1
image-Box-inactive
bounds: 436, 31, 4, 4
bounds: 435, 95, 4, 4
split: 1, 1, 1, 1
plugin-tab-active
bounds: 436, 105, 73, 21
split: 4, 4, 3, 0
plugin-tab-inactive
bounds: 2, 5, 83, 21
split: 3, 3, 2, 1
tab-back-line
bounds: 2, 2, 2, 1
split: 0, 0, 0, 0
tile
bounds: 436, 71, 32, 32
tile-eraser
bounds: 436, 37, 32, 32
tiles-drop-here-normal
bounds: 2, 28, 215, 98
bounds: 1, 26, 215, 98
tiles-drop-here-over
bounds: 219, 28, 215, 98
bounds: 218, 26, 215, 98
tool-tilebrush
bounds: 470, 80, 22, 23
bounds: 1, 1, 22, 23
tool-tileeraser
bounds: 470, 55, 22, 23
bounds: 435, 101, 22, 23
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 B

+3
View File
@@ -19,10 +19,13 @@ dependencies {
implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
implementation "com.kotcrab.vis:vis-ui:$visuiVersion"
implementation "com.esotericsoftware.spine:spine-libgdx:$spineVersion"
implementation 'net.mountainblade:modular:1.0'
implementation project(":hyperlap2d-common-api")
implementation project(":hyperlap2d-runtime-libgdx")
implementation project(":h2d-libgdx-spine-extension")
testImplementation group: 'junit', name: 'junit', version: '4.12'
}
@@ -21,6 +21,7 @@ package games.rednblack.editor.plugin.tiled;
import com.badlogic.ashley.core.Engine;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.kotcrab.vis.ui.VisUI;
import com.kotcrab.vis.ui.widget.VisLabel;
import com.kotcrab.vis.ui.widget.VisTable;
@@ -40,11 +41,11 @@ import org.puremvc.java.interfaces.IFacade;
*/
public class TiledPanel extends UIDraggablePanel {
public static final float GRID_WIDTH = 200f;
public static final float GRID_WIDTH = 220f;
public static final float GRID_HEIGHT = 250f;
public static final float DROP_WIDTH = 210f;
public static final float DROP_WIDTH = 220f;
public static final float DROP_HEIGHT = 140f;
public static final float SETTINGS_WIDTH = 200f;
public static final float SETTINGS_WIDTH = 220f;
public static final float SETTINGS_HEIGHT = 150f;
public TiledPlugin tiledPlugin;
@@ -79,11 +80,6 @@ public class TiledPanel extends UIDraggablePanel {
this.resourcesManager = tiledPlugin.pluginRM;
mainTable.clear();
VisTextButton.VisTextButtonStyle btnStyle = new VisTextButton.VisTextButtonStyle();
btnStyle.up = new TextureRegionDrawable(resourcesManager.getTextureRegion("plugin-tab-inactive"));
btnStyle.checked = new TextureRegionDrawable(resourcesManager.getTextureRegion("plugin-tab-active"));
btnStyle.font = VisUI.getSkin().getFont("default-font");
btnStyle.fontColor = VisUI.getSkin().getColor("white");
tabbedPane = new ImageTabbedPane();
paneTable = tabbedPane.getTable();
@@ -127,9 +123,10 @@ public class TiledPanel extends UIDraggablePanel {
.width(WIDTH)
.height(HEIGHT)
.row();
float prevHeight = getHeight();
pack();
setFixedPosition();
float heightDiff = getHeight() - prevHeight;
setY(getY() - heightDiff);
}
@Override
@@ -161,8 +158,8 @@ public class TiledPanel extends UIDraggablePanel {
settingsTab.resetGridCategory();
}
public void addTile(String tileName) {
tilesTab.addTile(tileName);
public void addTile(String tileName, int type) {
tilesTab.addTile(tileName, type);
}
public void selectTile(TileVO tileVO) {
@@ -172,7 +169,6 @@ public class TiledPanel extends UIDraggablePanel {
public void removeTile() {
tilesTab.removeTile();
reInitTabTable();
setFixedPosition();
tilesTab.scrollTiles();
}
@@ -22,8 +22,11 @@ import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop;
import games.rednblack.editor.plugin.tiled.view.SpineDrawable;
import games.rednblack.editor.renderer.factory.EntityFactory;
import games.rednblack.h2d.common.vo.CursorData;
import games.rednblack.editor.plugin.tiled.data.TileVO;
import games.rednblack.editor.plugin.tiled.tools.DeleteTileTool;
@@ -46,6 +49,7 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
public static final String NAME = TAG;
private TiledPlugin tiledPlugin;
private DragAndDrop.Target target;
public TiledPanelMediator(TiledPlugin tiledPlugin) {
super(NAME, new TiledPanel(tiledPlugin));
@@ -63,7 +67,6 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
TiledPlugin.ACTION_DELETE_TILE,
TiledPlugin.ACTION_SET_GRID_SIZE_FROM_LIST,
TiledPlugin.ACTION_SET_OFFSET,
TiledPlugin.PANEL_OPEN,
TiledPlugin.OPEN_DROP_DOWN,
TiledPlugin.GRID_CHANGED,
SettingsTab.OK_BTN_CLICKED,
@@ -87,7 +90,9 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
tiledPlugin.initSaveData();
viewComponent.initView();
DragAndDrop.Target target = new DragAndDrop.Target(viewComponent.getDropTable()) {
if (target != null)
tiledPlugin.facade.sendNotification(MsgAPI.REMOVE_TARGET, target);
target = new DragAndDrop.Target(viewComponent.getDropTable()) {
@Override
public boolean drag(DragAndDrop.Source source, DragAndDrop.Payload payload, float x, float y, int pointer) {
return true;
@@ -95,14 +100,14 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
@Override
public void drop(DragAndDrop.Source source, DragAndDrop.Payload payload, float x, float y, int pointer) {
ResourcePayloadObject resourcePayloadObject = (ResourcePayloadObject) payload.getObject();
if (!resourcePayloadObject.className.endsWith(".ImageResource")) return; //only image resource can become a tile!
int type = mapClassNameToEntityType(resourcePayloadObject.className);
if (type == EntityFactory.UNKNOWN_TYPE) return; //only some resources can become a tile!
String tileName = resourcePayloadObject.name;
if (tiledPlugin.dataToSave.containsTile(tileName)) return;
tiledPlugin.facade.sendNotification(TiledPlugin.TILE_ADDED, tileName);
tiledPlugin.facade.sendNotification(TiledPlugin.TILE_ADDED, new Object[]{tileName, type});
}
};
@@ -112,11 +117,12 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
viewComponent.setFixedPosition();
break;
case TiledPlugin.TILE_ADDED:
tileName = notification.getBody();
viewComponent.addTile(tileName);
viewComponent.setFixedPosition();
Object[] payload = notification.getBody();
tileName = (String) payload[0];
int type = (int) payload[1];
viewComponent.addTile(tileName, type);
tiledPlugin.dataToSave.addTile(tileName);
tiledPlugin.dataToSave.addTile(tileName, type);
tiledPlugin.saveDataManager.save();
break;
case TiledPlugin.TILE_SELECTED:
@@ -136,8 +142,20 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
tiledPlugin.facade.sendNotification(TiledPlugin.ACTION_DELETE_TILE, tileName);
break;
case TiledPlugin.ACTION_SET_GRID_SIZE_FROM_LIST:
TextureRegion r = tiledPlugin.pluginRM.getTextureRegion(notification.getBody());
tiledPlugin.dataToSave.setGrid(r.getRegionWidth() / tiledPlugin.getPixelToWorld(), r.getRegionHeight() / tiledPlugin.getPixelToWorld());
float width = 0;
float height = 0;
TileVO t = tiledPlugin.dataToSave.getTile(notification.getBody());
if (t.entityType == EntityFactory.SPINE_TYPE) {
SpineDrawable spineDrawable = tiledPlugin.pluginRM.getSpineDrawable(t.regionName);
width = spineDrawable.width;
height = spineDrawable.height;
} else {
TextureRegion r = tiledPlugin.pluginRM.getTextureRegion(t.regionName, t.entityType);
width = r.getRegionWidth();
height = r.getRegionHeight();
}
tiledPlugin.dataToSave.setGrid(width / tiledPlugin.getPixelToWorld(), height / tiledPlugin.getPixelToWorld());
tiledPlugin.facade.sendNotification(TiledPlugin.GRID_CHANGED);
break;
case TiledPlugin.ACTION_DELETE_TILE:
@@ -149,38 +167,25 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
viewComponent.removeTile();
break;
case TiledPlugin.PANEL_OPEN:
if(viewComponent.isOpen) {
break;
}
viewComponent.show(tiledPlugin.getAPI().getUIStage());
if(tiledPlugin.isSceneLoaded) {
viewComponent.setFixedPosition();
}
break;
case MsgAPI.TOOL_SELECTED:
String body = notification.getBody();
String cursorName = null;
switch (body) {
case DrawTileTool.NAME:
cursorName = "tile";
tiledPlugin.facade.sendNotification(TiledPlugin.PANEL_OPEN);
break;
case DeleteTileTool.NAME:
cursorName = "tile-eraser";
case DrawTileTool.NAME:
if(viewComponent.isOpen) {
break;
}
viewComponent.show(tiledPlugin.getAPI().getUIStage());
if(tiledPlugin.isSceneLoaded) {
viewComponent.setFixedPosition();
}
break;
default:
viewComponent.hide();
break;
}
if (cursorName != null) {
CursorData cursorData = new CursorData(cursorName, 14, 14);
TextureRegion region = tiledPlugin.pluginRM.getTextureRegion(cursorName);
//TODO A custom cursor has to be a Texture not a region of an atlas
//tiledPlugin.getAPI().setCursor(cursorData, region);
}
break;
case SettingsTab.OK_BTN_CLICKED:
tiledPlugin.dataToSave.setParameterVO(notification.getBody());
@@ -207,5 +212,14 @@ public class TiledPanelMediator extends Mediator<TiledPanel> {
}
}
private int mapClassNameToEntityType(String className) {
if (className.endsWith(".ImageResource"))
return EntityFactory.IMAGE_TYPE;
else if (className.endsWith(".SpriteResource"))
return EntityFactory.SPRITE_TYPE;
else if (className.endsWith(".SpineResource"))
return EntityFactory.SPINE_TYPE;
return EntityFactory.UNKNOWN_TYPE;
}
}
@@ -45,7 +45,6 @@ import net.mountainblade.modular.annotations.Implementation;
import java.util.Set;
/**
* Created by mariam on 2/2/2016.
*/
@@ -56,7 +55,6 @@ public class TiledPlugin extends H2DPluginAdapter {
public static final String CLASS_NAME = "games.rednblack.editor.plugin.tiled";
public static final String TILE_ADDED = CLASS_NAME + ".TILE_ADDED";
public static final String TILE_SELECTED = CLASS_NAME + ".TILE_SELECTED";
public static final String PANEL_OPEN = CLASS_NAME + ".PANEL_OPEN";
public static final String OPEN_DROP_DOWN = CLASS_NAME + ".OPEN_DROP_DOWN";
public static final String GRID_CHANGED = CLASS_NAME + ".GRID_CHANGED";
public static final String ACTION_DELETE_TILE = CLASS_NAME + ".ACTION_DELETE_TILE";
@@ -107,7 +105,7 @@ public class TiledPlugin extends H2DPluginAdapter {
tileAddButtonStyle.down = skin.getDrawable("toolbar-down");
tileAddButtonStyle.checked = skin.getDrawable("toolbar-down");
tileAddButtonStyle.over = skin.getDrawable("toolbar-over");
tileAddButtonStyle.imageUp = new TextureRegionDrawable(pluginRM.getTextureRegion("tool-tilebrush"));
tileAddButtonStyle.imageUp = new TextureRegionDrawable(pluginRM.getTextureRegion("tool-tilebrush", -1));
pluginAPI.addTool(DrawTileTool.NAME, tileAddButtonStyle, true, drawTileTool);
VisImageButton.VisImageButtonStyle tileDeleteButtonStyle = new VisImageButton.VisImageButtonStyle();
@@ -115,7 +113,7 @@ public class TiledPlugin extends H2DPluginAdapter {
tileDeleteButtonStyle.down = skin.getDrawable("toolbar-down");
tileDeleteButtonStyle.checked = skin.getDrawable("toolbar-down");
tileDeleteButtonStyle.over = skin.getDrawable("toolbar-over");
tileDeleteButtonStyle.imageUp = new TextureRegionDrawable(pluginRM.getTextureRegion("tool-tileeraser"));
tileDeleteButtonStyle.imageUp = new TextureRegionDrawable(pluginRM.getTextureRegion("tool-tileeraser", -1));
pluginAPI.addTool(DeleteTileTool.NAME, tileDeleteButtonStyle, false, deleteTileTool);
pluginAPI.setDropDownItemName(ACTION_SET_GRID_SIZE_FROM_ITEM, "Set tile grid size");
@@ -197,6 +195,10 @@ public class TiledPlugin extends H2DPluginAdapter {
return selectedTileVO.regionName;
}
public int getSelectedTileType() {
return selectedTileVO.entityType;
}
public Vector2 getSelectedTileGridOffset() {
return selectedTileVO.gridOffset;
}
@@ -1,6 +1,7 @@
package games.rednblack.editor.plugin.tiled.data;
import com.badlogic.gdx.math.Vector2;
import games.rednblack.editor.renderer.factory.EntityFactory;
/**
* Created by mariam on 5/13/16.
@@ -9,6 +10,7 @@ public class TileVO {
public String regionName = "";
public Vector2 gridOffset;
public int entityType = EntityFactory.IMAGE_TYPE;
public TileVO() {
gridOffset = new Vector2();
@@ -1,12 +1,19 @@
package games.rednblack.editor.plugin.tiled.manager;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.ObjectMap;
import com.esotericsoftware.spine.Skeleton;
import com.esotericsoftware.spine.SkeletonData;
import com.esotericsoftware.spine.SkeletonJson;
import com.esotericsoftware.spine.SkeletonRenderer;
import com.google.common.io.ByteStreams;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.plugin.tiled.view.SpineDrawable;
import games.rednblack.editor.renderer.factory.EntityFactory;
import java.io.File;
import java.io.FileOutputStream;
@@ -23,22 +30,36 @@ public class ResourcesManager {
private TiledPlugin tiledPlugin;
private TextureAtlas textureAtlas;
private final SkeletonRenderer skeletonRenderer = new SkeletonRenderer();
private final ObjectMap<String, Texture> textureCache = new ObjectMap<>();
private final ObjectMap<String, SpineDrawable> spineDrawableCache = new ObjectMap<>();
public ResourcesManager(TiledPlugin tiledPlugin) {
this.tiledPlugin = tiledPlugin;
skeletonRenderer.setPremultipliedAlpha(true);
init();
}
private void init() {
FileHandle atlasTempFile = getResourceFileFromJar(".atlas");
FileHandle pngTempFile = getResourceFileFromJar(".png");
FileHandle atlasTempFile = getResourceFileFromJar(RESOURCES_FILE_NAME + ".atlas");
FileHandle pngTempFile = getResourceFileFromJar(RESOURCES_FILE_NAME + ".png");
textureAtlas = new TextureAtlas(atlasTempFile);
atlasTempFile.file().deleteOnExit();
pngTempFile.file().deleteOnExit();
loadTexture("tile-cursor");
loadTexture("tile-eraser-cursor");
}
private FileHandle getResourceFileFromJar(String extension) {
String fileName = RESOURCES_FILE_NAME+extension;
private void loadTexture(String name) {
FileHandle file = getResourceFileFromJar(name + ".png");
file.file().deleteOnExit();
textureCache.put(name, new Texture(file));
}
private FileHandle getResourceFileFromJar(String fileName) {
File tempFile = new File(tiledPlugin.getAPI().getCacheDir()+ File.separator + fileName);
try {
@@ -53,17 +74,37 @@ public class ResourcesManager {
return new FileHandle(tempFile);
}
public TextureRegion getTextureRegion(String name) {
public Texture getTexture(String name) {
return textureCache.get(name);
}
public TextureRegion getTextureRegion(String name, int type) {
TextureRegion region = textureAtlas.findRegion(name); // try to get region from plugin assets
if (region != null) {
// System.out.println("region: "+name+", "+region.getRegionWidth()+" "+region.getRegionHeight());
}
if (region == null) { // take the region from hyperlap assets
region = tiledPlugin.getAPI().getSceneLoader().getRm().getTextureRegion(name);
switch (type) {
case EntityFactory.IMAGE_TYPE:
region = tiledPlugin.getAPI().getSceneLoader().getRm().getTextureRegion(name);
break;
case EntityFactory.SPRITE_TYPE:
region = tiledPlugin.getAPI().getSceneLoader().getRm().getSpriteAnimation(name).getRegions().get(0);
break;
}
}
return region;
}
public SpineDrawable getSpineDrawable(String name) {
if (spineDrawableCache.get(name) == null) {
SkeletonJson skeletonJson = new SkeletonJson(tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonAtlas(name));
SkeletonData skeletonData = skeletonJson.readSkeletonData(tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonJSON(name));
Skeleton skeleton = new Skeleton(skeletonData);
spineDrawableCache.put(name, new SpineDrawable(skeleton, skeletonRenderer));
}
return spineDrawableCache.get(name);
}
public NinePatch getPluginNinePatch(String name) {
TextureAtlas.AtlasRegion region = textureAtlas.findRegion(name);
if(region == null) return null;
@@ -20,8 +20,9 @@ public class DataToSave {
parameterVO = new ParameterVO();
}
public void addTile(String tileDrawableName) {
public void addTile(String tileDrawableName, int type) {
TileVO newTile = new TileVO(tileDrawableName);
newTile.entityType = type;
if (!tiles.contains(newTile, false)) {
tiles.add(newTile);
}
@@ -2,9 +2,12 @@ package games.rednblack.editor.plugin.tiled.tools;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.h2d.common.MsgAPI;
import games.rednblack.h2d.common.view.tools.Tool;
import games.rednblack.h2d.common.vo.CursorData;
import org.puremvc.java.interfaces.INotification;
import java.util.HashSet;
@@ -14,7 +17,7 @@ import java.util.Set;
* Created by mariam on 4/5/16.
*/
public class DeleteTileTool implements Tool {
private static final CursorData CURSOR = new CursorData("tile-eraser-cursor", 14, 14);
public static final String NAME = "TILE_DELETE_TOOL";
private TiledPlugin tiledPlugin;
@@ -27,6 +30,8 @@ public class DeleteTileTool implements Tool {
@Override
public void initTool() {
Texture cursorTexture = tiledPlugin.pluginRM.getTexture(CURSOR.region);
tiledPlugin.getAPI().setCursor(CURSOR, new TextureRegion(cursorTexture));
}
@Override
@@ -2,38 +2,51 @@ package games.rednblack.editor.plugin.tiled.tools;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.kotcrab.vis.ui.util.OsUtils;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.renderer.components.MainItemComponent;
import games.rednblack.editor.plugin.tiled.tools.drawStrategy.IDrawStrategy;
import games.rednblack.editor.plugin.tiled.tools.drawStrategy.ImageDrawStrategy;
import games.rednblack.editor.plugin.tiled.tools.drawStrategy.SpineDrawStrategy;
import games.rednblack.editor.plugin.tiled.tools.drawStrategy.SpriteDrawStrategy;
import games.rednblack.editor.renderer.components.TextureRegionComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.factory.EntityFactory;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.h2d.common.command.TransformCommandBuilder;
import games.rednblack.h2d.common.command.UpdateRegionCommandBuilder;
import games.rednblack.h2d.common.factory.IFactory;
import games.rednblack.h2d.common.view.tools.Tool;
import games.rednblack.h2d.common.vo.CursorData;
import org.puremvc.java.interfaces.INotification;
/**
* Created by mariam on 3/29/16.
*/
public class DrawTileTool implements Tool {
private static final CursorData CURSOR = new CursorData("tile-cursor", 14, 14);
public static final String NAME = "TILE_ADD_TOOL";
private TiledPlugin tiledPlugin;
private float gridWidth;
private float gridHeight;
private final ImageDrawStrategy imageDrawStrategy;
private final SpriteDrawStrategy spriteDrawStrategy;
private final SpineDrawStrategy spineDrawStrategy;
private IDrawStrategy currentDrawStrategy;
public DrawTileTool(TiledPlugin tiledPlugin) {
this.tiledPlugin = tiledPlugin;
imageDrawStrategy = new ImageDrawStrategy(tiledPlugin);
spriteDrawStrategy = new SpriteDrawStrategy(tiledPlugin);
spineDrawStrategy = new SpineDrawStrategy(tiledPlugin);
}
@Override
public void initTool() {
Texture cursorTexture = tiledPlugin.pluginRM.getTexture(CURSOR.region);
tiledPlugin.getAPI().setCursor(CURSOR, new TextureRegion(cursorTexture));
}
@Override
@@ -49,7 +62,7 @@ public class DrawTileTool implements Tool {
@Override
public boolean stageMouseDown(float x, float y) {
initGridThings();
drawImage(x, y);
drawTile(x, y);
return true;
}
@@ -59,7 +72,7 @@ public class DrawTileTool implements Tool {
@Override
public void stageMouseDragged(float x, float y) {
drawImage(x, y);
drawTile(x, y);
}
@Override
@@ -75,7 +88,10 @@ public class DrawTileTool implements Tool {
@Override
public boolean itemMouseDown(Entity entity, float x, float y) {
initGridThings();
drawOnEntity(entity, x, y);
if (entity == null)
drawTile(x, y);
else
drawOnEntity(entity);
return true;
}
@@ -85,33 +101,27 @@ public class DrawTileTool implements Tool {
@Override
public void itemMouseDragged(Entity entity, float x, float y) {
drawImage(x, y);
drawTile(x, y);
}
@Override
public void itemMouseDoubleClick(Entity entity, float x, float y) {
if (!tiledPlugin.isOnCurrentSelectedLayer(entity)) return;
if (entity != null) {
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
if (textureRegionComponent != null && tiledPlugin.isTile(entity)) {
// there is already other tile under this one
if (textureRegionComponent.regionName.equals(tiledPlugin.getSelectedTileName())) {
//rotate
TransformCommandBuilder commandBuilder = new TransformCommandBuilder();
commandBuilder.begin(entity);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
if (transformComponent.scaleX > 0 && transformComponent.scaleY > 0) {
commandBuilder.setScale(transformComponent.scaleX * -1f, transformComponent.scaleY);
} else if (transformComponent.scaleX < 0 && transformComponent.scaleY > 0) {
commandBuilder.setScale(transformComponent.scaleX, transformComponent.scaleY * -1f);
} else if (transformComponent.scaleX < 0 && transformComponent.scaleY < 0) {
commandBuilder.setScale(transformComponent.scaleX * -1f, transformComponent.scaleY);
} else if (transformComponent.scaleX > 0 && transformComponent.scaleY < 0) {
commandBuilder.setScale(transformComponent.scaleX, transformComponent.scaleY * -1f);
}
commandBuilder.execute(tiledPlugin.facade);
}
if (entity != null && tiledPlugin.isTile(entity)) {
//rotate
TransformCommandBuilder commandBuilder = new TransformCommandBuilder();
commandBuilder.begin(entity);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
if (transformComponent.scaleX > 0 && transformComponent.scaleY > 0) {
commandBuilder.setScale(transformComponent.scaleX * -1f, transformComponent.scaleY);
} else if (transformComponent.scaleX < 0 && transformComponent.scaleY > 0) {
commandBuilder.setScale(transformComponent.scaleX, transformComponent.scaleY * -1f);
} else if (transformComponent.scaleX < 0 && transformComponent.scaleY < 0) {
commandBuilder.setScale(transformComponent.scaleX * -1f, transformComponent.scaleY);
} else if (transformComponent.scaleX > 0 && transformComponent.scaleY < 0) {
commandBuilder.setScale(transformComponent.scaleX, transformComponent.scaleY * -1f);
}
commandBuilder.execute(tiledPlugin.facade);
}
}
@@ -143,9 +153,23 @@ public class DrawTileTool implements Tool {
gridHeight = tiledPlugin.dataToSave.getParameterVO().gridHeight;
}
private final Vector2 temp = new Vector2();
private void chooseDrawStrategy() {
switch (tiledPlugin.getSelectedTileType()) {
case EntityFactory.IMAGE_TYPE:
currentDrawStrategy = imageDrawStrategy;
break;
case EntityFactory.SPRITE_TYPE:
currentDrawStrategy = spriteDrawStrategy;
break;
case EntityFactory.SPINE_TYPE:
currentDrawStrategy = spineDrawStrategy;
break;
default:
currentDrawStrategy = null;
}
}
private void drawImage(float x, float y) {
private void drawTile(float x, float y) {
if (tiledPlugin.getSelectedTileName().equals("")) return;
float newX = MathUtils.floor(x / gridWidth) * gridWidth + tiledPlugin.getSelectedTileGridOffset().x;
@@ -153,53 +177,12 @@ public class DrawTileTool implements Tool {
int row = MathUtils.floor(newY / gridHeight);
int column = MathUtils.round(newX / gridWidth);
Entity underneathTile = tiledPlugin.getPluginEntityWithParams(row, column);
if (underneathTile != null) {
drawOnEntity(underneathTile, x, y);
return;
}
IFactory itemFactory = tiledPlugin.getAPI().getItemFactory();
temp.set(newX, newY);
if (itemFactory.createSimpleImage(tiledPlugin.getSelectedTileName(), temp)) {
Entity imageEntity = itemFactory.getCreatedEntity();
MainItemComponent mainItemComponent = ComponentRetriever.get(imageEntity, MainItemComponent.class);
mainItemComponent.tags.add(TiledPlugin.TILE_TAG);
mainItemComponent.setCustomVars(TiledPlugin.ROW, Integer.toString(row));
mainItemComponent.setCustomVars(TiledPlugin.COLUMN, Integer.toString(column));
TransformComponent transformComponent = ComponentRetriever.get(imageEntity, TransformComponent.class);
transformComponent.x = newX;
transformComponent.y = newY;
}
chooseDrawStrategy();
currentDrawStrategy.drawTile(newX, newY, row, column);
}
private void drawOnEntity(Entity entity, float x, float y) {
if (!tiledPlugin.isOnCurrentSelectedLayer(entity)) return;
if (entity != null) {
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
if (textureRegionComponent != null && textureRegionComponent.regionName != null
&& tiledPlugin.isTile(entity)) {
// there is already other tile under this one
if(textureRegionComponent.regionName.equals(tiledPlugin.getSelectedTileName())) {
return;
} else {
//replace
updateRegion(entity, tiledPlugin.getSelectedTileName());
}
}
return;
}
drawImage(x, y);
private void drawOnEntity(Entity entity) {
chooseDrawStrategy();
currentDrawStrategy.updateTile(entity);
}
private void updateRegion(Entity entity, String region) {
UpdateRegionCommandBuilder builder = new UpdateRegionCommandBuilder();
builder.begin(entity);
builder.setRegion(tiledPlugin.getAPI().getSceneLoader().getRm().getTextureRegion(region));
builder.setRegionName(tiledPlugin.getSelectedTileName());
builder.execute(tiledPlugin.facade);
}
}
@@ -0,0 +1,34 @@
package games.rednblack.editor.plugin.tiled.tools.drawStrategy;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.math.Vector2;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.renderer.components.MainItemComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
public abstract class BasicDrawStrategy implements IDrawStrategy {
protected TiledPlugin tiledPlugin;
protected final Vector2 temp = new Vector2();
public BasicDrawStrategy(TiledPlugin plugin) {
tiledPlugin = plugin;
}
protected void postProcessEntity(Entity entity, float x, float y, int row, int column) {
MainItemComponent mainItemComponent = ComponentRetriever.get(entity, MainItemComponent.class);
mainItemComponent.tags.add(TiledPlugin.TILE_TAG);
mainItemComponent.setCustomVars(TiledPlugin.ROW, Integer.toString(row));
mainItemComponent.setCustomVars(TiledPlugin.COLUMN, Integer.toString(column));
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
transformComponent.x = x;
transformComponent.y = y;
}
protected boolean checkValidTile(Entity entity) {
return tiledPlugin.isOnCurrentSelectedLayer(entity) && tiledPlugin.isTile(entity)
&& ComponentRetriever.get(entity, MainItemComponent.class).entityType == tiledPlugin.getSelectedTileType();
}
}
@@ -0,0 +1,8 @@
package games.rednblack.editor.plugin.tiled.tools.drawStrategy;
import com.badlogic.ashley.core.Entity;
public interface IDrawStrategy {
void drawTile(float x, float y, int row, int column);
void updateTile(Entity entity);
}
@@ -0,0 +1,49 @@
package games.rednblack.editor.plugin.tiled.tools.drawStrategy;
import com.badlogic.ashley.core.Entity;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.renderer.components.TextureRegionComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.h2d.common.command.ReplaceRegionCommandBuilder;
import games.rednblack.h2d.common.factory.IFactory;
public class ImageDrawStrategy extends BasicDrawStrategy {
private final ReplaceRegionCommandBuilder replaceRegionCommandBuilder = new ReplaceRegionCommandBuilder();
public ImageDrawStrategy(TiledPlugin plugin) {
super(plugin);
}
@Override
public void drawTile(float x, float y, int row, int column) {
Entity underneathTile = tiledPlugin.getPluginEntityWithParams(row, column);
if (underneathTile != null) {
updateTile(underneathTile);
return;
}
IFactory itemFactory = tiledPlugin.getAPI().getItemFactory();
temp.set(x, y);
if (itemFactory.createSimpleImage(tiledPlugin.getSelectedTileName(), temp)) {
Entity imageEntity = itemFactory.getCreatedEntity();
postProcessEntity(imageEntity, x, y, row, column);
}
}
@Override
public void updateTile(Entity entity) {
if (!checkValidTile(entity)) return;
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
if (textureRegionComponent != null && textureRegionComponent.regionName != null) {
// there is already other tile under this one
if (!textureRegionComponent.regionName.equals(tiledPlugin.getSelectedTileName())) {
String region = tiledPlugin.getSelectedTileName();
replaceRegionCommandBuilder.begin(entity);
replaceRegionCommandBuilder.setRegion(tiledPlugin.getAPI().getSceneLoader().getRm().getTextureRegion(region));
replaceRegionCommandBuilder.setRegionName(region);
replaceRegionCommandBuilder.execute(tiledPlugin.facade);
}
}
}
}
@@ -0,0 +1,57 @@
package games.rednblack.editor.plugin.tiled.tools.drawStrategy;
import com.badlogic.ashley.core.Entity;
import com.esotericsoftware.spine.Skeleton;
import com.esotericsoftware.spine.SkeletonData;
import com.esotericsoftware.spine.SkeletonJson;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.renderer.components.SpineDataComponent;
import games.rednblack.editor.renderer.components.sprite.SpriteAnimationComponent;
import games.rednblack.editor.renderer.components.sprite.SpriteAnimationStateComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.h2d.common.command.ReplaceSpineCommandBuilder;
import games.rednblack.h2d.common.factory.IFactory;
import games.rednblack.h2d.extention.spine.SpineObjectComponent;
public class SpineDrawStrategy extends BasicDrawStrategy {
private final ReplaceSpineCommandBuilder replaceSpineCommandBuilder = new ReplaceSpineCommandBuilder();
public SpineDrawStrategy(TiledPlugin plugin) {
super(plugin);
}
@Override
public void drawTile(float x, float y, int row, int column) {
Entity underneathTile = tiledPlugin.getPluginEntityWithParams(row, column);
if (underneathTile != null) {
updateTile(underneathTile);
return;
}
IFactory itemFactory = tiledPlugin.getAPI().getItemFactory();
temp.set(x, y);
if (itemFactory.createSpineAnimation(tiledPlugin.getSelectedTileName(), temp)) {
Entity imageEntity = itemFactory.getCreatedEntity();
postProcessEntity(imageEntity, x, y, row, column);
}
}
@Override
public void updateTile(Entity entity) {
if (!checkValidTile(entity)) return;
SpineDataComponent spineDataComponent = ComponentRetriever.get(entity, SpineDataComponent.class);
if (!spineDataComponent.animationName.equals(tiledPlugin.getSelectedTileName())) {
replaceSpineCommandBuilder.begin(entity);
String animName = tiledPlugin.getSelectedTileName();
replaceSpineCommandBuilder.setAnimationName(animName);
SkeletonJson skeletonJson = new SkeletonJson(tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonAtlas(animName));
replaceSpineCommandBuilder.setSkeletonJson(skeletonJson);
SkeletonData skeletonData = skeletonJson.readSkeletonData((tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonJSON(animName)));
replaceSpineCommandBuilder.setSkeleton(new Skeleton(skeletonData));
replaceSpineCommandBuilder.execute(tiledPlugin.facade);
}
}
}
@@ -0,0 +1,64 @@
package games.rednblack.editor.plugin.tiled.tools.drawStrategy;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.Array;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.renderer.components.sprite.SpriteAnimationComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.h2d.common.command.ReplaceSpriteAnimationCommandBuilder;
import games.rednblack.h2d.common.factory.IFactory;
public class SpriteDrawStrategy extends BasicDrawStrategy {
ReplaceSpriteAnimationCommandBuilder replaceSpriteAnimationCommandBuilder = new ReplaceSpriteAnimationCommandBuilder();
public SpriteDrawStrategy(TiledPlugin plugin) {
super(plugin);
}
@Override
public void drawTile(float x, float y, int row, int column) {
Entity underneathTile = tiledPlugin.getPluginEntityWithParams(row, column);
if (underneathTile != null) {
updateTile(underneathTile);
return;
}
IFactory itemFactory = tiledPlugin.getAPI().getItemFactory();
temp.set(x, y);
if (itemFactory.createSpriteAnimation(tiledPlugin.getSelectedTileName(), temp)) {
Entity imageEntity = itemFactory.getCreatedEntity();
postProcessEntity(imageEntity, x, y, row, column);
}
}
@Override
public void updateTile(Entity entity) {
if (!checkValidTile(entity)) return;
SpriteAnimationComponent spriteAnimationComponent = ComponentRetriever.get(entity, SpriteAnimationComponent.class);
if (!spriteAnimationComponent.animationName.equals(tiledPlugin.getSelectedTileName())) {
Array<TextureAtlas.AtlasRegion> regions = getRegions(tiledPlugin.getSelectedTileName());
replaceSpriteAnimationCommandBuilder.begin(entity);
replaceSpriteAnimationCommandBuilder.setAnimationName(tiledPlugin.getSelectedTileName());
replaceSpriteAnimationCommandBuilder.setRegion(regions);
replaceSpriteAnimationCommandBuilder.execute(tiledPlugin.facade);
}
}
private Array<TextureAtlas.AtlasRegion> getRegions(String filter) {
// filtering regions by name
Array<TextureAtlas.AtlasRegion> allRegions = tiledPlugin.getAPI().getSceneLoader().getRm().getSpriteAnimation(filter).getRegions();
Array<TextureAtlas.AtlasRegion> regions = new Array<>();
for(TextureAtlas.AtlasRegion region: allRegions) {
if(region.name.contains(filter)) {
regions.add(region);
}
}
return regions;
}
}
@@ -0,0 +1,108 @@
package games.rednblack.editor.plugin.tiled.view;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray;
import com.esotericsoftware.spine.*;
import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.MeshAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
public class SpineDrawable extends BaseDrawable {
private float minX = 0;
private float minY = 0;
private Skeleton skeleton;
private AnimationState animationState;
private SkeletonRenderer skeletonRenderer;
public float width, height;
private FloatArray temp;
public SpineDrawable(Skeleton skeleton, SkeletonRenderer skeletonRenderer) {
temp = new FloatArray();
this.skeletonRenderer = skeletonRenderer;
this.skeleton = skeleton;
AnimationStateData animationStateData = new AnimationStateData(skeleton.getData());
animationState = new AnimationState(animationStateData);
computeBoundBox();
float scaleFactor;
if (this.width > this.height) {
//scale by width
scaleFactor = 1.0f / (this.width / 40);
} else {
scaleFactor = 1.0f / (this.height / 40);
}
skeleton.setScale(scaleFactor, scaleFactor);
}
public Skeleton getSkeleton() {
return skeleton;
}
public AnimationState getAnimationState() {
return animationState;
}
private void computeBoundBox() {
skeleton.updateWorldTransform();
Array<Slot> drawOrder = skeleton.getDrawOrder();
minX = Float.MAX_VALUE;
minY = Float.MAX_VALUE;
float maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
for (int i = 0, n = drawOrder.size; i < n; i++) {
Slot slot = drawOrder.get(i);
if (!slot.getBone().isActive()) continue;
int verticesLength = 0;
float[] vertices = null;
Attachment attachment = slot.getAttachment();
if (attachment instanceof RegionAttachment) {
verticesLength = 8;
vertices = temp.setSize(8);
((RegionAttachment)attachment).computeWorldVertices(slot.getBone(), vertices, 0, 2);
} else if (attachment instanceof MeshAttachment) {
MeshAttachment mesh = (MeshAttachment)attachment;
verticesLength = mesh.getWorldVerticesLength();
vertices = temp.setSize(verticesLength);
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
}
if (vertices != null) {
for (int ii = 0; ii < verticesLength; ii += 2) {
float x = vertices[ii], y = vertices[ii + 1];
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
}
width = (maxX - minX);
height = (maxY - minY);
}
@Override
public void draw(Batch batch, float x, float y, float width, float height) {
skeleton.updateWorldTransform();
animationState.update(Gdx.graphics.getDeltaTime());
animationState.apply(skeleton);
skeleton.setPosition(x, y - 20);
Color color = skeleton.getColor();
float oldAlpha = color.a;
skeleton.getColor().a *= batch.getColor().a;
skeletonRenderer.draw(batch, skeleton);
color.a = oldAlpha;
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
}
}
@@ -2,6 +2,7 @@ package games.rednblack.editor.plugin.tiled.view.tabs;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
@@ -16,6 +17,8 @@ import games.rednblack.editor.plugin.tiled.TiledPanel;
import games.rednblack.editor.plugin.tiled.TiledPlugin;
import games.rednblack.editor.plugin.tiled.data.TileVO;
import games.rednblack.editor.plugin.tiled.manager.ResourcesManager;
import games.rednblack.editor.plugin.tiled.view.SpineDrawable;
import games.rednblack.editor.renderer.factory.EntityFactory;
import games.rednblack.h2d.common.view.ui.StandardWidgetsFactory;
/**
@@ -49,8 +52,8 @@ public class GridTilesTab extends DefaultTab {
public void initView() {
if (isDrop = savedTiles.size == 0) {
VisImageButton.VisImageButtonStyle dropBoxStyle = new VisImageButton.VisImageButtonStyle();
dropBoxStyle.up = new TextureRegionDrawable(resourcesManager.getTextureRegion("tiles-drop-here-normal"));
dropBoxStyle.imageOver = new TextureRegionDrawable(resourcesManager.getTextureRegion("tiles-drop-here-over"));
dropBoxStyle.up = new TextureRegionDrawable(resourcesManager.getTextureRegion("tiles-drop-here-normal", -1));
dropBoxStyle.imageOver = new TextureRegionDrawable(resourcesManager.getTextureRegion("tiles-drop-here-over", -1));
VisImageButton dropRegion = new VisImageButton(dropBoxStyle);
content.clear();
content.add(dropRegion)
@@ -72,14 +75,14 @@ public class GridTilesTab extends DefaultTab {
}
}
public void addTile(String tileName) {
public void addTile(String tileName, int type) {
if (pane != null) isBottomEdge = pane.isBottomEdge();
if (tileIndex == 0) {
setGridSizeToFirstTileSize(tileName);
setGridSizeToFirstTileSize(tileName, type);
isDrop = false;
panel.reInitTabTable();
}
initTiles(tileName);
initTiles(tileName, type);
panel.pack();
scrollTiles();
tiles.get(tileIndex).setChecked(true);
@@ -107,14 +110,25 @@ public class GridTilesTab extends DefaultTab {
}
}
private void setGridSizeToFirstTileSize(String tileName) {
float gridWidth = resourcesManager.getTextureRegion(tileName).getRegionWidth() / tiledPlugin.getPixelToWorld();
float gridHeight = resourcesManager.getTextureRegion(tileName).getRegionHeight() / tiledPlugin.getPixelToWorld();
private void setGridSizeToFirstTileSize(String tileName, int type) {
float width = 0;
float height = 0;
if (type == EntityFactory.SPINE_TYPE) {
SpineDrawable spineDrawable = tiledPlugin.pluginRM.getSpineDrawable(tileName);
width = spineDrawable.width;
height = spineDrawable.height;
} else {
TextureRegion r = tiledPlugin.pluginRM.getTextureRegion(tileName, type);
width = r.getRegionWidth();
height = r.getRegionHeight();
}
float gridWidth = width / tiledPlugin.getPixelToWorld();
float gridHeight = height / tiledPlugin.getPixelToWorld();
tiledPlugin.dataToSave.setGrid(gridWidth, gridHeight);
tiledPlugin.facade.sendNotification(TiledPlugin.GRID_CHANGED);
}
private void initTiles(String tileName) {
private void initTiles(String tileName, int type) {
content.clear();
tiles.clear();
@@ -140,10 +154,19 @@ public class GridTilesTab extends DefaultTab {
imageBoxStyle.over = active;
Drawable tileDrawable = null;
if (i < savedTiles.size) {
tileDrawable = new TextureRegionDrawable(resourcesManager.getTextureRegion(savedTiles.get(i).regionName));
int t = savedTiles.get(i).entityType;
if (t == EntityFactory.SPINE_TYPE) {
tileDrawable = resourcesManager.getSpineDrawable(savedTiles.get(i).regionName);
} else {
tileDrawable = new TextureRegionDrawable(resourcesManager.getTextureRegion(savedTiles.get(i).regionName, t));
}
} else if (!tileName.equals("")) {
if (i == tileIndex) {
tileDrawable = new TextureRegionDrawable(resourcesManager.getTextureRegion(tileName));
if (type == EntityFactory.SPINE_TYPE) {
tileDrawable = resourcesManager.getSpineDrawable(tileName);
} else {
tileDrawable = new TextureRegionDrawable(resourcesManager.getTextureRegion(tileName, type));
}
}
}
imageBoxStyle.imageUp = tileDrawable;
@@ -198,6 +221,6 @@ public class GridTilesTab extends DefaultTab {
}
private void initTiles() {
initTiles("");
initTiles("", -1);
}
}
@@ -63,7 +63,9 @@ public class BootstrapCommand extends SimpleCommand {
facade.registerCommand(MsgAPI.ACTION_ITEM_AND_CHILDREN_TO, ItemChildrenTransformCommand::new);
facade.registerCommand(MsgAPI.ACTION_ITEM_TRANSFORM_TO, ItemTransformCommand::new);
facade.registerCommand(MsgAPI.ACTION_UPDATE_REGION_DATA, UpdateRegionCommand::new);
facade.registerCommand(MsgAPI.ACTION_REPLACE_REGION_DATA, ReplaceRegionCommand::new);
facade.registerCommand(MsgAPI.ACTION_REPLACE_SPRITE_ANIMATION_DATA, ReplaceSpriteAnimationCommand::new);
facade.registerCommand(MsgAPI.ACTION_REPLACE_SPINE_ANIMATION_DATA, ReplaceSpineCommand::new);
facade.registerCommand(MsgAPI.ACTION_ADD_TO_LIBRARY, AddToLibraryCommand::new);
facade.registerCommand(MsgAPI.ACTION_ADD_TO_LIBRARY_ACTION, AddToLibraryAction::new);
facade.registerCommand(MsgAPI.ACTION_CONVERT_TO_BUTTON, ConvertToButtonCommand::new);
@@ -1,17 +1,19 @@
package games.rednblack.editor.controller.commands;
package games.rednblack.editor.controller.commands.component;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import games.rednblack.editor.HyperLap2DFacade;
import games.rednblack.editor.controller.commands.EntityModifyRevertibleCommand;
import games.rednblack.editor.renderer.components.DimensionsComponent;
import games.rednblack.editor.renderer.components.TextureRegionComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.data.ProjectInfoVO;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.editor.utils.runtime.EntityUtils;
import games.rednblack.editor.view.stage.Sandbox;
import games.rednblack.h2d.common.MsgAPI;
public class UpdateRegionCommand extends EntityModifyRevertibleCommand {
public class ReplaceRegionCommand extends EntityModifyRevertibleCommand {
private Integer entityId;
private String backupRegionName;
@@ -28,6 +30,7 @@ public class UpdateRegionCommand extends EntityModifyRevertibleCommand {
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
DimensionsComponent size = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
backupRegionName = textureRegionComponent.regionName;
backupRegion = textureRegionComponent.region;
@@ -39,6 +42,9 @@ public class UpdateRegionCommand extends EntityModifyRevertibleCommand {
size.width = textureRegionComponent.region.getRegionWidth() / ppwu;
size.height = textureRegionComponent.region.getRegionHeight() / ppwu;
transformComponent.originX = size.width / 2;
transformComponent.originY = size.height / 2;
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
@@ -48,6 +54,7 @@ public class UpdateRegionCommand extends EntityModifyRevertibleCommand {
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
DimensionsComponent size = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
textureRegionComponent.regionName = backupRegionName;
textureRegionComponent.region = backupRegion;
@@ -56,6 +63,9 @@ public class UpdateRegionCommand extends EntityModifyRevertibleCommand {
size.width = textureRegionComponent.region.getRegionWidth() / ppwu;
size.height = textureRegionComponent.region.getRegionHeight() / ppwu;
transformComponent.originX = size.width / 2;
transformComponent.originY = size.height / 2;
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
}
@@ -0,0 +1,94 @@
package games.rednblack.editor.controller.commands.component;
import com.badlogic.ashley.core.Entity;
import com.esotericsoftware.spine.*;
import games.rednblack.editor.HyperLap2DFacade;
import games.rednblack.editor.controller.commands.EntityModifyRevertibleCommand;
import games.rednblack.editor.renderer.components.DimensionsComponent;
import games.rednblack.editor.renderer.components.SpineDataComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.editor.utils.runtime.EntityUtils;
import games.rednblack.h2d.common.MsgAPI;
import games.rednblack.h2d.extention.spine.SpineObjectComponent;
public class ReplaceSpineCommand extends EntityModifyRevertibleCommand {
private Integer entityId;
private String backupAnimName;
private SkeletonJson backupSkeletonJson;
private Skeleton backupSkeleton;
@Override
public void doAction() {
Object[] payload = getNotification().getBody();
Entity entity = (Entity) payload[0];
String animName = (String) payload[1];
SkeletonJson skeletonJson = (SkeletonJson) payload[2];
Skeleton skeleton = (Skeleton) payload[3];
SkeletonData skeletonData = skeleton.getData();
entityId = EntityUtils.getEntityId(entity);
SpineDataComponent spineDataComponent = ComponentRetriever.get(entity, SpineDataComponent.class);
SpineObjectComponent spineObjectComponent = ComponentRetriever.get(entity, SpineObjectComponent.class);
DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
backupAnimName = spineDataComponent.animationName;
backupSkeletonJson = spineObjectComponent.skeletonJson;
backupSkeleton = spineObjectComponent.skeleton;
spineDataComponent.animationName = animName;
spineObjectComponent.skeletonJson = skeletonJson;
spineObjectComponent.skeletonData = skeletonData;
spineObjectComponent.skeleton = skeleton;
AnimationStateData stateData = new AnimationStateData(skeletonData);
spineObjectComponent.state = new AnimationState(stateData);
spineObjectComponent.computeBoundBox(dimensionsComponent);
dimensionsComponent.width *= spineObjectComponent.worldMultiplier;
dimensionsComponent.height *= spineObjectComponent.worldMultiplier;
transformComponent.originX = dimensionsComponent.width / 2f;
transformComponent.originY = dimensionsComponent.height / 2f;
String currentAnimName = skeletonData.getAnimations().get(0).getName();
spineDataComponent.currentAnimationName = currentAnimName;
spineObjectComponent.setAnimation(currentAnimName);
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
@Override
public void undoAction() {
Entity entity = EntityUtils.getByUniqueId(entityId);
SpineDataComponent spineDataComponent = ComponentRetriever.get(entity, SpineDataComponent.class);
SpineObjectComponent spineObjectComponent = ComponentRetriever.get(entity, SpineObjectComponent.class);
DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
spineDataComponent.animationName = backupAnimName;
spineObjectComponent.skeletonJson = backupSkeletonJson;
spineObjectComponent.skeletonData = backupSkeleton.getData();
spineObjectComponent.skeleton = backupSkeleton;
AnimationStateData stateData = new AnimationStateData(spineObjectComponent.skeletonData);
spineObjectComponent.state = new AnimationState(stateData);
spineObjectComponent.computeBoundBox(dimensionsComponent);
dimensionsComponent.width *= spineObjectComponent.worldMultiplier;
dimensionsComponent.height *= spineObjectComponent.worldMultiplier;
transformComponent.originX = dimensionsComponent.width / 2f;
transformComponent.originY = dimensionsComponent.height / 2f;
String currentAnimName = spineObjectComponent.skeletonData.getAnimations().get(0).getName();
spineDataComponent.currentAnimationName = currentAnimName;
spineObjectComponent.setAnimation(currentAnimName);
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
}
@@ -0,0 +1,100 @@
package games.rednblack.editor.controller.commands.component;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.Array;
import games.rednblack.editor.HyperLap2DFacade;
import games.rednblack.editor.controller.commands.EntityModifyRevertibleCommand;
import games.rednblack.editor.renderer.components.DimensionsComponent;
import games.rednblack.editor.renderer.components.TextureRegionComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.components.sprite.SpriteAnimationComponent;
import games.rednblack.editor.renderer.components.sprite.SpriteAnimationStateComponent;
import games.rednblack.editor.renderer.data.FrameRange;
import games.rednblack.editor.renderer.data.ProjectInfoVO;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.editor.utils.runtime.EntityUtils;
import games.rednblack.editor.view.stage.Sandbox;
import games.rednblack.h2d.common.MsgAPI;
public class ReplaceSpriteAnimationCommand extends EntityModifyRevertibleCommand {
private Integer entityId;
private String backupAnimName;
private Array<TextureAtlas.AtlasRegion> backupAnimRegions;
@Override
public void doAction() {
Object[] payload = getNotification().getBody();
Entity entity = (Entity) payload[0];
String animName = (String) payload[1];
Array<TextureAtlas.AtlasRegion> regions = (Array<TextureAtlas.AtlasRegion>) payload[2];
entityId = EntityUtils.getEntityId(entity);
SpriteAnimationComponent spriteAnimationComponent = ComponentRetriever.get(entity, SpriteAnimationComponent.class);
SpriteAnimationStateComponent spriteAnimationStateComponent = ComponentRetriever.get(entity, SpriteAnimationStateComponent.class);
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
DimensionsComponent size = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
backupAnimName = spriteAnimationComponent.animationName;
backupAnimRegions = spriteAnimationStateComponent.allRegions;
spriteAnimationComponent.animationName = animName;
spriteAnimationComponent.frameRangeMap.clear();
spriteAnimationComponent.frameRangeMap.put("Default", new FrameRange("Default", 0, regions.size-1));
spriteAnimationComponent.currentAnimation = "Default";
spriteAnimationComponent.playMode = Animation.PlayMode.LOOP;
spriteAnimationStateComponent.setAllRegions(regions);
spriteAnimationStateComponent.set(spriteAnimationComponent);
textureRegionComponent.region = regions.get(0);
ProjectInfoVO projectInfoVO = Sandbox.getInstance().getSceneControl().sceneLoader.getRm().getProjectVO();
float ppwu = projectInfoVO.pixelToWorld;
size.width = textureRegionComponent.region.getRegionWidth() / ppwu;
size.height = textureRegionComponent.region.getRegionHeight() / ppwu;
transformComponent.originX = size.width / 2;
transformComponent.originY = size.height / 2;
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
@Override
public void undoAction() {
Entity entity = EntityUtils.getByUniqueId(entityId);
SpriteAnimationComponent spriteAnimationComponent = ComponentRetriever.get(entity, SpriteAnimationComponent.class);
SpriteAnimationStateComponent spriteAnimationStateComponent = ComponentRetriever.get(entity, SpriteAnimationStateComponent.class);
TextureRegionComponent textureRegionComponent = ComponentRetriever.get(entity, TextureRegionComponent.class);
DimensionsComponent size = ComponentRetriever.get(entity, DimensionsComponent.class);
TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
spriteAnimationComponent.animationName = backupAnimName;
spriteAnimationComponent.frameRangeMap.clear();
spriteAnimationComponent.frameRangeMap.put("Default", new FrameRange("Default", 0, backupAnimRegions.size-1));
spriteAnimationComponent.currentAnimation = "Default";
spriteAnimationComponent.playMode = Animation.PlayMode.LOOP;
spriteAnimationStateComponent.setAllRegions(backupAnimRegions);
spriteAnimationStateComponent.set(spriteAnimationComponent);
textureRegionComponent.region = backupAnimRegions.get(0);
ProjectInfoVO projectInfoVO = Sandbox.getInstance().getSceneControl().sceneLoader.getRm().getProjectVO();
float ppwu = projectInfoVO.pixelToWorld;
size.width = textureRegionComponent.region.getRegionWidth() / ppwu;
size.height = textureRegionComponent.region.getRegionHeight() / ppwu;
transformComponent.originX = size.width / 2;
transformComponent.originY = size.height / 2;
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ITEM_DATA_UPDATED, entity);
}
}