1
Fork 0

Update arrow graphics

Although this is much better than the old version, this doesn't handle
some edge cases like a very harsh diagonal.
This commit is contained in:
Joshua Goins 2022-05-02 18:08:35 -04:00
parent a55410c122
commit 36b7e0dda9
3 changed files with 312 additions and 25 deletions

BIN
assets/arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,114 @@
package com.redstrate.watersymbol;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class ArrowSpritesheet {
private static final int ATLAS_COLUMNS = 3, ATLAS_ROWS = 9;
TextureRegion[][] regions;
Texture texture;
public ArrowSpritesheet() {
texture = new Texture("arrow.png");
regions = TextureRegion.split(texture,
texture.getWidth() / ATLAS_COLUMNS,
texture.getHeight() / ATLAS_ROWS);
}
// straights
public TextureRegion getUpDown() {
return regions[0][1];
}
public TextureRegion getLeftRight() {
return regions[0][2];
}
// diagonals
public TextureRegion getDiagUp() {
return regions[1][0];
}
public TextureRegion getDiagDown() {
return regions[1][1];
}
// corners
public TextureRegion getCornerTopRight() {
return regions[1][2];
}
public TextureRegion getCornerBottomRight() {
return regions[3][1];
}
public TextureRegion getCornerTopLeft() {
return regions[3][2];
}
public TextureRegion getCornerBottomLeft() {
return regions[2][0];
}
// bends
public TextureRegion getBendTopLeftToBottom() {
return regions[2][2];
}
public TextureRegion getBendBottomLeftToTop() {
return regions[4][0];
}
public TextureRegion getBendBottomRightToTop() {
return regions[5][0];
}
public TextureRegion getBendBottomLeftToRight() {
return regions[3][0];
}
public TextureRegion getBendTopLeftToRight() {
return regions[4][2];
}
public TextureRegion getBendTopRightToBottom() {
return regions[5][1];
}
// arrows
public TextureRegion getArrowFromLeft() {
return regions[5][2];
}
public TextureRegion getArrowFromTop() {
return regions[6][0];
}
public TextureRegion getArrowFromRight() {
return regions[6][1];
}
public TextureRegion getArrowFromBottom() {
return regions[6][2];
}
public TextureRegion getArrowFromTopLeft() {
return regions[7][0];
}
public TextureRegion getArrowFromBottomLeft() {
return regions[7][1];
}
public TextureRegion getArrowFromTopRight() {
return regions[7][2];
}
public TextureRegion getArrowFromBottomRight() {
return regions[8][0];
}
}

View file

