diff --git a/src/main/java/inf112/fiasko/roborally/GameLauncher.java b/src/main/java/inf112/fiasko/roborally/GameLauncher.java index 169605e..f26f580 100644 --- a/src/main/java/inf112/fiasko/roborally/GameLauncher.java +++ b/src/main/java/inf112/fiasko/roborally/GameLauncher.java @@ -7,10 +7,12 @@ import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import inf112.fiasko.roborally.element_properties.GameTexture; import inf112.fiasko.roborally.game.Game; import inf112.fiasko.roborally.game.IDrawableGame; import inf112.fiasko.roborally.objects.IDrawableObject; +import inf112.fiasko.roborally.utility.IOUtil; + +import java.util.List; /** * This class renders a game using libgdx @@ -23,6 +25,8 @@ public class GameLauncher extends ApplicationAdapter { private Texture robotTexture; private Texture textureSheet; + private final int tileDimensions = 64; + @Override public void create() { //Loads some textures @@ -31,8 +35,11 @@ public class GameLauncher extends ApplicationAdapter { game = new Game(); camera = new OrthographicCamera(); - camera.setToOrtho(false, game.getWidth(), game.getHeight()); + camera.setToOrtho(false, game.getWidth() * tileDimensions, + game.getHeight() * tileDimensions); batch = new SpriteBatch(); + /*MyTextInputListener listener = new MyTextInputListener(); + Gdx.input.getTextInput(listener, "Input name", "", "Name");*/ } /** @@ -45,8 +52,12 @@ public class GameLauncher extends ApplicationAdapter { batch.setProjectionMatrix(camera.combined); batch.begin(); //Draws all elements the game wants to draw - for (IDrawableObject object : game.getObjectsToDraw()) { - TextureRegion objectTextureRegion = gameTextureToTextureRegion(object.getTexture()); + List elementsToDraw = IOUtil.getDrawableObjectsFromGame(game, tileDimensions, tileDimensions); + for (IDrawableObject object : elementsToDraw) { + TextureRegion objectTextureRegion = object.getTexture(); + /*System.out.println(object.getTexture() + " " + object.getXPosition() + " " + object.getYPosition() + " " + object.getWidth() + " " + + object.getHeight() + " " + object.getRotation() + " " + objectTextureRegion.getRegionX() + " " + + objectTextureRegion.getRegionY() + " " + objectTextureRegion.getRegionWidth() + " " + objectTextureRegion.getRegionHeight());*/ batch.draw(objectTextureRegion.getTexture(), object.getXPosition(), object.getYPosition(), (float)object.getWidth()/2, (float)object.getHeight()/2, object.getWidth(), object.getHeight(), 1, 1, object.getRotation(), @@ -64,22 +75,14 @@ public class GameLauncher extends ApplicationAdapter { batch.dispose(); } - /** - * Turns a GameTexture element into a TextureRegion element - * - * This is necessary to keep all libgdx logic in this class only. Otherwise, testing would be painful. - * - * @param gameTexture A GameTexture enum - * @return A Gdx TextureRegion - */ - private TextureRegion gameTextureToTextureRegion(GameTexture gameTexture) { - switch (gameTexture) { - case ROBOT: - return new TextureRegion(robotTexture, 0, 0, 64, 64); - case TILE: - return new TextureRegion(textureSheet, 4*300, 0, 300, 300); - default: - throw new IllegalArgumentException("Non existing texture encountered."); + /*public static class MyTextInputListener implements Input.TextInputListener { + @Override + public void input (String text) { + System.out.println(text); } - } + + @Override + public void canceled () { + } + }*/ } \ No newline at end of file diff --git a/src/main/java/inf112/fiasko/roborally/element_properties/GameTexture.java b/src/main/java/inf112/fiasko/roborally/element_properties/GameTexture.java deleted file mode 100644 index 83b0505..0000000 --- a/src/main/java/inf112/fiasko/roborally/element_properties/GameTexture.java +++ /dev/null @@ -1,9 +0,0 @@ -package inf112.fiasko.roborally.element_properties; - -/** - * This enum represents a drawable texture - */ -public enum GameTexture { - ROBOT, - TILE -} diff --git a/src/main/java/inf112/fiasko/roborally/game/Game.java b/src/main/java/inf112/fiasko/roborally/game/Game.java index 6f310e9..132cbc2 100644 --- a/src/main/java/inf112/fiasko/roborally/game/Game.java +++ b/src/main/java/inf112/fiasko/roborally/game/Game.java @@ -1,53 +1,77 @@ package inf112.fiasko.roborally.game; -import inf112.fiasko.roborally.element_properties.GameTexture; +import inf112.fiasko.roborally.element_properties.Direction; +import inf112.fiasko.roborally.element_properties.Position; +import inf112.fiasko.roborally.element_properties.RobotID; import inf112.fiasko.roborally.objects.Board; -import inf112.fiasko.roborally.objects.DrawableObject; -import inf112.fiasko.roborally.objects.IDrawableObject; import inf112.fiasko.roborally.objects.Robot; +import inf112.fiasko.roborally.objects.Tile; +import inf112.fiasko.roborally.objects.Wall; import inf112.fiasko.roborally.utility.BoardLoaderUtil; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; /** * This class represent a game which is drawable using libgdx */ public class Game implements IDrawableGame { - private final int TILE_SIZE = 64; private Board gameBoard; public Game() { try { List robots = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(1, 1))); gameBoard = BoardLoaderUtil.loadBoard("boards/Checkmate.txt", robots); + new Thread(() -> { + try { + runGameLoop(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); } catch (IOException e) { e.printStackTrace(); } } + private void runGameLoop() throws InterruptedException { + TimeUnit.SECONDS.sleep(10); + gameBoard.moveRobot(RobotID.ROBOT_1, Direction.NORTH); + TimeUnit.SECONDS.sleep(1); + gameBoard.moveRobot(RobotID.ROBOT_1, Direction.EAST); + TimeUnit.SECONDS.sleep(1); + gameBoard.moveRobot(RobotID.ROBOT_1, Direction.NORTH); + TimeUnit.SECONDS.sleep(1); + gameBoard.moveRobot(RobotID.ROBOT_1, Direction.WEST); + TimeUnit.SECONDS.sleep(1); + gameBoard.moveRobot(RobotID.ROBOT_1, Direction.WEST); + } + @Override public int getWidth() { - return gameBoard.getBoardWidth() * TILE_SIZE; + return gameBoard.getBoardWidth(); } @Override public int getHeight() { - return gameBoard.getBoardHeight() * TILE_SIZE; + return gameBoard.getBoardHeight(); } @Override - public List getObjectsToDraw() { - List list = new ArrayList<>(); - for (int i = 0; i < gameBoard.getBoardWidth(); i++) { - for (int j = 0; j < gameBoard.getBoardHeight(); j++) { - DrawableObject tile = new DrawableObject(GameTexture.TILE, i * TILE_SIZE, j * TILE_SIZE); - list.add(tile); - } - } - DrawableObject robot = new DrawableObject(GameTexture.ROBOT, TILE_SIZE, TILE_SIZE); - list.add(robot); - return list; + public List getTilesToDraw() { + return gameBoard.getTiles(); + } + + @Override + public List getWallsToDraw() { + return gameBoard.getWalls(); + } + + @Override + public List getRobotsToDraw() { + return gameBoard.getAliveRobots(); } } diff --git a/src/main/java/inf112/fiasko/roborally/game/IDrawableGame.java b/src/main/java/inf112/fiasko/roborally/game/IDrawableGame.java index 5a1ec89..ac25ae3 100644 --- a/src/main/java/inf112/fiasko/roborally/game/IDrawableGame.java +++ b/src/main/java/inf112/fiasko/roborally/game/IDrawableGame.java @@ -1,6 +1,8 @@ package inf112.fiasko.roborally.game; -import inf112.fiasko.roborally.objects.IDrawableObject; +import inf112.fiasko.roborally.objects.Robot; +import inf112.fiasko.roborally.objects.Tile; +import inf112.fiasko.roborally.objects.Wall; import java.util.List; @@ -10,21 +12,41 @@ import java.util.List; public interface IDrawableGame { /** - * Gets the screen width of the game + * Gets the number of tiles in the x direction * @return A positive integer */ int getWidth(); /** - * Gets the screen height of the game + * Gets the number of tiles in the y direction * @return A positive integer */ int getHeight(); /** - * Gets a list of objects which are to be drawn - * @return A list of drawable objects in the order they are to be drawn + * Gets a list of all the tiles to be drawn + * + * Should return a list readable from top-left to top-right and so on. In other words, the first getWidth() tiles + * should be drawn on the top row from left to right. + * + * @return A list of tiles */ - List getObjectsToDraw(); + List getTilesToDraw(); + + /** + * Gets a list of all the walls to be drawn + * + * Should return a list readable from top-left to top-right and so on. In other words, the first getWidth() walls + * should be drawn on the top row from left to right. + * + * @return A list of walls + */ + List getWallsToDraw(); + + /** + * Gets a list of all robots to draw + * @return A list of all robots to draw + */ + List getRobotsToDraw(); } diff --git a/src/main/java/inf112/fiasko/roborally/objects/Board.java b/src/main/java/inf112/fiasko/roborally/objects/Board.java index 48049a5..79a36a1 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Board.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Board.java @@ -81,6 +81,22 @@ public class Board { return new ArrayList<>(robots.values()); } + /** + * Gets all the tiles from the board + * @return A list of all tiles on the board + */ + public List getTiles() { + return getAllElementsFromGrid(tiles); + } + + /** + * Gets all the walls from the board + * @return A list of all the walls on the board + */ + public List getWalls() { + return getAllElementsFromGrid(walls); + } + /** * Removes a dead robot from the board over to the dead robot list * @param robot the dead robot @@ -265,4 +281,20 @@ public class Board { throw new IllegalArgumentException("It's not possible to move in that direction."); } } + + /** + * Gets all elements on a grid + * @param grid The grid to get elements from + * @param The type of the elements int the grid + * @return A list containing all the elements in the grid + */ + private List getAllElementsFromGrid(IGrid grid) { + List elements = new ArrayList<>(); + for (int x = grid.getWidth() - 1; x >= 0; x--) { + for (int y = 0; y < grid.getHeight(); y++) { + elements.add(grid.getElement(x, y)); + } + } + return elements; + } } diff --git a/src/main/java/inf112/fiasko/roborally/objects/DrawableObject.java b/src/main/java/inf112/fiasko/roborally/objects/DrawableObject.java index 062e62f..c5fb69a 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/DrawableObject.java +++ b/src/main/java/inf112/fiasko/roborally/objects/DrawableObject.java @@ -1,12 +1,12 @@ package inf112.fiasko.roborally.objects; -import inf112.fiasko.roborally.element_properties.GameTexture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; /** * This class represents an object that can be drawn using libgdx */ public class DrawableObject implements IDrawableObject { - private final GameTexture texture; + private final TextureRegion texture; private final int xPos; private final int yPos; private int width = 64; @@ -26,7 +26,7 @@ public class DrawableObject implements IDrawableObject { * @param flipX Whether to flip/mirror the element over the x axis * @param flipY Whether to flip/mirror the element over the y axis */ - public DrawableObject(GameTexture texture, int xPos, int yPos, int width, int height, int rotation, boolean flipX, + public DrawableObject(TextureRegion texture, int xPos, int yPos, int width, int height, int rotation, boolean flipX, boolean flipY) { this.xPos = xPos; this.yPos = yPos; @@ -38,20 +38,38 @@ public class DrawableObject implements IDrawableObject { this.flipY = flipY; } + /** + * Initializes a drawable object + * @param texture The texture to use for drawing the element + * @param xPos The pixel to start drawing on for the x axis + * @param yPos The pixel to start drawing on for the y axis + * @param width The width of the element + * @param height The height of the element + * @param rotation The amount of degrees to rotate the element counterclockwise + */ + public DrawableObject(TextureRegion texture, int xPos, int yPos, int width, int height, int rotation) { + this.xPos = xPos; + this.yPos = yPos; + this.rotation = rotation; + this.texture = texture; + this.width = width; + this.height = height; + } + /** * Initializes a new drawable object * @param texture The texture to use for drawing the element * @param xPos The pixel to start drawing on for the x axis * @param yPos The pixel to start drawing on for the y axis */ - public DrawableObject(GameTexture texture, int xPos, int yPos) { + public DrawableObject(TextureRegion texture, int xPos, int yPos) { this.xPos = xPos; this.yPos = yPos; this.texture = texture; } @Override - public GameTexture getTexture() { + public TextureRegion getTexture() { return texture; } diff --git a/src/main/java/inf112/fiasko/roborally/objects/Grid.java b/src/main/java/inf112/fiasko/roborally/objects/Grid.java index 38a5982..fda120c 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Grid.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Grid.java @@ -77,7 +77,7 @@ public class Grid implements IGrid { */ private void makeSureCoordinatesAreWithinBounds(int x, int y) { if (x < 0 || x >= width || y < 0 || y >= height) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Coordinates are outside the bounds of the board."); } } } diff --git a/src/main/java/inf112/fiasko/roborally/objects/IDrawableObject.java b/src/main/java/inf112/fiasko/roborally/objects/IDrawableObject.java index afbdd8e..4e5c982 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/IDrawableObject.java +++ b/src/main/java/inf112/fiasko/roborally/objects/IDrawableObject.java @@ -1,6 +1,6 @@ package inf112.fiasko.roborally.objects; -import inf112.fiasko.roborally.element_properties.GameTexture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; /** * This interface describes an object drawable using libgdx @@ -11,7 +11,7 @@ public interface IDrawableObject { * Gets the texture to use for drawing the object * @return The texture of the object */ - GameTexture getTexture(); + TextureRegion getTexture(); /** * Gets the x position the object should be drawn on diff --git a/src/main/java/inf112/fiasko/roborally/utility/IOUtil.java b/src/main/java/inf112/fiasko/roborally/utility/IOUtil.java new file mode 100644 index 0000000..77764e1 --- /dev/null +++ b/src/main/java/inf112/fiasko/roborally/utility/IOUtil.java @@ -0,0 +1,129 @@ +package inf112.fiasko.roborally.utility; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import inf112.fiasko.roborally.element_properties.Direction; +import inf112.fiasko.roborally.element_properties.Position; +import inf112.fiasko.roborally.game.IDrawableGame; +import inf112.fiasko.roborally.objects.DrawableObject; +import inf112.fiasko.roborally.objects.IDrawableObject; +import inf112.fiasko.roborally.objects.Robot; +import inf112.fiasko.roborally.objects.Tile; +import inf112.fiasko.roborally.objects.Wall; + +import java.util.ArrayList; +import java.util.List; + +public class IOUtil { + private IOUtil() {} + + /** + * Gets a list of all elements which should be drawn from the game provided + * @param game A game implementing IDrawableGame + * @param tileWidth The with of all tiles to be drawn + * @param tileHeight The height of all tiles to be drawn + * @return A list of drawable objects + */ + public static List getDrawableObjectsFromGame(IDrawableGame game, int tileWidth, int tileHeight) { + List drawableObjects = new ArrayList<>(); + List tilesToDraw = game.getTilesToDraw(); + List wallsToDraw = game.getWallsToDraw(); + List robotsToDraw = game.getRobotsToDraw(); + int gameWidth = game.getWidth(); + int gameHeight = game.getHeight(); + drawableObjects.addAll(getDrawableObjectsFromElementList(tilesToDraw, gameWidth, gameHeight, tileWidth, tileHeight)); + drawableObjects.addAll(getDrawableObjectsFromElementList(wallsToDraw, gameWidth, gameHeight, tileWidth, tileHeight)); + drawableObjects.addAll(getDrawableRobots(robotsToDraw, gameWidth, gameHeight, tileWidth, tileHeight)); + return drawableObjects; + } + + private static List getDrawableRobots(List robots, int gameWidth, int gameHeight, int tileWidth, int tileHeight) { + List drawableObjects = new ArrayList<>(); + for (Robot robot : robots) { + TextureRegion region = TextureConverterUtil.convertElement(robot); + Position robotPosition = robot.getPosition(); + int rotation = getElementRotation(robot); + IDrawableObject drawableObject = new DrawableObject(region, robotPosition.getXCoordinate() * tileWidth, + (-robotPosition.getYCoordinate() + gameHeight - 1) * tileHeight, tileWidth, tileHeight, rotation); + drawableObjects.add(drawableObject); + } + return drawableObjects; + } + + /** + * Gets a list of drawable objects with correct positions from a list of elements + * @param elementsToDraw A list of elements to draw + * @param gameWidth The width of the game board in tiles + * @param gameHeight The height of the game board in tiles + * @param tileWidth The width of a tile + * @param tileHeight The height of a tile + * @param Should be type Robot, Tile or Wall + * @return A list of drawable objects + */ + private static List getDrawableObjectsFromElementList(List elementsToDraw, int gameWidth, + int gameHeight, int tileWidth, + int tileHeight) { + List drawableObjects = new ArrayList<>(); + for (int j = 0; j < gameHeight; j++) { + for (int i = j * gameWidth; i < (j + 1) * gameWidth; i++) { + K currentElement = elementsToDraw.get(i); + if (currentElement == null) { + continue; + } + TextureRegion region; + if (currentElement.getClass().isAssignableFrom(Tile.class)) { + Tile tile = (Tile) currentElement; + region = TextureConverterUtil.convertElement(tile); + } else if (currentElement.getClass().isAssignableFrom(Wall.class)) { + Wall wall = (Wall) currentElement; + region = TextureConverterUtil.convertElement(wall); + } else { + throw new IllegalArgumentException("Unknown element type passed to function."); + } + int rotation = getElementRotation(currentElement); + IDrawableObject drawableObject = new DrawableObject(region, + (i % gameWidth) * tileWidth, j * tileHeight, tileWidth, tileHeight, rotation); + drawableObjects.add(drawableObject); + } + } + return drawableObjects; + } + + private static int getElementRotation(K element) { + boolean hasRotatedTexture; + Direction direction; + if (element.getClass().isAssignableFrom(Robot.class)) { + Robot robot = (Robot) element; + hasRotatedTexture = TextureConverterUtil.hasRotatedTexture(robot); + direction = robot.getFacingDirection(); + } else if (element.getClass().isAssignableFrom(Tile.class)) { + Tile tile = (Tile) element; + hasRotatedTexture = TextureConverterUtil.hasRotatedTexture(tile); + direction = tile.getDirection(); + } else if (element.getClass().isAssignableFrom(Wall.class)) { + Wall wall = (Wall) element; + hasRotatedTexture = TextureConverterUtil.hasRotatedTexture(wall); + direction = wall.getDirection(); + } else { + throw new IllegalArgumentException("Unknown element type passed to function."); + } + if (hasRotatedTexture) { + return 0; + } + switch (direction) { + case NORTH: + case NORTH_EAST: + return 0; + case WEST: + case NORTH_WEST: + return 90; + case SOUTH: + case SOUTH_WEST: + return 180; + case EAST: + case SOUTH_EAST: + return 270; + default: + throw new IllegalArgumentException("Invalid element direction encountered."); + } + } +} diff --git a/src/main/java/inf112/fiasko/roborally/utility/TextureConverterUtil.java b/src/main/java/inf112/fiasko/roborally/utility/TextureConverterUtil.java index 4270184..fc87098 100644 --- a/src/main/java/inf112/fiasko/roborally/utility/TextureConverterUtil.java +++ b/src/main/java/inf112/fiasko/roborally/utility/TextureConverterUtil.java @@ -67,6 +67,9 @@ public final class TextureConverterUtil { e.printStackTrace(); } } + if (wall == null) { + return null; + } Direction direction = wall.getDirection(); TextureConverterContainer converterContainer = tileSheetWallTextureMappings.get(wall.getWallType()); if (converterContainer != null) { @@ -104,6 +107,24 @@ public final class TextureConverterUtil { return tileSheetTileHasRotatedTextureMappings.get(tile.getTileType()); } + /** + * Checks whether a wall has textures for different rotations + * @param wall The wall to check + * @return True if rotated versions of the texture exists. False otherwise + */ + public static boolean hasRotatedTexture(Wall wall) { + return true; + } + + /** + * Checks whether a robot has textures for different rotations + * @param robot The robot to check + * @return True if rotated versions of the texture exists. False otherwise + */ + public static boolean hasRotatedTexture(Robot robot) { + return false; + } + /** * Loads mappings between a tile and texture * diff --git a/src/test/java/inf112/fiasko/roborally/game/GameTest.java b/src/test/java/inf112/fiasko/roborally/game/GameTest.java index 2e2ae88..6d6621a 100644 --- a/src/test/java/inf112/fiasko/roborally/game/GameTest.java +++ b/src/test/java/inf112/fiasko/roborally/game/GameTest.java @@ -1,10 +1,6 @@ package inf112.fiasko.roborally.game; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - -import inf112.fiasko.roborally.game.Game; -import inf112.fiasko.roborally.game.IDrawableGame; import org.junit.Before; import org.junit.Test; @@ -35,9 +31,4 @@ public class GameTest { public void gameHeightIsMaximumFullHD() { assertTrue(game.getHeight() <= 1080); } - - @Test - public void getObjectsToDrawReturnsNonemptyList() { - assertFalse(game.getObjectsToDraw().isEmpty()); - } } diff --git a/src/test/java/inf112/fiasko/roborally/objects/DrawableObjectTest.java b/src/test/java/inf112/fiasko/roborally/objects/DrawableObjectTest.java index ff6a3fb..44a3599 100644 --- a/src/test/java/inf112/fiasko/roborally/objects/DrawableObjectTest.java +++ b/src/test/java/inf112/fiasko/roborally/objects/DrawableObjectTest.java @@ -1,17 +1,24 @@ package inf112.fiasko.roborally.objects; -import inf112.fiasko.roborally.element_properties.GameTexture; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import inf112.fiasko.roborally.GdxTestRunner; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertFalse; +@RunWith(GdxTestRunner.class) public class DrawableObjectTest { - public static final GameTexture TEXTURE_MIN_ARG = GameTexture.TILE; - public static final GameTexture TEXTURE_MAX_ARG = GameTexture.ROBOT; + private static final Texture textureSheet = new Texture(Gdx.files.internal("assets/tiles.png")); + private static final Texture robotTexture = new Texture(Gdx.files.internal("assets/Robot.png")); + public static final TextureRegion TEXTURE_MIN_ARG = new TextureRegion(textureSheet, 4*300, 0, 300, 300); + public static final TextureRegion TEXTURE_MAX_ARG = new TextureRegion(robotTexture, 0, 0, 64, 64); public static final int X_POSITION_MIN_ARG = 5; public static final int Y_POSITION_MIN_ARG = 8; public static final int X_POSITION_MAX_ARG = 6;