Oppdaterer TextureConverterUtil til å lese fra en tekstfil

Legger til en tekstfil som beskriver teksturregion som hører til en Tile
Legger til nødvendige metoder for å lese fra filen
Legger til noen tester for TextureConverterUtil
This commit is contained in:
Kristian Knarvik 2020-02-23 14:35:31 +01:00
parent 93e9f3c93d
commit 6c745bd434
3 changed files with 237 additions and 67 deletions

View File

@ -4,13 +4,24 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import inf112.fiasko.roborally.element_properties.Direction; import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.TileType;
import inf112.fiasko.roborally.objects.Tile; import inf112.fiasko.roborally.objects.Tile;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/** /**
* This class can convert an element to an appropriate texture * This class can convert an element to an appropriate texture
*/ */
public final class TextureConverterUtil { public final class TextureConverterUtil {
private static final Texture textureSheet = new Texture(Gdx.files.internal("assets/tiles.png")); private static final Texture textureSheet = new Texture(Gdx.files.internal("assets/tiles.png"));
private static Map<TileType, TextureConverterContainer> tileSheetTileTextureMappings;
private static Map<TileType, Boolean> tileSheetTileHasRotatedTextureMappings;
private TextureConverterUtil() {} private TextureConverterUtil() {}
@ -20,39 +31,99 @@ public final class TextureConverterUtil {
* @return The texture to draw * @return The texture to draw
*/ */
public static TextureRegion convertElement(Tile tile) { public static TextureRegion convertElement(Tile tile) {
Direction direction = tile.getDirection(); if (tileSheetTileTextureMappings == null) {
switch (tile.getTileType()) { try {
case TILE: loadTileMappings();
return getTextureOnSheet(4, 0); } catch (IOException e) {
case HOLE: e.printStackTrace();
return getTextureOnSheet(5, 0); }
case COGWHEEL_RIGHT:
return getTextureOnSheet(5, 6);
case COGWHEEL_LEFT:
return getTextureOnSheet(4, 6);
case TRANSPORT_BAND_SLOW:
return getDirectionalTextureRegion(direction, 0, 6, 3, 6, 1, 6, 2, 6);
case TRANSPORT_BAND_SLOW_RIGHT:
return getDirectionalTextureRegion(direction, 2, 5, 2, 4, 3, 4, 3, 5);
case TRANSPORT_BAND_SLOW_LEFT:
return getDirectionalTextureRegion(direction, 1, 5, 0, 5, 0, 4, 1, 4);
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCES:
return getDirectionalTextureRegion(direction, 4, 8, 0, 5, 0, 4, 1, 4);
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_RIGHT:
return getDirectionalTextureRegion(direction, 0, 8, 1, 8, 2, 8, 3, 8);
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_LEFT:
return getDirectionalTextureRegion(direction, 0, 7, 1, 7, 2, 7, 3, 7);
case TRANSPORT_BAND_FAST:
return getDirectionalTextureRegion(direction, 4, 1, 5, 1, 4, 2, 5, 2);
case TRANSPORT_BAND_FAST_RIGHT:
return getDirectionalTextureRegion(direction, 2, 3, 2, 2, 3, 2, 3, 3);
case TRANSPORT_BAND_FAST_LEFT:
return getDirectionalTextureRegion(direction, 1, 3, 0, 3, 0, 2, 1, 2);
case TRANSPORT_BAND_FAST_SIDE_ENTRANCES:
return getDirectionalTextureRegion(direction, 3, 10, 0, 10, 1, 10, 2, 10);
default:
throw new IllegalArgumentException("Invalid or unimplemented tile type encountered");
} }
Direction direction = tile.getDirection();
TextureConverterContainer converterContainer = tileSheetTileTextureMappings.get(tile.getTileType());
if (converterContainer != null) {
return getDirectionalTextureRegion(direction, converterContainer.getXNorth(),
converterContainer.getYNorth(), converterContainer.getXEast(), converterContainer.getYEast(),
converterContainer.getXSouth(), converterContainer.getYSouth(), converterContainer.getXWest(),
converterContainer.getYWest());
}
throw new IllegalArgumentException("Invalid or unimplemented tile type encountered");
}
/**
* Checks whether a tile has textures for different rotations
*
* For a tile without a rotated texture, the texture needs to be rotated when rendering.
*
* @param tile The tile to check
* @return True if rotated versions of the texture exists. False otherwise
*/
public static boolean hasRotatedTexture(Tile tile) {
if (tileSheetTileTextureMappings == null) {
try {
loadTileMappings();
} catch (IOException e) {
e.printStackTrace();
}
}
return tileSheetTileHasRotatedTextureMappings.get(tile.getTileType());
}
/**
* Loads mappings between a tile and texture
*
* Loads both information about mapping from a tile to a texture converter container and information about mapping
* from a tile to whether the tile has a rotated version of each texture
*
* @throws IOException If the mapping file can't be properly read
*/
private static synchronized void loadTileMappings() throws IOException {
tileSheetTileTextureMappings = new HashMap<>();
tileSheetTileHasRotatedTextureMappings = new HashMap<>();
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream fileStream = classloader.getResourceAsStream("texture_sheet_tile_mapping.txt");
if (fileStream == null) {
throw new FileNotFoundException("Unable to load texture sheet mapping file.");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream));
String line;
while ((line = reader.readLine()) != null) {
String[] parameters = line.split(" ");
TileType type = TileType.valueOf(parameters[0]);
storeTextMappingInMap(parameters, type, tileSheetTileTextureMappings,
tileSheetTileHasRotatedTextureMappings);
}
}
/**
* Reads one line of texture mapping and puts it into the correct maps
* @param parameters The parameters describing the texture mapping of the element
* @param mapKey The key to store in the map
* @param textureMapping The map containing texture mappings
* @param hasRotatedTextureMapping The map containing whether an element has rotated textures or not
* @param <K> The type of element that will be used for map keys
*/
private static synchronized <K> void storeTextMappingInMap(String[] parameters, K mapKey,
Map<K,TextureConverterContainer> textureMapping,
Map<K,Boolean> hasRotatedTextureMapping) {
TextureConverterContainer container;
int xNorth = Integer.parseInt(parameters[1]);
int yNorth = Integer.parseInt(parameters[2]);
if (parameters.length == 3) {
container = new TextureConverterContainer(xNorth, yNorth, xNorth, yNorth,
xNorth, yNorth, xNorth, yNorth);
hasRotatedTextureMapping.put(mapKey, false);
} else {
int xEast = Integer.parseInt(parameters[3]);
int yEast = Integer.parseInt(parameters[4]);
int xSouth = Integer.parseInt(parameters[5]);
int ySouth = Integer.parseInt(parameters[6]);
int xWest = Integer.parseInt(parameters[7]);
int yWest = Integer.parseInt(parameters[8]);
container = new TextureConverterContainer(xNorth, yNorth, xEast, yEast,
xSouth, ySouth, xWest, yWest);
hasRotatedTextureMapping.put(mapKey, true);
}
textureMapping.put(mapKey, container);
} }
/** /**
@ -99,42 +170,60 @@ public final class TextureConverterUtil {
} }
/** /**
* Checks whether a tile has textures for different rotations * This class serves as a temporary container for texture region coordinates
*
* For a tile without a rotation texture, the texture needs to be rotated when rendering.
*
* @param tile The tile to check
* @return True if rotated versions of the texture exists. False otherwise
*/ */
public static boolean hasRotatedTexture(Tile tile) { private static class TextureConverterContainer {
switch (tile.getTileType()) { private int xNorth;
case TILE: private int yNorth;
case HOLE: private int xEast;
case COGWHEEL_RIGHT: private int yEast;
case COGWHEEL_LEFT: private int xSouth;
case FLAG_1: private int ySouth;
case FLAG_2: private int xWest;
case FLAG_3: private int yWest;
case FLAG_4:
case WRENCH: TextureConverterContainer(int xNorth, int yNorth, int xEast, int yEast, int xSouth, int ySouth,
case WRENCH_AND_HAMMER: int xWest, int yWest) {
case DEATH_TILE: this.xNorth = xNorth;
return false; this.yNorth = yNorth;
case TRANSPORT_BAND_SLOW: this.xEast = xEast;
case TRANSPORT_BAND_SLOW_RIGHT: this.yEast = yEast;
case TRANSPORT_BAND_SLOW_LEFT: this.xSouth = xSouth;
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCES: this.ySouth = ySouth;
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_LEFT: this.xWest = xWest;
case TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_RIGHT: this.yWest = yWest;
case TRANSPORT_BAND_FAST: }
case TRANSPORT_BAND_FAST_RIGHT:
case TRANSPORT_BAND_FAST_LEFT: public int getXNorth() {
case TRANSPORT_BAND_FAST_SIDE_ENTRANCES: return xNorth;
case TRANSPORT_BAND_FAST_SIDE_ENTRANCE_LEFT: }
case TRANSPORT_BAND_FAST_SIDE_ENTRANCE_RIGHT:
return true; public int getYNorth() {
default: return yNorth;
throw new IllegalArgumentException("Invalid tile type encountered"); }
public int getXEast() {
return xEast;
}
public int getYEast() {
return yEast;
}
public int getXSouth() {
return xSouth;
}
public int getYSouth() {
return ySouth;
}
public int getXWest() {
return xWest;
}
public int getYWest() {
return yWest;
} }
} }
} }

