- Add Mini Map feature

- Allow to extend `HyperLap2dRenderer`
- Update copyright year
This commit is contained in:
fgnm
2024-06-26 10:58:53 +02:00
parent 317c152d44
commit d4d4f21ba7
13 changed files with 202 additions and 5 deletions
+2
View File
@@ -1,6 +1,7 @@
[0.1.5]
- [BREAK CHANGE] Update Spine runtime support to `4.2.0`
- Add Items Tree search filter
- Add Mini Map feature (press and hold keyboard `M` button)
- Basic folder visualization for different atlas packages
- Fix many editor memory leaks
- Fix common crashes related to multi-thread issues
@@ -8,6 +9,7 @@
**Runtime**
- [BREAK CHANGE] Make `ZIndexComponent#layerName` field private
- Optimize some built-in systems
- Allow to extend `HyperLap2dRenderer` and use custom rendering systems
[0.1.4]
- Update libGDX to 1.12.1
@@ -94,6 +94,7 @@ public class BootstrapViewCommand extends SimpleCommand {
facade.registerMediator(new ImagesPackDialogMediator());
facade.registerMediator(new AnimationsPackDialogMediator());
facade.registerMediator(new ShaderManagerDialogMediator());
facade.registerMediator(new MiniMapDialogMediator());
facade.registerMediator(new SaveProjectDialogMediator());
}
@@ -58,7 +58,7 @@ public class SplashStage extends Stage {
companyName.setY(55 - companyName.getHeight() - 7);
addActor(companyName);
Label copyright = new Label("Copyright (c) 2023, All rights reserved.", whiteLabelStyle);
Label copyright = new Label("Copyright (c) 2024, All rights reserved.", whiteLabelStyle);
copyright.setX(13);
copyright.setY(companyName.getY() - 20);
addActor(copyright);
@@ -0,0 +1,71 @@
package games.rednblack.editor.system;
import com.artemis.annotations.All;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
import games.rednblack.editor.renderer.components.BoundingBoxComponent;
import games.rednblack.editor.renderer.components.NodeComponent;
import games.rednblack.editor.renderer.components.ViewPortComponent;
import games.rednblack.editor.renderer.systems.render.HyperLap2dRenderer;
import games.rednblack.editor.renderer.systems.render.logic.DrawableLogic;
import games.rednblack.editor.utils.runtime.SandboxComponentRetriever;
@All(ViewPortComponent.class)
public class HyperLap2dRendererMiniMap extends HyperLap2dRenderer {
private final Rectangle bounds = new Rectangle();
private final OrthographicCamera minimapCamera = new OrthographicCamera();
public HyperLap2dRendererMiniMap(Batch batch, boolean hasStencilBuffer) {
super(batch, hasStencilBuffer);
}
public Texture getMiniMapTexture(int rootEntity) {
Camera oldCamera = camera;
camera = minimapCamera;
NodeComponent nodeComponent = nodeMapper.get(rootEntity);
bounds.set(0, 0, 0, 0);
Integer[] children = nodeComponent.children.begin();
for (int i = 0, n = nodeComponent.children.size; i < n; i++) {
int child = children[i];
BoundingBoxComponent boundingBoxComponent = SandboxComponentRetriever.get(child, BoundingBoxComponent.class);
if (boundingBoxComponent != null && boundingBoxComponent.rectangle != null)
bounds.merge(boundingBoxComponent.rectangle);
}
nodeComponent.children.end();
minimapCamera.setToOrtho(true, bounds.width, bounds.height);
minimapCamera.position.set(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2,0);
Gdx.gl.glClearColor(0.318f, 0.318f, 0.318f, 1);
frameBufferManager.createIfNotExists("minimap", (int) (bounds.width * pixelsPerWU), (int) (bounds.height * pixelsPerWU), false, hasStencilBuffer);
frameBufferManager.begin("minimap");
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
minimapCamera.update();
batch.setProjectionMatrix(minimapCamera.combined);
drawableLogicMapper.beginPipeline();
batch.begin();
enableCull = false;
drawRecursively(rootEntity, 1f, DrawableLogic.RenderingType.TEXTURE);
enableCull = true;
batch.end();
frameBufferManager.endCurrent();
drawableLogicMapper.endPipeline();
camera = oldCamera;
return frameBufferManager.getColorBufferTexture("minimap");
}
public Rectangle getMiniMapBounds() {
return bounds;
}
}
@@ -61,6 +61,8 @@ public class KeyBindingsLayout {
public static final int TOGGLE_FULL_SCREEN = 29;
public static final int SHOW_MINI_MAP = 30;
private static final ObjectMap<Integer, KeyMapper> defaultMapper = new ObjectMap<>();
static {
defaultMapper.put(NEW_PROJECT, new KeyMapper(NEW_PROJECT, true, false, false, Input.Keys.N));
@@ -103,6 +105,7 @@ public class KeyBindingsLayout {
defaultMapper.put(HIDE_GUI, new KeyMapper(HIDE_GUI, false, false, false, Input.Keys.F12));
defaultMapper.put(OPEN_CONSOLE, new KeyMapper(OPEN_CONSOLE, false, false, false, Input.Keys.F10));
defaultMapper.put(TOGGLE_FULL_SCREEN, new KeyMapper(TOGGLE_FULL_SCREEN, false, false, false, Input.Keys.F11));
defaultMapper.put(SHOW_MINI_MAP, new KeyMapper(SHOW_MINI_MAP, false, false, false, Input.Keys.M));
}
private static final Array<KeyMapper> mapping = new Array<>();
@@ -241,6 +241,9 @@ public class HyperLap2DScreen implements Screen, InputProcessor {
case KeyBindingsLayout.OPEN_CONSOLE:
facade.sendNotification(MsgAPI.OPEN_CONSOLE);
break;
case KeyBindingsLayout.SHOW_MINI_MAP:
facade.sendNotification(MsgAPI.SHOW_MINI_MAP);
break;
}
return false;
}
@@ -251,6 +254,9 @@ public class HyperLap2DScreen implements Screen, InputProcessor {
case KeyBindingsLayout.HIDE_GUI:
uiStage.addAction(Actions.parallel(Actions.touchable(Touchable.enabled), Actions.fadeIn(0.1f)));
break;
case KeyBindingsLayout.SHOW_MINI_MAP:
facade.sendNotification(MsgAPI.HIDE_MINI_MAP);
break;
}
return false;
}
@@ -24,6 +24,7 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationGLESFix;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
@@ -48,6 +49,7 @@ import games.rednblack.editor.renderer.systems.ParticleSystem;
import games.rednblack.editor.renderer.systems.PhysicsSystem;
import games.rednblack.editor.renderer.utils.HyperJson;
import games.rednblack.editor.renderer.utils.TextureArrayCpuPolygonSpriteBatch;
import games.rednblack.editor.system.HyperLap2dRendererMiniMap;
import games.rednblack.editor.system.ParticleContinuousSystem;
import games.rednblack.editor.system.PhysicsAdjustSystem;
import games.rednblack.editor.system.TalosContinuousSystem;
@@ -150,7 +152,8 @@ public class Sandbox {
externalItemTypes.addExternalItemType(new TinyVGItemType());
externalItemTypes.addExternalItemType(new TypingLabelItemType());
SceneConfiguration config = new SceneConfiguration(new TextureArrayCpuPolygonSpriteBatch(32_000), true);
Batch batch = new TextureArrayCpuPolygonSpriteBatch(32_767);
SceneConfiguration config = new SceneConfiguration(batch, true);
config.setResourceRetriever(resourceManager);
config.setExternalItemTypes(externalItemTypes);
@@ -167,6 +170,7 @@ public class Sandbox {
config.addSystem(new ParticleContinuousSystem());
config.removeSystem(TalosSystem.class);
config.addSystem(new TalosContinuousSystem());
config.setRendererSystem(new HyperLap2dRendererMiniMap(batch, true));
config.addSystem(manager);
@@ -54,7 +54,7 @@ public class AboutDialog extends H2DDialog {
leftTable.add("Total Time").padTop(20).row();
leftTable.add(totalTimeSpent).row();
contentTable.add("Copyright \u00A9 2023 Red & Black Games").left().row();
contentTable.add("Copyright \u00A9 2024 Red & Black Games").left().row();
contentTable.add("").row();
contentTable.add("Dedicated to game lovers. Create something awesome!").left().row();
contentTable.add("").row();
@@ -0,0 +1,64 @@
package games.rednblack.editor.view.ui.dialog;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Scaling;
import com.kotcrab.vis.ui.VisUI;
import games.rednblack.editor.system.HyperLap2dRendererMiniMap;
import games.rednblack.editor.view.stage.Sandbox;
public class MiniMapDialog extends Table {
private final TextureRegionDrawable drawable;
private final TextureRegion region;
private final Image miniMap;
private Rectangle miniMapBounds;
public MiniMapDialog() {
drawable = new TextureRegionDrawable();
region = new TextureRegion();
drawable.setRegion(region);
miniMap = new Image(drawable);
miniMap.addListener(new ClickListener() {
private final Vector2 touchPoint = new Vector2();
@Override
public void clicked(InputEvent event, float x, float y) {
touchPoint.set(x - miniMap.getImageX(), y - miniMap.getImageY());
float relativeX = (touchPoint.x) / miniMap.getImageWidth();
float relativeY = (touchPoint.y) / miniMap.getImageHeight();
float transformedX = miniMapBounds.x + relativeX * miniMapBounds.width;
float transformedY = miniMapBounds.y + relativeY * miniMapBounds.height;
Sandbox.getInstance().panSceneTo(transformedX, transformedY);
}
});
miniMap.setAlign(Align.center);
add(miniMap);
setBackground(VisUI.getSkin().getDrawable("panel"));
}
public void update() {
Sandbox sandbox = Sandbox.getInstance();
HyperLap2dRendererMiniMap rendererMiniMap = sandbox.getEngine().getSystem(HyperLap2dRendererMiniMap.class);
Texture texture = rendererMiniMap.getMiniMapTexture(sandbox.getRootEntity());
region.setRegion(texture);
drawable.setRegion(region);
miniMap.setScaling(Scaling.contain);
miniMap.setDrawable(drawable);
miniMapBounds = rendererMiniMap.getMiniMapBounds();
}
}
@@ -0,0 +1,43 @@
package games.rednblack.editor.view.ui.dialog;
import com.badlogic.gdx.utils.Align;
import games.rednblack.editor.view.stage.Sandbox;
import games.rednblack.editor.view.stage.UIStage;
import games.rednblack.h2d.common.MsgAPI;
import games.rednblack.puremvc.Mediator;
import games.rednblack.puremvc.interfaces.INotification;
import games.rednblack.puremvc.util.Interests;
public class MiniMapDialogMediator extends Mediator<MiniMapDialog> {
private static final String TAG = MiniMapDialogMediator.class.getCanonicalName();
private static final String NAME = TAG;
public MiniMapDialogMediator() {
super(NAME, new MiniMapDialog());
}
@Override
public void listNotificationInterests(Interests interests) {
interests.add(MsgAPI.SHOW_MINI_MAP, MsgAPI.HIDE_MINI_MAP);
}
@Override
public void handleNotification(INotification notification) {
super.handleNotification(notification);
Sandbox sandbox = Sandbox.getInstance();
UIStage uiStage = sandbox.getUIStage();
switch (notification.getName()) {
case MsgAPI.SHOW_MINI_MAP:
viewComponent.setSize(uiStage.getWidth() * 0.6f, uiStage.getHeight() * 0.6f);
viewComponent.setOrigin(Align.center);
viewComponent.update();
uiStage.addActor(viewComponent);
viewComponent.setPosition((uiStage.getWidth() - viewComponent.getWidth()) / 2, (uiStage.getHeight() - viewComponent.getHeight()) / 2);
break;
case MsgAPI.HIDE_MINI_MAP:
viewComponent.remove();
break;
}
}
}
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
public class WhitePixel {
public static WhitePixel sharedInstance;
@@ -18,6 +19,7 @@ public class WhitePixel {
public Texture texture;
public TextureRegion textureRegion;
public TextureRegionDrawable drawable;
public WhitePixel() {
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
@@ -27,6 +29,7 @@ public class WhitePixel {
texture = new Texture(pixmap, true);
texture.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.MipMapLinearLinear);
textureRegion = new TextureRegion(texture);
drawable = new TextureRegionDrawable(textureRegion);
}
public void dispose() {