v0.5.0: refactoring and performance improvements to tile sheet and wall blocking

This commit is contained in:
Evan Debenham 2017-02-05 21:47:27 -05:00
parent dc3a2ea907
commit ec35e03875
7 changed files with 119 additions and 100 deletions

View File

@ -56,7 +56,7 @@ public class DungeonTerrainTilemap extends DungeonTilemap {
} }
if (!flat) { if (!flat) {
if ((DungeonTileSheet.doorTiles.contains(tile))) { if ((DungeonTileSheet.doorTile(tile))) {
return DungeonTileSheet.getRaisedDoorTile(tile, map[pos - mapWidth]); return DungeonTileSheet.getRaisedDoorTile(tile, map[pos - mapWidth]);
} else if (tile == Terrain.WALL || tile == Terrain.WALL_DECO } else if (tile == Terrain.WALL || tile == Terrain.WALL_DECO
|| tile == Terrain.SECRET_DOOR || tile == Terrain.BOOKSHELF){ || tile == Terrain.SECRET_DOOR || tile == Terrain.BOOKSHELF){
@ -97,8 +97,8 @@ public class DungeonTerrainTilemap extends DungeonTilemap {
return data[pos] != DungeonTileSheet.WATER || return data[pos] != DungeonTileSheet.WATER ||
( (
pos + mapWidth < size && pos + mapWidth < size &&
DungeonTileSheet.wallStitcheable.contains(map[pos]) && DungeonTileSheet.wallStitcheable(map[pos]) &&
DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth]) DungeonTileSheet.wallStitcheable(map[pos + mapWidth])
); );
} }
} }

View File

