From 36b7e0dda9dd3d76c20d242389e8d69b86c45d3b Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 2 May 2022 18:08:35 -0400 Subject: [PATCH] Update arrow graphics Although this is much better than the old version, this doesn't handle some edge cases like a very harsh diagonal. --- assets/arrow.png | Bin 0 -> 1235 bytes .../watersymbol/ArrowSpritesheet.java | 114 +++++++++ .../watersymbol/screens/GameScreen.java | 223 ++++++++++++++++-- 3 files changed, 312 insertions(+), 25 deletions(-) create mode 100644 assets/arrow.png create mode 100644 core/src/com/redstrate/watersymbol/ArrowSpritesheet.java diff --git a/assets/arrow.png b/assets/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7f8b4dc841b250d75fd7ccc113950af2fae0fa GIT binary patch literal 1235 zcmV;^1T6cBP)Px(jY&j7RCt{2T-j~pFbpM))R8SLsbNw}wuWqBNh8XSHS0qXN%4>j_yGZO*b<)( z-V+2Lq?8i8fBXOdz}M$1AR+(&T2HiC4;YP`z-U~az{_X>03c~z9!?-7mHgugWL4XX z`wnRF_4%rLe>j2FLU&_00Z_UZm%jryfzh};fu0Mr^Yt@4eg2jV(#eX#XN({rndl^Z zHbTeWMUvo7QWQQLp~m0bNpL1;36FwjTtE#j5o`#F*1$aig_H0QB$PyHKnnrFNO+#( z5E9#gJSKD}5upZMNuc)xE8ON-f-V~(;x7Ju|M*d-Q~&_*?eYB_CBX2UcH-aPKQ=nCs4WAY!br>G_(_o#PBm6Djzqo_wf93VvG8JwjGcN1sEN2M*$XuRD!(r| z4n43qLfHD!>UjzgcfggzVlfBp!sy%?ke?xs;bteTp|ci zc1D#qvgq7xPQtV^R93nQH33SO3+zmlL<=GH0RXm|ERtv;Bpwjzcv138-7jQZVv-JR z(l6v0_|uD%AH1qdea8c%5#29jj#2S|8HUFLW*u8WFgKFJE=p84(YdVtDtu7U2O67;COA0q)?vLYNfwj@a!0L$~(|A=d9)6mz2h zXBC+>Plpic;2Kaeh;a0Up8ij9rcU9v{(WW4>ihYz+5?_yl$C*Kq*abPC;9-yZYKuV zfYZ*^JYa6mTz7i>xRWOV&Sywe2&Y0y?W&h{vW2FW^9ZQ8NULO&ihgD%QcCIV@tqE> z$)|CmEHNwJ!z=>sei8W}o{*^da*u`R4p_td>|Wj*MeXN#2VkdWpF2W zh=s~FIAtF=INF3_x^iiyOg#K|DYmkda;*zAQYJI>PnTrb-q(BwB2p&ZXl1##cHoo? z6@of%YVB6il$k(2Xx+lM?u%6ed7+EzIWk88vSUT!1~b5t>E-{=?cOv3xDH}k2PSsz zdZNg*xrouV&o_qi5i&m0{5``P-1egSp0UZVPEU(Wyl002ovPDHLkV1ksxGAaN7 literal 0 HcmV?d00001 diff --git a/core/src/com/redstrate/watersymbol/ArrowSpritesheet.java b/core/src/com/redstrate/watersymbol/ArrowSpritesheet.java new file mode 100644 index 0000000..71179b2 --- /dev/null +++ b/core/src/com/redstrate/watersymbol/ArrowSpritesheet.java @@ -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]; + } +} diff --git a/core/src/com/redstrate/watersymbol/screens/GameScreen.java b/core/src/com/redstrate/watersymbol/screens/GameScreen.java index c7c20c7..1aeba73 100644 --- a/core/src/com/redstrate/watersymbol/screens/GameScreen.java +++ b/core/src/com/redstrate/watersymbol/screens/GameScreen.java @@ -17,6 +17,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.ScreenUtils; import com.redstrate.watersymbol.*; +import org.w3c.dom.Text; import java.util.ArrayList; import java.util.Collections; @@ -40,7 +41,7 @@ public class GameScreen implements Screen { Animation playerIdleAnimation; - TextureAtlas arrowAtlas; + ArrowSpritesheet arrowSpritesheet; // data for in-turn actions boolean currentlyTakingAction = false; @@ -90,7 +91,7 @@ public class GameScreen implements Screen { playerSprite = new Sprite(playerTexture); playerIdleAnimation = new Animation(0.500f, new TextureAtlas("player-idle.atlas").getRegions(), Animation.PlayMode.LOOP_PINGPONG); - arrowAtlas = new TextureAtlas("test.atlas"); + arrowSpritesheet = new ArrowSpritesheet(); 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)); for (Vector2 position : adjacentPositions) { - Vector2 newPosition = new Vector2(a.positionX + position.x, a.positionY + position.y); - if(b.positionX == newPosition.x && b.positionY == newPosition.y) + int newX = a.positionX + (int)position.x; + int newY = a.positionY + (int)position.y; + + if(b.positionX == newX && b.positionY == newY) return true; } @@ -250,6 +253,52 @@ public class GameScreen implements Screen { } 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 public void render(float delta) { @@ -300,55 +349,179 @@ public class GameScreen implements Screen { int newFixedY = (int) (newY / 16.0); ArrayList 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); List 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 - for (int i = 1; i < realPath.size(); i++) { - Vector2 previousPosition = realPath.get(Math.max(i - 1, 0)); + for (int i = 1; i < realPath.size() - 1; i++) { + Vector2 previousPosition = realPath.get(i - 1); 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 leftSprite = null; + TextureRegion rightSprite = null; - // going down - if (d.epsilonEquals(new Vector2(0, -1))) { - spriteRegion = arrowAtlas.findRegion("down"); + // TODO: condense duplicate branches + + // handle straights + if(entrance == Direction.Bottom && exit == Direction.Top) { + spriteRegion = arrowSpritesheet.getUpDown(); } - if (d.epsilonEquals(new Vector2(0, 1))) { - spriteRegion = arrowAtlas.findRegion("up"); + if(entrance == Direction.Top && exit == Direction.Bottom) { + spriteRegion = arrowSpritesheet.getUpDown(); } - if (d.epsilonEquals(new Vector2(-1, 0))) { - spriteRegion = arrowAtlas.findRegion("right"); + if(entrance == Direction.Left && exit == Direction.Right) { + spriteRegion = arrowSpritesheet.getLeftRight(); } - if (d.epsilonEquals(new Vector2(1, 0))) { - spriteRegion = arrowAtlas.findRegion("left"); + if(entrance == Direction.Right && exit == Direction.Left) { + spriteRegion = arrowSpritesheet.getLeftRight(); } - if (d.epsilonEquals(new Vector2(1, 1))) { - spriteRegion = arrowAtlas.findRegion("cross-up"); + // handle crosses + if(entrance == Direction.TopLeft && exit == Direction.BottomRight) { + spriteRegion = arrowSpritesheet.getDiagDown(); } - if (d.epsilonEquals(new Vector2(-1, -1))) { - spriteRegion = arrowAtlas.findRegion("cross-up"); + if(entrance == Direction.TopLeft && exit == Direction.TopLeft) { + spriteRegion = arrowSpritesheet.getDiagDown(); } - if (d.epsilonEquals(new Vector2(1, -1))) { - spriteRegion = arrowAtlas.findRegion("cross-down"); + if(entrance == Direction.BottomLeft && exit == Direction.BottomLeft) { + spriteRegion = arrowSpritesheet.getDiagUp(); } - if (d.epsilonEquals(new Vector2(-1, 1))) { - spriteRegion = arrowAtlas.findRegion("cross-down"); + if(entrance == Direction.BottomLeft && exit == Direction.TopRight) { + 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) { 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) {