v0.5.0: fixes and improved to the fog of war and wall visibility

This commit is contained in:
Evan Debenham 2016-12-20 20:02:00 -05:00
parent 591b96fb81
commit d1f729500a
3 changed files with 288 additions and 31 deletions

View File

@ -27,7 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.FogOfWar; import com.shatteredpixel.shatteredpixeldungeon.tiles.FogOfWar;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@ -59,6 +59,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.DiscardedItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
import com.shatteredpixel.shatteredpixeldungeon.tiles.WallBlockingTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner; import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
@ -114,6 +115,7 @@ public class GameScene extends PixelScene {
private DungeonTerrainTilemap tiles; private DungeonTerrainTilemap tiles;
private TerrainFeaturesTilemap terrainFeatures; private TerrainFeaturesTilemap terrainFeatures;
private DungeonWallsTilemap walls; private DungeonWallsTilemap walls;
private WallBlockingTilemap wallBlocking;
private FogOfWar fog; private FogOfWar fog;
private HeroSprite hero; private HeroSprite hero;
@ -241,6 +243,9 @@ public class GameScene extends PixelScene {
walls = new DungeonWallsTilemap(); walls = new DungeonWallsTilemap();
add(walls); add(walls);
wallBlocking = new WallBlockingTilemap();
add (wallBlocking);
fog = new FogOfWar( Dungeon.level.width(), Dungeon.level.height() ); fog = new FogOfWar( Dungeon.level.width(), Dungeon.level.height() );
add( fog ); add( fog );
@ -723,13 +728,16 @@ public class GameScene extends PixelScene {
} }
public static void updateFog(){ public static void updateFog(){
if (scene != null) if (scene != null) {
scene.fog.updateFog(); scene.fog.updateFog();
scene.wallBlocking.updateMap();
}
} }
public static void updateFog(int x, int y, int w, int h){ public static void updateFog(int x, int y, int w, int h){
if (scene != null) { if (scene != null) {
scene.fog.updateFogArea(x, y, w, h); scene.fog.updateFogArea(x, y, w, h);
scene.wallBlocking.updateArea(x, y, w, h);
} }
} }

View File

@ -18,11 +18,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
package com.shatteredpixel.shatteredpixeldungeon; package com.shatteredpixel.shatteredpixeldungeon.tiles;
import android.opengl.GLES20; import android.opengl.GLES20;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.watabou.gltextures.SmartTexture; import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache; import com.watabou.gltextures.TextureCache;
import com.watabou.glwrap.Texture; import com.watabou.glwrap.Texture;
@ -37,24 +38,37 @@ import java.nio.IntBuffer;
public class FogOfWar extends Image { public class FogOfWar extends Image {
private static final int VISIBLE[] = new int[]{0xAA000000, 0x55000000, //-2 and -1 brightness //first index is visibility type, second is brightness level
0x00000000, //0 brightness private static final int FOG_COLORS[][] = new int[][]{{
0x00000000, 0x00000000}; //1 and 2 brightness //visible
0xAA000000, 0x55000000, //-2 and -1 brightness
0x00000000, //0 brightness
0x00000000, 0x00000000 //1 and 2 brightness
}, {
//visited
0xEE000000, 0xDD000000,
0xCC000000,
0x99000000, 0x66000000
}, {
//mapped
0xEE442211, 0xDD442211,
0xCC442211,
0x99442211, 0x66442211
}, {
//invisible
0xFF000000, 0xFF000000,
0xFF000000,
0xFF000000, 0xFF000000
}};
private static final int VISITED[] = new int[]{0xEE000000, 0xDD000000, private static final int VISIBLE = 0;
0xCC000000, private static final int VISITED = 1;
0x99000000, 0x66000000}; private static final int MAPPED = 2;
private static final int INVISIBLE = 3;
private static final int MAPPED[] = new int[]{0xEE442211, 0xDD442211,
0xCC442211,
0x99442211, 0x66442211};
private static final int INVISIBLE[]= new int[]{0xFF000000, 0xFF000000,
0xFF000000,
0xFF000000, 0xFF000000};
private int mapWidth; private int mapWidth;
private int mapHeight; private int mapHeight;
private int mapLength;
private int pWidth; private int pWidth;
private int pHeight; private int pHeight;
@ -73,6 +87,7 @@ public class FogOfWar extends Image {
this.mapWidth = mapWidth; this.mapWidth = mapWidth;
this.mapHeight = mapHeight; this.mapHeight = mapHeight;
mapLength = mapHeight * mapWidth;
pWidth = mapWidth * PIX_PER_TILE; pWidth = mapWidth * PIX_PER_TILE;
pHeight = mapHeight * PIX_PER_TILE; pHeight = mapHeight * PIX_PER_TILE;
@ -114,29 +129,99 @@ public class FogOfWar extends Image {
updated.setEmpty(); updated.setEmpty();
} }
private boolean[] visible;
private boolean[] visited;
private boolean[] mapped;
private int brightness;
private void updateTexture( boolean[] visible, boolean[] visited, boolean[] mapped ) { private void updateTexture( boolean[] visible, boolean[] visited, boolean[] mapped ) {
this.visible = visible;
this.visited = visited;
this.mapped = mapped;
this.brightness = ShatteredPixelDungeon.brightness() + 2;
moveToUpdating(); moveToUpdating();
FogTexture fog = (FogTexture)texture; FogTexture fog = (FogTexture)texture;
int brightness = ShatteredPixelDungeon.brightness() + 2; int cellIndex;
int[] colorArray = new int[PIX_PER_TILE*PIX_PER_TILE];
for (int i=updating.top; i < updating.bottom; i++) { for (int i=updating.top; i < updating.bottom; i++) {
int cell = mapWidth * i + updating.left; int cell = mapWidth * i + updating.left;
//fog.pixels.position((width2) * i + updating.left);
for (int j=updating.left; j < updating.right; j++) { for (int j=updating.left; j < updating.right; j++) {
if (cell >= Dungeon.level.length()) {
//do nothing if (cell >= Dungeon.level.length()) continue; //do nothing
} else if (visible[cell]) {
fillCell(j, i, VISIBLE[brightness]); if (!visible[cell] && !visited[cell] && !mapped[cell]){
} else if (visited[cell]) { fillCell(j, i, FOG_COLORS[INVISIBLE][brightness]);
fillCell(j, i, VISITED[brightness]); cell++;
} else if (mapped[cell] ) { continue;
fillCell(j, i, MAPPED[brightness]);
} else {
fillCell(j, i, INVISIBLE[brightness]);
} }
//triggers on wall tiles or sideways doors
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell]) ||
( DungeonTileSheet.doorTiles.contains(Dungeon.level.map[cell])
&& cell + mapWidth < mapLength
&& DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth]))) {
cellIndex = getColorIndexForCell(cell);
if (cell + mapWidth < mapLength){
if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth])
&& getColorIndexForCell(cell + mapWidth) > cellIndex) {
cellIndex = getColorIndexForCell(cell + mapWidth);
}
if (cell % mapWidth != 0){
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1])){
if (getColorIndexForCell(cell - 1 + mapWidth) > cellIndex)
colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1 + mapWidth)][brightness];
else
colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
} else {
if (getColorIndexForCell(cell - 1) > cellIndex)
colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1)][brightness];
else
colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
}
} else {
colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
}
if ((cell+1) % mapWidth != 0){
if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1])){
if (getColorIndexForCell(cell + 1 + mapWidth) > cellIndex)
colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1 + mapWidth)][brightness];
else
colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
} else {
if (getColorIndexForCell(cell + 1) > cellIndex)
colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1)][brightness];
else
colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
}
} else {
colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
}
} else {
if (cell % mapWidth != 0 && getColorIndexForCell(cell - 1) > cellIndex) {
colorArray[0] = colorArray[2] = FOG_COLORS[getColorIndexForCell(cell - 1)][brightness];
} else {
colorArray[0] = colorArray[2] = FOG_COLORS[cellIndex][brightness];
}
if ((cell+1) % mapWidth != 0 && getColorIndexForCell(cell + 1) > cellIndex) {
colorArray[1] = colorArray[3] = FOG_COLORS[getColorIndexForCell(cell + 1)][brightness];
} else {
colorArray[1] = colorArray[3] = FOG_COLORS[cellIndex][brightness];
}
}
fillCell(j, i, colorArray);
} else {
fillCell(j, i, FOG_COLORS[getColorIndexForCell(cell)][brightness]);
}
cell++; cell++;
} }
} }
@ -148,6 +233,29 @@ public class FogOfWar extends Image {
} }
private int getColorIndexForCell( int cell ){
if (visible[cell]) {
return VISIBLE;
} else if (visited[cell]) {
return VISITED;
} else if (mapped[cell] ) {
return MAPPED;
} else {
return INVISIBLE;
}
}
private void fillCell( int x, int y, int[] colors){
FogTexture fog = (FogTexture)texture;
for (int i = 0; i < PIX_PER_TILE; i++){
fog.pixels.position(((y * PIX_PER_TILE)+i)*width2 + x * PIX_PER_TILE);
for (int j = 0; j < PIX_PER_TILE; j++) {
fog.pixels.put(colors[i*PIX_PER_TILE + j]);
}
}
}
private void fillCell( int x, int y, int color){ private void fillCell( int x, int y, int color){
FogTexture fog = (FogTexture)texture; FogTexture fog = (FogTexture)texture;
for (int i = 0; i < PIX_PER_TILE; i++){ for (int i = 0; i < PIX_PER_TILE; i++){

View File

@ -0,0 +1,141 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.tiles;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap;
public class WallBlockingTilemap extends Tilemap {
public static final int SIZE = 16;
private static final int BLOCK_NONE = 0;
private static final int BLOCK_RIGHT = 1;
private static final int BLOCK_LEFT = 2;
private static final int BLOCK_ALL = 3;
public WallBlockingTilemap() {
super("wall_blocking.png", new TextureFilm( "wall_blocking.png", SIZE, SIZE ) );
map( new int[Dungeon.level.length()], Dungeon.level.width());
}
@Override
public synchronized void updateMap() {
super.updateMap();
for (int i = 0; i < data.length; i++)
updateMapCell(i);
}
@Override
public synchronized void updateMapCell(int cell) {
int prev = data[cell];
int curr;
//no point in blocking tiles that are already obscured by fog
if (fogHidden(cell) && fogHidden(cell - mapWidth)){
curr = BLOCK_NONE;
} else if (DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell])) {
if (cell + mapWidth < Dungeon.level.map.length) {
if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + mapWidth])) {
if (fogHidden(cell + mapWidth)) {
curr = BLOCK_ALL;
} else {
curr = BLOCK_NONE;
}
} else {
curr = BLOCK_NONE;
if ((cell + 1) % mapWidth != 0) {
if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell + 1])){
if (fogHidden(cell + 1)) {
curr += 1;
}
} else {
if (fogHidden(cell + 1 + mapWidth)){
curr += 1;
}
}
}
if (cell % mapWidth != 0) {
if (!DungeonTileSheet.wallStitcheable.contains(Dungeon.level.map[cell - 1])){
if (fogHidden(cell - 1)) {
curr += 2;
}
} else {
if (fogHidden(cell - 1 + mapWidth)){
curr += 2;
}
}
}
}
} else {
curr = BLOCK_NONE;
if ((cell + 1) % mapWidth != 0 && fogHidden(cell + 1)) {
curr += 1;
}
if (cell % mapWidth != 0 && fogHidden(cell - 1)) {
curr += 2;
}
}
} else {
curr = BLOCK_NONE;
}
if (prev != curr){
data[cell] = curr;
super.updateMapCell(cell);
}
}
private boolean fogHidden(int cell){
if (cell < 0 || cell >= Dungeon.level.length()) return false;
return (!Dungeon.level.visited[cell] && !Dungeon.level.mapped[cell]);
}
public synchronized void updateArea(int x, int y, int w, int h) {
int cell;
for (int i = x; i <= x+w; i++){
for (int j = y; j <= y+h; j++){
cell = i + j*mapWidth;
if (cell < data.length)
updateMapCell(cell);
}
}
}
@Override
protected boolean needsRender(int pos) {
return data[pos] != BLOCK_NONE;
}
}