diff --git a/core/src/com/riiablo/camera/IsometricCamera.java b/core/src/com/riiablo/camera/IsometricCamera.java new file mode 100644 index 00000000..bf63f4cb --- /dev/null +++ b/core/src/com/riiablo/camera/IsometricCamera.java @@ -0,0 +1,63 @@ +package com.riiablo.camera; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import com.riiablo.map.DT1.Tile; +import com.riiablo.util.EngineUtils; + +public class IsometricCamera extends OrthographicCamera { + + public final OrthographicCamera camera = this; + private final Vector2 offset = new Vector2(); + + public IsometricCamera() {} + + public void offset(float x, float y) { + offset.set(x, y); + } + + public void translate(Vector2 vec) { + position.add(vec.x, vec.y, 0); + } + + public void set(Vector2 vec) { + set(vec.x, vec.y); + } + + public void set(float x, float y) { + position.set(x, y, 0).add(offset.x, offset.y, 0); + } + + public Vector2 toScreen(Vector2 worldCoords) { + return toScreen(worldCoords.x, worldCoords.y, worldCoords); + } + + public Vector2 toScreen(float x, float y, Vector2 dst) { + return EngineUtils.worldToScreenCoords(x, y, dst); + } + + public Vector2 toWorld(Vector2 screenCoords) { + return toWorld(screenCoords.x, screenCoords.y, screenCoords); + } + + public Vector2 toWorld(float x, float y, Vector2 dst) { + x += offset.x; + y += offset.y; + //y += offset.y; + x /= Tile.SUBTILE_WIDTH50; + y /= Tile.SUBTILE_HEIGHT50; + dst.x = ( x - y) / 2; + dst.y = (-x - y) / 2; + return dst; + } + + public Vector2 toTile(Vector2 worldCoords) { + return toTile(worldCoords.x, worldCoords.y, worldCoords); + } + + public Vector2 toTile(float x, float y, Vector2 dst) { + dst.x = x < 0 ? MathUtils.floor(x) : MathUtils.floorPositive(x); + dst.y = y < 0 ? MathUtils.floor(y) : MathUtils.floorPositive(y); + return dst; + } +} diff --git a/core/src/com/riiablo/camera/OrthographicCamera.java b/core/src/com/riiablo/camera/OrthographicCamera.java new file mode 100644 index 00000000..1dd7f5fc --- /dev/null +++ b/core/src/com/riiablo/camera/OrthographicCamera.java @@ -0,0 +1,31 @@ +package com.riiablo.camera; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; + +public class OrthographicCamera extends com.badlogic.gdx.graphics.OrthographicCamera { + + private final Vector3 tmpVec3 = new Vector3(); + + public OrthographicCamera() {} + + public Vector2 project(Vector2 worldCoords) { + return project(worldCoords.x, worldCoords.y, worldCoords); + } + + public Vector2 project(float x, float y, Vector2 dst) { + tmpVec3.set(x, y, 0); + project(tmpVec3); + return dst.set(tmpVec3.x, tmpVec3.y); + } + + public Vector2 unproject(Vector2 screenCoords) { + return unproject(screenCoords.x, screenCoords.y, screenCoords); + } + + public Vector2 unproject(float x, float y, Vector2 dst) { + tmpVec3.set(x, y, 0); + unproject(tmpVec3); + return dst.set(tmpVec3.x, tmpVec3.y); + } +} diff --git a/tools/src/com/riiablo/CameraTool.java b/tools/src/com/riiablo/CameraTool.java new file mode 100644 index 00000000..f5a953ee --- /dev/null +++ b/tools/src/com/riiablo/CameraTool.java @@ -0,0 +1,148 @@ +package com.riiablo; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.InputAdapter; +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Vector2; +import com.riiablo.map.DT1.Tile; +import com.riiablo.camera.IsometricCamera; +import com.riiablo.util.DebugUtils; + +public class CameraTool extends ApplicationAdapter { + private static final String TAG = "CameraTool"; + + public static void main(String[] args) { + LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + config.title = TAG; + config.resizable = false; + config.width = 1280; + config.height = 720; + config.vSyncEnabled = false; + config.foregroundFPS = config.backgroundFPS = 144; + new LwjglApplication(new CameraTool(), config); + } + + Batch batch; + BitmapFont font; + ShapeRenderer shapes; + IsometricCamera iso; + Matrix4 center = new Matrix4(); + Matrix4 idt = new Matrix4(); + + @Override + public void create() { + batch = new SpriteBatch(); + font = new BitmapFont(); + iso = new IsometricCamera(); + shapes = new ShapeRenderer(); + center.set(shapes.getTransformMatrix()).translate( + Gdx.graphics.getWidth() / 2, + Gdx.graphics.getHeight() / 2, + 0); + idt.set(shapes.getProjectionMatrix()); + + iso.setToOrtho(false); + //iso.offset(0, -Tile.SUBTILE_HEIGHT50); + iso.set(0, 0); + + Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f); + + Gdx.input.setInputProcessor(new InputAdapter() { + @Override + public boolean scrolled(int amount) { + iso.zoom += (amount * 0.05); + iso.zoom = MathUtils.clamp(iso.zoom, 0.05f, 2f); + return super.scrolled(amount); + } + }); + } + + final Vector2 vec2 = new Vector2(); + + @Override + public void render() { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + iso.update(); + + shapes.setTransformMatrix(center); + shapes.setProjectionMatrix(idt); + shapes.begin(ShapeRenderer.ShapeType.Line); { + shapes.setColor(Color.GREEN); + shapes.line(-Gdx.graphics.getWidth() / 2, 0, Gdx.graphics.getWidth() / 2, 0); + shapes.line(0, -Gdx.graphics.getHeight() / 2, 0, Gdx.graphics.getHeight() / 2); + +// shapes.setColor(Color.BLUE); +// shapes.rect(-80, -40, 160, 80); + } shapes.end(); + + shapes.identity(); + shapes.setProjectionMatrix(iso.combined); + shapes.begin(ShapeRenderer.ShapeType.Line); { + shapes.setColor(Color.RED); + shapes.line(0, 0, 8, 0); + shapes.line(0, 0, 0, 8); + + shapes.setColor(Color.WHITE); + for (int x = -160; x < 160; x += 32) { + for (int y = -80; y <= 80; y += 16) { + shapes.line(x, y, x + 32, y + 16); + shapes.line(x, y + 16, x + 32, y); + } + } + + shapes.setColor(Color.BLUE); + shapes.line(-320, 160, 320, -160); + shapes.line(-320, -160, 320, 160); + } shapes.end(); + +// vec2.set( +// Gdx.input.getX() - Gdx.graphics.getWidth() / 2, +// Gdx.graphics.getHeight() / 2 - Gdx.input.getY()); +// iso.toWorld(vec2); +// System.out.println(vec2); +// vec2.x = (int) vec2.x; +// vec2.y = (int) vec2.y; +// System.out.println(vec2); +// vec2.set(Gdx.input.getX(), Gdx.input.getY()); +// iso.unproject(vec2); +// System.out.println(vec2); + + shapes.begin(ShapeRenderer.ShapeType.Line); { + vec2.set(Gdx.input.getX(), Gdx.input.getY()); + iso.unproject(vec2); + iso.toWorld(vec2); + iso.toTile(vec2); + iso.toScreen(vec2); + + shapes.setColor(Color.SALMON); + DebugUtils.drawDiamond(shapes, vec2.x, vec2.y - Tile.SUBTILE_HEIGHT50, Tile.SUBTILE_WIDTH, Tile.SUBTILE_HEIGHT); + + shapes.setColor(Color.GREEN); + shapes.point(vec2.x, vec2.y, 0); + } shapes.end(); + + batch.begin(); + StringBuilder builder = new StringBuilder() + .append(vec2); + font.draw(batch, builder.toString(), 0, Gdx.graphics.getHeight()); + batch.end(); + } + + @Override + public void dispose() { + font.dispose(); + batch.dispose(); + shapes.dispose(); + } +}