View File

@ -0,0 +1,14 @@
TILE 4 0
HOLE 5 0
COGWHEEL_RIGHT 5 6
COGWHEEL_LEFT 4 6
TRANSPORT_BAND_SLOW 0 6 3 6 1 6 2 6
TRANSPORT_BAND_SLOW_RIGHT 2 5 2 4 3 4 3 5
TRANSPORT_BAND_SLOW_LEFT 1 5 0 5 0 4 1 4
TRANSPORT_BAND_SLOW_SIDE_ENTRANCES 4 8 0 5 0 4 1 4
TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_RIGHT 0 8 1 8 2 8 3 8
TRANSPORT_BAND_SLOW_SIDE_ENTRANCE_LEFT 0 7 1 7 2 7 3 7
TRANSPORT_BAND_FAST 4 1 5 1 4 2 5 2
TRANSPORT_BAND_FAST_RIGHT 2 3 2 2 3 2 3 3
TRANSPORT_BAND_FAST_LEFT 1 3 0 3 0 2 1 2
TRANSPORT_BAND_FAST_SIDE_ENTRANCES 3 10 0 10 1 10 2 10

View File

@ -0,0 +1,67 @@
package inf112.fiasko.roborally.utility;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import inf112.fiasko.roborally.GdxTestRunner;
import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.TileType;
import inf112.fiasko.roborally.objects.Tile;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@RunWith (GdxTestRunner.class)
public class TextureConverterUtilTest {
private Tile tileNorth;
private Tile holeNorth;
private Tile transportBandSlowEast;
private TextureRegion tileTextureRegion;
private TextureRegion holeTextureRegion;
private TextureRegion transportBandSlowEastTextureRegion;
@Before
public void setUp() {
tileNorth = new Tile(TileType.TILE, Direction.NORTH);
holeNorth = new Tile(TileType.HOLE, Direction.NORTH);
transportBandSlowEast = new Tile(TileType.TRANSPORT_BAND_SLOW, Direction.EAST);
tileTextureRegion = TextureConverterUtil.convertElement(tileNorth);
holeTextureRegion = TextureConverterUtil.convertElement(holeNorth);
transportBandSlowEastTextureRegion = TextureConverterUtil.convertElement(transportBandSlowEast);
}
@Test
public void tileTileConversion() {
assertEquals(4*300, tileTextureRegion.getRegionX());
assertEquals(0, tileTextureRegion.getRegionY());
}
@Test
public void tileHoleConversion() {
assertEquals(5*300, holeTextureRegion.getRegionX());
assertEquals(0, holeTextureRegion.getRegionY());
}
@Test
public void tileTransportBandSlowFacingEastConversion() {
assertEquals(3*300, transportBandSlowEastTextureRegion.getRegionX());
assertEquals(6*300, transportBandSlowEastTextureRegion.getRegionY());
}
@Test
public void tileTileHasRotatedTextureTest() {
assertFalse(TextureConverterUtil.hasRotatedTexture(tileNorth));
}
@Test
public void tileHoleHasRotatedTextureTest() {
assertFalse(TextureConverterUtil.hasRotatedTexture(holeNorth));
}
@Test
public void tileTransportBandHasRotatedTextureTest() {
assertTrue(TextureConverterUtil.hasRotatedTexture(transportBandSlowEast));
}
}