@ -191,15 +191,25 @@ public class DungeonTileSheet {
public static final int RAISED_WALL_DECO_ALT = RAISED_WALLS+20; public static final int RAISED_WALL_DECO_ALT = RAISED_WALLS+20;
public static final int RAISED_WALL_BOOKSHELF_ALT = RAISED_WALLS+28; public static final int RAISED_WALL_BOOKSHELF_ALT = RAISED_WALLS+28;
//we use an array instead of a collection because the small element count
// makes array traversal much faster than something like HashSet.contains.
//These tiles count as wall for the purposes of wall stitching //These tiles count as wall for the purposes of wall stitching
public static HashSet<Integer> wallStitcheable = new HashSet<>(Arrays.asList( private static int[] wallStitcheable = new int[]{
Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR, Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR,
Terrain.LOCKED_EXIT, Terrain.UNLOCKED_EXIT, Terrain.BOOKSHELF, NULL_TILE Terrain.LOCKED_EXIT, Terrain.UNLOCKED_EXIT, Terrain.BOOKSHELF, NULL_TILE
)); };
public static boolean wallStitcheable(int tile){
for (int i : wallStitcheable)
if (tile == i)
return true;
return false;
}
public static int getRaisedWallTile(int tile, int pos, int right, int below, int left){ public static int getRaisedWallTile(int tile, int pos, int right, int below, int left){
int result; int result;
if (doorTiles.contains(below)) result = RAISED_WALL_DOOR; if (doorTile(below)) result = RAISED_WALL_DOOR;
else if (tile == Terrain.WALL || tile == Terrain.SECRET_DOOR) result = RAISED_WALL; else if (tile == Terrain.WALL || tile == Terrain.SECRET_DOOR) result = RAISED_WALL;
else if (tile == Terrain.WALL_DECO) result = RAISED_WALL_DECO; else if (tile == Terrain.WALL_DECO) result = RAISED_WALL_DECO;
else if (tile == Terrain.BOOKSHELF) result = RAISED_WALL_BOOKSHELF; else if (tile == Terrain.BOOKSHELF) result = RAISED_WALL_BOOKSHELF;
@ -207,8 +217,8 @@ public class DungeonTileSheet {
result = getVisualWithAlts(result, pos); result = getVisualWithAlts(result, pos);
if (!wallStitcheable.contains(right)) result += 1; if (!wallStitcheable(right)) result += 1;
if (!wallStitcheable.contains(left)) result += 2; if (!wallStitcheable(left)) result += 2;
return result; return result;
} }
@ -221,16 +231,23 @@ public class DungeonTileSheet {
public static int getRaisedDoorTile(int tile, int below){ public static int getRaisedDoorTile(int tile, int below){
if (wallStitcheable.contains(below)) return RAISED_DOOR_SIDEWAYS; if (wallStitcheable(below)) return RAISED_DOOR_SIDEWAYS;
else if (tile == Terrain.DOOR) return DungeonTileSheet.RAISED_DOOR; else if (tile == Terrain.DOOR) return DungeonTileSheet.RAISED_DOOR;
else if (tile == Terrain.OPEN_DOOR) return DungeonTileSheet.RAISED_DOOR_OPEN; else if (tile == Terrain.OPEN_DOOR) return DungeonTileSheet.RAISED_DOOR_OPEN;
else if (tile == Terrain.LOCKED_DOOR) return DungeonTileSheet.RAISED_DOOR_LOCKED; else if (tile == Terrain.LOCKED_DOOR) return DungeonTileSheet.RAISED_DOOR_LOCKED;
else return -1; else return -1;
} }
public static HashSet<Integer> doorTiles = new HashSet<>(Arrays.asList( private static int[] doorTiles = new int[]{
Terrain.DOOR, Terrain.LOCKED_DOOR, Terrain.OPEN_DOOR Terrain.DOOR, Terrain.LOCKED_DOOR, Terrain.OPEN_DOOR
)); };
public static boolean doorTile(int tile){
for (int i : doorTiles)
if (tile == i)
return true;
return false;
}
private static final int RAISED_OTHER = xy(1, 11); //16 slots private static final int RAISED_OTHER = xy(1, 11); //16 slots
public static final int RAISED_SIGN = RAISED_OTHER+0; public static final int RAISED_SIGN = RAISED_OTHER+0;
@ -255,10 +272,10 @@ public class DungeonTileSheet {
if (tile == Terrain.BOOKSHELF) result = WALL_INTERNAL_WOODEN; if (tile == Terrain.BOOKSHELF) result = WALL_INTERNAL_WOODEN;
else result = WALL_INTERNAL; else result = WALL_INTERNAL;
if (!wallStitcheable.contains(right)) result += 1; if (!wallStitcheable(right)) result += 1;
if (!wallStitcheable.contains(rightBelow)) result += 2; if (!wallStitcheable(rightBelow)) result += 2;
if (!wallStitcheable.contains(leftBelow)) result += 4; if (!wallStitcheable(leftBelow)) result += 4;
if (!wallStitcheable.contains(left)) result += 8; if (!wallStitcheable(left)) result += 8;
return result; return result;
} }
@ -278,8 +295,8 @@ public class DungeonTileSheet {
else if (below == Terrain.BOOKSHELF) visual = WALL_OVERHANG_WOODEN; else if (below == Terrain.BOOKSHELF) visual = WALL_OVERHANG_WOODEN;
else visual = WALL_OVERHANG; else visual = WALL_OVERHANG;
if (!wallStitcheable.contains(rightBelow)) visual += 1; if (!wallStitcheable(rightBelow)) visual += 1;
if (!wallStitcheable.contains(leftBelow)) visual += 2; if (!wallStitcheable(leftBelow)) visual += 2;
return visual; return visual;
} }

View File

@ -92,11 +92,11 @@ public abstract class DungeonTilemap extends Tilemap {
if (wallAssist if (wallAssist
&& map != null && map != null
&& DungeonTileSheet.wallStitcheable.contains(map[cell])){ && DungeonTileSheet.wallStitcheable(map[cell])){
if (cell + mapWidth < size if (cell + mapWidth < size
&& p.y % 1 >= 0.75f && p.y % 1 >= 0.75f
&& !DungeonTileSheet.wallStitcheable.contains(map[cell + mapWidth])){ && !DungeonTileSheet.wallStitcheable(map[cell + mapWidth])){
cell += mapWidth; cell += mapWidth;
} }

View File

@ -43,8 +43,8 @@ public class DungeonWallsTilemap extends DungeonTilemap {
if (flat) return -1; if (flat) return -1;
if (DungeonTileSheet.wallStitcheable.contains(tile)) { if (DungeonTileSheet.wallStitcheable(tile)) {
if (pos + mapWidth < size && !DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth])){ if (pos + mapWidth < size && !DungeonTileSheet.wallStitcheable(map[pos + mapWidth])){
if (map[pos + mapWidth] == Terrain.DOOR){ if (map[pos + mapWidth] == Terrain.DOOR){
return DungeonTileSheet.DOOR_SIDEWAYS; return DungeonTileSheet.DOOR_SIDEWAYS;
@ -66,7 +66,7 @@ public class DungeonWallsTilemap extends DungeonTilemap {
} }
if (pos + mapWidth < size && DungeonTileSheet.wallStitcheable.contains(map[pos+mapWidth])) { if (pos + mapWidth < size && DungeonTileSheet.wallStitcheable(map[pos+mapWidth])) {
return DungeonTileSheet.stitchWallOverhangTile( return DungeonTileSheet.stitchWallOverhangTile(
tile, tile,

View File

@ -163,15 +163,15 @@ public class FogOfWar extends Image {
} }
//triggers on wall tiles or sideways doors //triggers on wall tiles or sideways doors
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]) || if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell]) ||
( DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell]) ( DungeonTileSheet.doorTile(Dungeon.level.map[cell])
&& cell + mapWidth < mapLength && cell + mapWidth < mapLength
&& DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]))) { && DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + mapWidth]))) {
cellIndex = getColorIndexForCell(cell); cellIndex = getColorIndexForCell(cell);
if (cell + mapWidth < mapLength){ if (cell + mapWidth < mapLength){
if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]) if (!DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + mapWidth])
&& !DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell + mapWidth])){ && !DungeonTileSheet.doorTile(Dungeon.level.map[cell + mapWidth])){
if (getColorIndexForCell(cell + mapWidth) > cellIndex) if (getColorIndexForCell(cell + mapWidth) > cellIndex)
cellIndex = getColorIndexForCell(cell + mapWidth); cellIndex = getColorIndexForCell(cell + mapWidth);
fillCell(j, i, FOG_COLORS[cellIndex][brightness]); fillCell(j, i, FOG_COLORS[cellIndex][brightness]);
@ -180,8 +180,8 @@ public class FogOfWar extends Image {
} }
if (cell % mapWidth != 0){ if (cell % mapWidth != 0){
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1]) if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell - 1])
|| DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell - 1])){ || DungeonTileSheet.doorTile(Dungeon.level.map[cell - 1])){
if (getColorIndexForCell(cell - 1 + mapWidth) > cellIndex) if (getColorIndexForCell(cell - 1 + mapWidth) > cellIndex)
colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1 + mapWidth)][brightness]; colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1 + mapWidth)][brightness];
else else
@ -197,8 +197,8 @@ public class FogOfWar extends Image {
} }
if ((cell+1) % mapWidth != 0){ if ((cell+1) % mapWidth != 0){
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1]) if (DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell + 1])
|| DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell + 1])){ || DungeonTileSheet.doorTile(Dungeon.level.map[cell + 1])){
if (getColorIndexForCell(cell + 1 + mapWidth) > cellIndex) if (getColorIndexForCell(cell + 1 + mapWidth) > cellIndex)
colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1 + mapWidth)][brightness]; colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1 + mapWidth)][brightness];
else else
@ -228,7 +228,7 @@ public class FogOfWar extends Image {
} }
fillCell(j, i, colorArray); fillCell(j, i, colorArray);
} else if (DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell])) { } else if (DungeonTileSheet.doorTile(Dungeon.level.map[cell])) {
colorArray[0] = colorArray[1] = FOG_COLORS[getColorIndexForCell(cell)][brightness]; colorArray[0] = colorArray[1] = FOG_COLORS[getColorIndexForCell(cell)][brightness];
colorArray[2] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + mapWidth)][brightness]; colorArray[2] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + mapWidth)][brightness];

