Skip to content

Commit

Permalink
[#200] implement isometric positioning
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbrain committed Aug 18, 2019
1 parent 50d6f0b commit cbbffd9
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import de.bitbrain.braingdx.ai.pathfinding.heuristics.AStarHeuristic;
import de.bitbrain.braingdx.ai.pathfinding.heuristics.ClosestHeuristic;
import de.bitbrain.braingdx.tmx.IndexCalculator;
import de.bitbrain.braingdx.tmx.ZIndexCalculator;
import de.bitbrain.braingdx.tmx.TiledMapContext;
import de.bitbrain.braingdx.world.GameObject;

Expand Down Expand Up @@ -87,8 +87,8 @@ public void refresh() {
public Path findPath(GameObject mover, int tx, int ty) {


int sx = IndexCalculator.calculateIndex(mover.getLeft(), context.getCellWidth());
int sy = IndexCalculator.calculateIndex(mover.getTop(), context.getCellHeight());
int sx = context.getPositionTranslator().toIndexX(mover.getLeft());
int sy = context.getPositionTranslator().toIndexY(mover.getTop());

// easy first check, if the destination is blocked, we can't get there
if (context.isExclusiveCollision(tx, ty, context.layerIndexOf(mover), mover)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

class CollisionCalculator {

public static void updateCollision(GameObject gameObject, boolean collision, float x, float y, int currentLayerIndex, State state) {
int tileX = IndexCalculator.calculateIndex(x, state.getCellWidth());
int tileY = IndexCalculator.calculateIndex(y, state.getCellWidth());
public static void updateCollision(PositionTranslator positionTranslator, GameObject gameObject, boolean collision, float x, float y, int currentLayerIndex, State state) {
int tileX = positionTranslator.toIndexX(x);
int tileY = positionTranslator.toIndexY(y);
updateCollision(gameObject, collision, tileX, tileY, currentLayerIndex, state);
}

Expand Down
68 changes: 46 additions & 22 deletions 2d/src/main/java/de/bitbrain/braingdx/tmx/GameObjectUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import de.bitbrain.braingdx.util.Factory;
import de.bitbrain.braingdx.world.GameObject;

import static de.bitbrain.braingdx.tmx.IndexCalculator.calculateIndex;

/**
* This component updates game objects which are part of the tiledmap lifecycle.
*
Expand All @@ -37,18 +35,35 @@ class GameObjectUpdater extends BehaviorAdapter {

private static final String FALSE = "false";

private class IndexFactory implements Factory<Integer> {
private class IndexXFactory implements Factory<Integer> {

float value;

private final PositionTranslator positionTranslator;

public IndexXFactory(PositionTranslator positionTranslator) {
this.positionTranslator = positionTranslator;
}

@Override
public Integer create() {
return positionTranslator.toIndexX(value);
}
}

private class IndexYFactory implements Factory<Integer> {

float value;
float cellSize;

public IndexFactory() {
private final PositionTranslator positionTranslator;

public IndexYFactory(PositionTranslator positionTranslator) {
this.positionTranslator = positionTranslator;
}

@Override
public Integer create() {
return calculateIndex(value, cellSize);
return positionTranslator.toIndexY(value);
}
}

Expand All @@ -62,7 +77,9 @@ public Integer create() {
}
}

private final IndexFactory indexFactory = new IndexFactory();
private final IndexXFactory indexXFactory;

private final IndexYFactory indexYFactory;

private final LayerIndexFactory layerIndexFactory = new LayerIndexFactory();

Expand All @@ -74,10 +91,19 @@ public Integer create() {

private final GameEventManager gameEventManager;

public GameObjectUpdater(TiledMapContext context, State state, GameEventManager gameEventManager) {
private final PositionTranslator positionTranslator;

public GameObjectUpdater(
TiledMapContext context,
State state,
GameEventManager gameEventManager,
PositionTranslator positionTranslator) {
this.context = context;
this.state = state;
this.gameEventManager = gameEventManager;
this.positionTranslator = positionTranslator;
this.indexXFactory = new IndexXFactory(positionTranslator);
this.indexYFactory = new IndexYFactory(positionTranslator);
}

@Override
Expand All @@ -94,7 +120,7 @@ public void update(GameObject object, float delta) {

private void updateZIndex(GameObject object) {
int currentLayerIndex = context.layerIndexOf(object);
object.setZIndex(IndexCalculator.calculateZIndex(object, context, currentLayerIndex));
object.setZIndex(ZIndexCalculator.calculateZIndex(object, context, positionTranslator, currentLayerIndex));
}

private void updateCollision(GameObject object) {
Expand Down Expand Up @@ -124,12 +150,10 @@ private void updateCollision(GameObject object) {
Gdx.app.debug("TiledMapAPI", "Updating collision of " + object);
}
// Object has moved, now check if last position is already occupied
indexFactory.value = lastPosition.x;
indexFactory.cellSize = context.getCellWidth();
int lastTileX = object.getOrSetAttribute(Constants.LAST_TILE_X, indexFactory);
indexFactory.value = lastPosition.y;
indexFactory.cellSize = context.getCellHeight();
int lastTileY = object.getOrSetAttribute(Constants.LAST_TILE_Y, indexFactory);
indexXFactory.value = lastPosition.x;
int lastTileX = object.getOrSetAttribute(Constants.LAST_TILE_X, indexXFactory);
indexYFactory.value = lastPosition.y;
int lastTileY = object.getOrSetAttribute(Constants.LAST_TILE_Y, indexYFactory);
GameObject occupant = context.getGameObjectAt(lastTileX, lastTileY, lastLayerIndex);

// clear last collision
Expand All @@ -147,10 +171,10 @@ private void updateCollision(GameObject object) {
// Update current collision
if (!object.equals(occupant) && object.isActive()) {
if (!context.isExclusiveCollision(object.getLeft(), object.getTop(), currentLayerIndex, object)) {
CollisionCalculator.updateCollision(object, true, object.getLeft(), object.getTop(), currentLayerIndex, state);
CollisionCalculator.updateCollision(positionTranslator, object, true, object.getLeft(), object.getTop(), currentLayerIndex, state);
}
int tileX = calculateIndex(object.getLeft(), state.getCellWidth());
int tileY = calculateIndex(object.getTop(), state.getCellWidth());
int tileX = positionTranslator.toIndexX(object.getLeft());
int tileY = positionTranslator.toIndexY(object.getTop());
for (int xIndex = tileX; xIndex < tileX + getObjectIndexWidth(object); ++xIndex) {
for (int yIndex = tileY; yIndex < tileY + getObjectIndexHeight(object); ++yIndex) {
if (!context.isExclusiveCollision(xIndex, yIndex, currentLayerIndex, object)) {
Expand All @@ -171,12 +195,12 @@ private void updateCollision(GameObject object) {

}
if (!currentPosition.equals(lastPosition)) {
int xIndex = calculateIndex(currentPosition.x, context.getCellWidth());
int yIndex = calculateIndex(currentPosition.y, context.getCellHeight());
int xIndex = positionTranslator.toIndexX(currentPosition.x);
int yIndex = positionTranslator.toIndexY(currentPosition.y);
gameEventManager.publish(new TiledMapEvents.OnEnterCellEvent(xIndex, yIndex, object, context));
}
object.setAttribute(Constants.LAST_TILE_X, calculateIndex(object.getLeft(), context.getCellWidth()));
object.setAttribute(Constants.LAST_TILE_Y, calculateIndex(object.getTop(), context.getCellHeight()));
object.setAttribute(Constants.LAST_TILE_X, positionTranslator.toIndexX(object.getLeft()));
object.setAttribute(Constants.LAST_TILE_Y, positionTranslator.toIndexY(object.getTop()));
object.setAttribute(Constants.LAST_LAYER_INDEX, context.layerIndexOf(object));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package de.bitbrain.braingdx.tmx;

import com.badlogic.gdx.math.Vector2;

public class IsometricPositionTranslator implements PositionTranslator {

private final State state;
private final Vector2 xAxis, yAxis;

public IsometricPositionTranslator(State state) {
this.state = state;
this.xAxis = new Vector2();
this.yAxis = new Vector2();
}

@Override
public float toWorldX(int indexX) {
return toWorldX(indexX * state.getCellWidth());
}

@Override
public float toWorldY(int indexY) {
return toWorldY(indexY * state.getCellHeight());
}

@Override
public float toWorldX(float mapX) {
return toWorld(mapX, 0f).x;
}

@Override
public float toWorldY(float mapY) {
return toWorld(0f, mapY).y;
}

@Override
public Vector2 toWorld(float x, float y) {
xAxis.set(state.getCellWidth() / 2f, -state.getCellHeight() / 2f);
yAxis.set(state.getCellWidth() / 2f, state.getCellHeight() / 2f);
float scalar = yAxis.len() / state.getCellHeight();
return xAxis.nor().scl(x).scl(scalar)
.add(yAxis.nor().scl(y).scl(scalar))
.add(0f, state.getCellHeight() / 2f);
}

@Override
public float toMapX(float worldX) {
return worldX;
}

@Override
public float toMapY(float worldY) {
return worldY;
}

@Override
public int toIndexX(float worldX) {
float mapX = toMapX(worldX);
return (int) Math.floor(mapX / state.getCellWidth());
}

@Override
public int toIndexY(float worldY) {
float mapY = toMapY(worldY);
return (int) Math.floor(mapY / state.getCellHeight());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package de.bitbrain.braingdx.tmx;

import com.badlogic.gdx.math.Vector2;

public class OrthogonalPositionTranslator implements PositionTranslator {

private final State state;

public OrthogonalPositionTranslator(State state) {
this.state = state;
}

@Override
public float toWorldX(int indexX) {
return (float) Math.floor(indexX * state.getCellWidth());
}

@Override
public float toWorldY(int indexY) {
return (float) Math.floor(indexY * state.getCellHeight());
}

@Override
public float toWorldX(float mapX) {
return mapX;
}

@Override
public float toWorldY(float mapY) {
return mapY;
}

@Override
public Vector2 toWorld(float x, float y) {
return new Vector2(x, y);
}

@Override
public float toMapX(float worldX) {
return worldX;
}

@Override
public float toMapY(float worldY) {
return worldY;
}

@Override
public int toIndexX(float worldX) {
return calculateIndex(worldX, state.getCellWidth());
}

@Override
public int toIndexY(float worldY) {
return calculateIndex(worldY, state.getCellHeight());
}

private static int calculateIndex(float value, float cellSize) {
return (int) Math.round(Math.floor(value / cellSize));
}
}
28 changes: 28 additions & 0 deletions 2d/src/main/java/de/bitbrain/braingdx/tmx/PositionTranslator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package de.bitbrain.braingdx.tmx;

import com.badlogic.gdx.math.Vector2;

/**
* Translates positions depending on the current map orientation
*/
public interface PositionTranslator {

float toWorldX(int indexX);

float toWorldY(int indexY);

float toWorldX(float mapX);

float toWorldY(float mapY);

Vector2 toWorld(float x, float y);

float toMapX(float worldX);

float toMapY(float worldY);

int toIndexX(float worldX);

int toIndexY(float worldY);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package de.bitbrain.braingdx.tmx;

interface PositionTranslatorFactory {
PositionTranslator create(State state);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public interface TiledMapContext extends TiledCollisionResolver, Disposable {

MapProperties getPropertiesAt(int tileX, int tileY, int layer);

PositionTranslator getPositionTranslator();

float getCellWidth();

float getCellHeight();
Expand Down
Loading

0 comments on commit cbbffd9

Please sign in to comment.