@ -17,6 +17,7 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.ScreenUtils; import com.badlogic.gdx.utils.ScreenUtils;
import com.redstrate.watersymbol.*; import com.redstrate.watersymbol.*;
import org.w3c.dom.Text;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -40,7 +41,7 @@ public class GameScreen implements Screen {
Animation<TextureRegion> playerIdleAnimation; Animation<TextureRegion> playerIdleAnimation;
TextureAtlas arrowAtlas; ArrowSpritesheet arrowSpritesheet;
// data for in-turn actions // data for in-turn actions
boolean currentlyTakingAction = false; boolean currentlyTakingAction = false;
@ -90,7 +91,7 @@ public class GameScreen implements Screen {
playerSprite = new Sprite(playerTexture); playerSprite = new Sprite(playerTexture);
playerIdleAnimation = new Animation<TextureRegion>(0.500f, new TextureAtlas("player-idle.atlas").getRegions(), Animation.PlayMode.LOOP_PINGPONG); playerIdleAnimation = new Animation<TextureRegion>(0.500f, new TextureAtlas("player-idle.atlas").getRegions(), Animation.PlayMode.LOOP_PINGPONG);
arrowAtlas = new TextureAtlas("test.atlas"); arrowSpritesheet = new ArrowSpritesheet();
startNewTeamTurn(Unit.Team.Player); startNewTeamTurn(Unit.Team.Player);
} }
@ -189,8 +190,10 @@ public class GameScreen implements Screen {
adjacentPositions.add(new Vector2(1, -1)); adjacentPositions.add(new Vector2(1, -1));
adjacentPositions.add(new Vector2(1, 1)); adjacentPositions.add(new Vector2(1, 1));
for (Vector2 position : adjacentPositions) { for (Vector2 position : adjacentPositions) {
Vector2 newPosition = new Vector2(a.positionX + position.x, a.positionY + position.y); int newX = a.positionX + (int)position.x;
if(b.positionX == newPosition.x && b.positionY == newPosition.y) int newY = a.positionY + (int)position.y;
if(b.positionX == newX && b.positionY == newY)
return true; return true;
} }
@ -250,6 +253,52 @@ public class GameScreen implements Screen {
} }
private float stateTime = 0.0f; private float stateTime = 0.0f;
enum Direction {
Top,
Bottom,
Left,
Right,
TopLeft,
TopRight,
BottomLeft,
BottomRight
};
Direction getFromDelta(Vector2 d) {
if (d.epsilonEquals(new Vector2(0, -1))) {
return Direction.Top;
}
if (d.epsilonEquals(new Vector2(0, 1))) {
return Direction.Bottom;
}
if (d.epsilonEquals(new Vector2(-1, 0))) {
return Direction.Right;
}
if (d.epsilonEquals(new Vector2(1, 0))) {
return Direction.Left;
}
if (d.epsilonEquals(new Vector2(1, 1))) {
return Direction.BottomLeft;
}
if (d.epsilonEquals(new Vector2(-1, -1))) {
return Direction.TopRight;
}
if (d.epsilonEquals(new Vector2(1, -1))) {
return Direction.TopLeft;
}
if (d.epsilonEquals(new Vector2(-1, 1))) {
return Direction.BottomRight;
}
throw new RuntimeException("Failed to find direction!");
}
@Override @Override
public void render(float delta) { public void render(float delta) {
@ -300,55 +349,179 @@ public class GameScreen implements Screen {
int newFixedY = (int) (newY / 16.0); int newFixedY = (int) (newY / 16.0);
ArrayList<Vector2> path = AStar.path(new Vector2(currentUnit.positionX, currentUnit.positionY), new Vector2((float) newFixedX, (float) newFixedY), getCollision(), tiledMap); ArrayList<Vector2> path = AStar.path(new Vector2(currentUnit.positionX, currentUnit.positionY), new Vector2((float) newFixedX, (float) newFixedY), getCollision(), tiledMap);
if (path != null) { if (path != null && path.size() > 1) {
Collections.reverse(path); Collections.reverse(path);
List<Vector2> realPath = path.subList(0, Math.min(currentUnit.maxDistance, path.size())); List<Vector2> realPath = path.subList(0, Math.min(currentUnit.maxDistance, path.size()));
// we start at index 1 since there's no point in drawing an arrow over the player // we start at index 1 since there's no point in drawing an arrow over the player
for (int i = 1; i < realPath.size(); i++) { for (int i = 1; i < realPath.size() - 1; i++) {
Vector2 previousPosition = realPath.get(Math.max(i - 1, 0)); Vector2 previousPosition = realPath.get(i - 1);
Vector2 newPosition = realPath.get(i); Vector2 newPosition = realPath.get(i);
Vector2 nextPosition = realPath.get(i + 1);
Vector2 d = new Vector2(newPosition.x - previousPosition.x, newPosition.y - previousPosition.y); // we want to grab two directions, first is our "entrance" and then our "exit". of course arrows that are just a position don't exist
Direction entrance = getFromDelta(new Vector2(newPosition.x - previousPosition.x, newPosition.y - previousPosition.y));
Direction exit = getFromDelta(new Vector2(newPosition.x - nextPosition.x, newPosition.y - nextPosition.y));
TextureRegion spriteRegion = null; TextureRegion spriteRegion = null;
TextureRegion leftSprite = null;
TextureRegion rightSprite = null;
// going down // TODO: condense duplicate branches
if (d.epsilonEquals(new Vector2(0, -1))) {
spriteRegion = arrowAtlas.findRegion("down"); // handle straights
if(entrance == Direction.Bottom && exit == Direction.Top) {
spriteRegion = arrowSpritesheet.getUpDown();
} }
if (d.epsilonEquals(new Vector2(0, 1))) { if(entrance == Direction.Top && exit == Direction.Bottom) {
spriteRegion = arrowAtlas.findRegion("up"); spriteRegion = arrowSpritesheet.getUpDown();
} }
if (d.epsilonEquals(new Vector2(-1, 0))) { if(entrance == Direction.Left && exit == Direction.Right) {
spriteRegion = arrowAtlas.findRegion("right"); spriteRegion = arrowSpritesheet.getLeftRight();
} }
if (d.epsilonEquals(new Vector2(1, 0))) { if(entrance == Direction.Right && exit == Direction.Left) {
spriteRegion = arrowAtlas.findRegion("left"); spriteRegion = arrowSpritesheet.getLeftRight();
} }
if (d.epsilonEquals(new Vector2(1, 1))) { // handle crosses
spriteRegion = arrowAtlas.findRegion("cross-up"); if(entrance == Direction.TopLeft && exit == Direction.BottomRight) {
spriteRegion = arrowSpritesheet.getDiagDown();
} }
if (d.epsilonEquals(new Vector2(-1, -1))) { if(entrance == Direction.TopLeft && exit == Direction.TopLeft) {
spriteRegion = arrowAtlas.findRegion("cross-up"); spriteRegion = arrowSpritesheet.getDiagDown();
} }
if (d.epsilonEquals(new Vector2(1, -1))) { if(entrance == Direction.BottomLeft && exit == Direction.BottomLeft) {
spriteRegion = arrowAtlas.findRegion("cross-down"); spriteRegion = arrowSpritesheet.getDiagUp();
} }
if (d.epsilonEquals(new Vector2(-1, 1))) { if(entrance == Direction.BottomLeft && exit == Direction.TopRight) {
spriteRegion = arrowAtlas.findRegion("cross-down"); spriteRegion = arrowSpritesheet.getDiagUp();
} }
if(entrance == Direction.BottomRight && exit == Direction.TopLeft) {
spriteRegion = arrowSpritesheet.getDiagDown();
}
if(entrance == Direction.TopRight && exit == Direction.BottomLeft) {
spriteRegion = arrowSpritesheet.getDiagDown();
}
if(spriteRegion == arrowSpritesheet.getDiagDown()) {
leftSprite = arrowSpritesheet.getCornerTopRight();
rightSprite = arrowSpritesheet.getCornerBottomLeft();
}
if(spriteRegion == arrowSpritesheet.getDiagUp()) {
leftSprite = arrowSpritesheet.getCornerBottomRight();
rightSprite = arrowSpritesheet.getCornerTopLeft();
}
// handle bends
if(entrance == Direction.BottomRight && exit == Direction.Top) {
spriteRegion = arrowSpritesheet.getBendBottomRightToTop();
}
if(entrance == Direction.Top && exit == Direction.BottomRight) {
spriteRegion = arrowSpritesheet.getBendBottomRightToTop();
}
if(entrance == Direction.BottomLeft && exit == Direction.Top) {
spriteRegion = arrowSpritesheet.getBendBottomLeftToTop();
}
if(entrance == Direction.Top && exit == Direction.BottomLeft) {
spriteRegion = arrowSpritesheet.getBendBottomLeftToTop();
}
if(entrance == Direction.TopLeft && exit == Direction.Bottom) {
spriteRegion = arrowSpritesheet.getBendTopLeftToBottom();
}
if(entrance == Direction.Bottom && exit == Direction.TopLeft) {
spriteRegion = arrowSpritesheet.getBendTopLeftToBottom();
}
if(entrance == Direction.TopRight && exit == Direction.Bottom) {
spriteRegion = arrowSpritesheet.getBendTopRightToBottom();
}
if(entrance == Direction.Bottom && exit == Direction.TopRight) {
spriteRegion = arrowSpritesheet.getBendTopRightToBottom();
}
if(entrance == Direction.TopLeft && exit == Direction.Right) {
spriteRegion = arrowSpritesheet.getBendTopLeftToRight();
}
if(entrance == Direction.Right && exit == Direction.TopLeft) {
spriteRegion = arrowSpritesheet.getBendTopLeftToRight();
}
if(entrance == Direction.BottomLeft && exit == Direction.Right) {
spriteRegion = arrowSpritesheet.getBendBottomLeftToRight();
}
if(entrance == Direction.Right && exit == Direction.BottomLeft) {
spriteRegion = arrowSpritesheet.getBendBottomLeftToRight();
}
game.font.draw(game.batch, entrance.toString() + " to " + exit.toString(), newPosition.x * 16, newPosition.y * 16);
if (spriteRegion != null) { if (spriteRegion != null) {
game.batch.draw(spriteRegion, newPosition.x * 16, newPosition.y * 16); game.batch.draw(spriteRegion, newPosition.x * 16, newPosition.y * 16);
} }
if(leftSprite != null) {
game.batch.draw(leftSprite, (newPosition.x - 1) * 16, newPosition.y * 16);
}
if(rightSprite != null) {
game.batch.draw(rightSprite, (newPosition.x + 1) * 16, newPosition.y * 16);
}
}
// now we want to draw the arrow or the "end" point.
Vector2 secondToLastPosition = realPath.get(realPath.size() - 2);
Vector2 lastPosition = realPath.get(realPath.size() - 1);
Direction exit = getFromDelta(new Vector2(lastPosition.x - secondToLastPosition.x, lastPosition.y - secondToLastPosition.y));
TextureRegion spriteRegion = null;
switch(exit) {
case Top:
spriteRegion = arrowSpritesheet.getArrowFromTop();
break;
case Bottom:
spriteRegion = arrowSpritesheet.getArrowFromBottom();
break;
case Left:
spriteRegion = arrowSpritesheet.getArrowFromLeft();
break;
case Right:
spriteRegion = arrowSpritesheet.getArrowFromRight();
break;
case TopLeft:
spriteRegion = arrowSpritesheet.getArrowFromTopLeft();
break;
case TopRight:
spriteRegion = arrowSpritesheet.getArrowFromTopRight();
break;
case BottomLeft:
spriteRegion = arrowSpritesheet.getArrowFromBottomLeft();
break;
case BottomRight:
spriteRegion = arrowSpritesheet.getArrowFromBottomRight();
break;
}
if(spriteRegion != null) {
game.batch.draw(spriteRegion, lastPosition.x * 16, lastPosition.y * 16);
} }
} }
} else if (hasStartedMoving) { } else if (hasStartedMoving) {