View File

@ -26,8 +26,8 @@ public class GridTileMap extends DungeonTilemap {
return -1; return -1;
} else if (DungeonTileSheet.floorTile(tile)) { } else if (DungeonTileSheet.floorTile(tile)) {
return gridSetting; return gridSetting;
} else if (DungeonTileSheet.doorTiles.contains(tile)){ } else if (DungeonTileSheet.doorTile(tile)){
if (DungeonTileSheet.wallStitcheable.contains(map[pos - mapWidth])){ if (DungeonTileSheet.wallStitcheable(map[pos - mapWidth])){
return 12 + gridSetting; return 12 + gridSetting;
} else if ( tile == Terrain.OPEN_DOOR){ } else if ( tile == Terrain.OPEN_DOOR){
return 8 + gridSetting; return 8 + gridSetting;

View File

@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.tiles; package com.shatteredpixel.shatteredpixeldungeon.tiles;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.watabou.noosa.TextureFilm; import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap; import com.watabou.noosa.Tilemap;
@ -29,6 +30,7 @@ public class WallBlockingTilemap extends Tilemap {
public static final int SIZE = 16; public static final int SIZE = 16;
private static final int CLEARED = -1;
private static final int BLOCK_NONE = 0; private static final int BLOCK_NONE = 0;
private static final int BLOCK_RIGHT = 1; private static final int BLOCK_RIGHT = 1;
private static final int BLOCK_LEFT = 2; private static final int BLOCK_LEFT = 2;
@ -42,6 +44,7 @@ public class WallBlockingTilemap extends Tilemap {
@Override @Override
public synchronized void updateMap() { public synchronized void updateMap() {
super.updateMap(); super.updateMap();
data = new int[size]; //clears all values, including cleared tiles
for (int i = 0; i < data.length; i++) for (int i = 0; i < data.length; i++)
updateMapCell(i); updateMapCell(i);
} }
@ -51,78 +54,76 @@ public class WallBlockingTilemap extends Tilemap {
int prev = data[cell]; int prev = data[cell];
int curr; int curr;
//no point in blocking tiles that are already obscured by fog if (prev == CLEARED){
if (fogHidden(cell) && fogHidden(cell - mapWidth) && fogHidden(cell + mapWidth)){ return;
curr = BLOCK_NONE;
} else if (wall(cell)) { } else if (!Level.discoverable[cell]) {
if (cell + mapWidth < Dungeon.level.map.length) { curr = CLEARED;
if (!wall(cell + mapWidth)) {
if (!fogHidden(cell + mapWidth)){
curr = BLOCK_NONE;
} else if ((cell + 1) % mapWidth != 0 && !fogHidden(cell + 1)
&& !door(cell + 1) && !(wall(cell + 1) && wall(cell + 1 + mapWidth))){
curr = BLOCK_NONE;
} else if (cell % mapWidth != 0 && !fogHidden(cell - 1)
&& !door(cell - 1) && !(wall(cell - 1) && wall(cell - 1 + mapWidth))){
curr = BLOCK_NONE;
} else {
curr = BLOCK_ALL;
}
} else {
curr = BLOCK_NONE;
if ((cell + 1) % mapWidth != 0) { //handles blocking wall overhang (which is technically on a none wall tile)
} else if (!wall(cell)) {
if (!wall(cell + 1) && !door(cell + 1)){ if (!fogHidden(cell)) {
if (fogHidden(cell + 1)) { curr = CLEARED;
curr += 1;
}
} else {
if (fogHidden(cell + 1 + mapWidth)){
curr += 1;
}
}
} } else if ( wall(cell + mapWidth) && !fogHidden(cell + mapWidth)
&& fogHidden(cell - 1) && fogHidden(cell + 1)) {
if (cell % mapWidth != 0) { curr = BLOCK_ALL;
if (!wall(cell - 1) && !door(cell - 1)){
if (fogHidden(cell - 1)) {
curr += 2;
}
} else {
if (fogHidden(cell - 1 + mapWidth)){
curr += 2;
}
}
}
}
} else { } else {
curr = BLOCK_NONE; curr = BLOCK_NONE;
if ((cell + 1) % mapWidth != 0 && fogHidden(cell + 1)) {
curr += 1;
}
if (cell % mapWidth != 0 && fogHidden(cell - 1)) {
curr += 2;
}
} }
} else { } else {
if (fogHidden(cell - 1) && fogHidden(cell) && fogHidden(cell + 1)
&& cell + mapWidth < Dungeon.level.map.length if (fogHidden(cell - mapWidth) && fogHidden(cell) && fogHidden(cell + mapWidth)) {
&& wall(cell + mapWidth -1 ) && wall(cell + mapWidth) && wall(cell + mapWidth + 1)
&& !fogHidden(cell + mapWidth)){
curr = BLOCK_ALL;
} else {
curr = BLOCK_NONE; curr = BLOCK_NONE;
//camera-facing wall tiles
} else if (!wall(cell + mapWidth)) {
if (!fogHidden(cell + mapWidth)){
curr = CLEARED;
} else if ((cell + 1) % mapWidth != 0 && !fogHidden(cell + 1)
&& !door(cell + 1) && !(wall(cell + 1) && wall(cell + 1 + mapWidth))){
curr = CLEARED;
} else if (cell % mapWidth != 0 && !fogHidden(cell - 1)
&& !door(cell - 1) && !(wall(cell - 1) && wall(cell - 1 + mapWidth))){
curr = CLEARED;
} else {
curr = BLOCK_ALL;
}
//internal wall tiles
} else {
curr = BLOCK_NONE;
if ((cell + 1) % mapWidth != 0) {
if ((wall(cell + 1) || fogHidden(cell + 1 - mapWidth))
&& fogHidden(cell + 1)
&& (wall(cell + 1 + mapWidth) || fogHidden(cell + 1 + mapWidth))){
curr += 1;
}
}
if (cell % mapWidth != 0) {
if ((wall(cell - 1) || fogHidden(cell - 1 - mapWidth))
&& fogHidden(cell - 1)
&& (wall(cell - 1 + mapWidth) || fogHidden(cell - 1 + mapWidth))){
curr += 2;
}
}
if (curr == BLOCK_NONE) {
curr = CLEARED;
}
} }
} }
if (prev != curr){ if (prev != curr){
@ -140,12 +141,13 @@ public class WallBlockingTilemap extends Tilemap {
return false; return false;
} }
private boolean wall(int cell){ //for the purposes of wall stitching, tiles below the map count as walls
return DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]); private boolean wall(int cell) {
return cell >= 0 && (cell >= size || DungeonTileSheet.wallStitcheable(Dungeon.level.map[cell]));
} }
private boolean door(int cell ) { private boolean door(int cell) {
return DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell]); return cell >= 0 && cell < size && DungeonTileSheet.doorTile(Dungeon.level.map[cell]);
} }
public synchronized void updateArea(int x, int y, int w, int h) { public synchronized void updateArea(int x, int y, int w, int h) {
@ -153,7 +155,7 @@ public class WallBlockingTilemap extends Tilemap {
for (int i = x; i <= x+w; i++){ for (int i = x; i <= x+w; i++){
for (int j = y; j <= y+h; j++){ for (int j = y; j <= y+h; j++){
cell = i + j*mapWidth; cell = i + j*mapWidth;
if (cell < data.length) if (cell < data.length && data[cell] != CLEARED)
updateMapCell(cell); updateMapCell(cell);
} }
} }
@ -161,6 +163,6 @@ public class WallBlockingTilemap extends Tilemap {
@Override @Override
protected boolean needsRender(int pos) { protected boolean needsRender(int pos) {
return data[pos] != BLOCK_NONE; return data[pos] > BLOCK_NONE;
} }
} }