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 ((DungeonTileSheet.doorTiles.contains(tile))) {
if ((DungeonTileSheet.doorTile(tile))) {
return DungeonTileSheet.getRaisedDoorTile(tile, map[pos - mapWidth]);
} else if (tile == Terrain.WALL || tile == Terrain.WALL_DECO
|| tile == Terrain.SECRET_DOOR || tile == Terrain.BOOKSHELF){
@ -97,8 +97,8 @@ public class DungeonTerrainTilemap extends DungeonTilemap {
return data[pos] != DungeonTileSheet.WATER ||
(
pos + mapWidth < size &&
DungeonTileSheet.wallStitcheable.contains(map[pos]) &&
DungeonTileSheet.wallStitcheable.contains(map[pos + mapWidth])
DungeonTileSheet.wallStitcheable(map[pos]) &&
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_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
public static HashSet<Integer> wallStitcheable = new HashSet<>(Arrays.asList(
private static int[] wallStitcheable = new int[]{
Terrain.WALL, Terrain.WALL_DECO, Terrain.SECRET_DOOR,
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){
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_DECO) result = RAISED_WALL_DECO;
else if (tile == Terrain.BOOKSHELF) result = RAISED_WALL_BOOKSHELF;
@ -207,8 +217,8 @@ public class DungeonTileSheet {
result = getVisualWithAlts(result, pos);
if (!wallStitcheable.contains(right)) result += 1;
if (!wallStitcheable.contains(left)) result += 2;
if (!wallStitcheable(right)) result += 1;
if (!wallStitcheable(left)) result += 2;
return result;
}
@ -221,16 +231,23 @@ public class DungeonTileSheet {
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.OPEN_DOOR) return DungeonTileSheet.RAISED_DOOR_OPEN;
else if (tile == Terrain.LOCKED_DOOR) return DungeonTileSheet.RAISED_DOOR_LOCKED;
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
));
};
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
public static final int RAISED_SIGN = RAISED_OTHER+0;
@ -255,10 +272,10 @@ public class DungeonTileSheet {
if (tile == Terrain.BOOKSHELF) result = WALL_INTERNAL_WOODEN;
else result = WALL_INTERNAL;
if (!wallStitcheable.contains(right)) result += 1;
if (!wallStitcheable.contains(rightBelow)) result += 2;
if (!wallStitcheable.contains(leftBelow)) result += 4;
if (!wallStitcheable.contains(left)) result += 8;
if (!wallStitcheable(right)) result += 1;
if (!wallStitcheable(rightBelow)) result += 2;
if (!wallStitcheable(leftBelow)) result += 4;
if (!wallStitcheable(left)) result += 8;
return result;
}
@ -278,8 +295,8 @@ public class DungeonTileSheet {
else if (below == Terrain.BOOKSHELF) visual = WALL_OVERHANG_WOODEN;
else visual = WALL_OVERHANG;
if (!wallStitcheable.contains(rightBelow)) visual += 1;
if (!wallStitcheable.contains(leftBelow)) visual += 2;
if (!wallStitcheable(rightBelow)) visual += 1;
if (!wallStitcheable(leftBelow)) visual += 2;
return visual;
}

View File

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

View File

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

View File

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

View File

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

View File

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