v0.5.0b: completely refactored custom tiled visuals

This commit is contained in:
Evan Debenham 2017-02-16 17:25:13 -05:00
parent 172e1b7c1b
commit 2d09869044
12 changed files with 268 additions and 184 deletions

View File

@ -202,8 +202,9 @@ public class Tilemap extends Visual {
}
Camera c = Camera.main;
camX = (int)c.scroll.x/16;
camY = (int)c.scroll.y/16;
//we treat the position of the tilemap as (0,0) here
camX = (int)(c.scroll.x/cellW - x/cellW);
camY = (int)(c.scroll.y/cellH - y/cellH);
camW = (int)Math.ceil(c.width/cellW);
camH = (int)Math.ceil(c.height/cellH);
@ -221,7 +222,7 @@ public class Tilemap extends Visual {
bottomRight = Math.min(camX+camW, mapWidth-1)
+ Math.min((camY+camH)*mapWidth, (mapHeight-1)*mapWidth);
if (topLeft >= size || bottomRight <= 0)
if (topLeft >= size || bottomRight < 0)
length = 0;
else
length = bottomRight - topLeft + 1;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -73,7 +73,7 @@ import com.shatteredpixel.shatteredpixeldungeon.plants.BlandfruitBush;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Game;
@ -142,7 +142,7 @@ public abstract class Level implements Bundlable {
public HashMap<Class<? extends Blob>,Blob> blobs;
public SparseArray<Plant> plants;
public SparseArray<Trap> traps;
public HashSet<CustomTileVisual> customTiles;
public HashSet<CustomTiledVisual> customTiles;
protected ArrayList<Item> itemsToSpawn = new ArrayList<>();
@ -361,7 +361,7 @@ public abstract class Level implements Bundlable {
collection = bundle.getCollection( CUSTOM_TILES );
for (Bundlable p : collection) {
CustomTileVisual vis = (CustomTileVisual)p;
CustomTiledVisual vis = (CustomTiledVisual)p;
customTiles.add( vis );
}

View File

@ -38,7 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
import com.watabou.noosa.Group;
import com.watabou.noosa.audio.Sample;
@ -340,7 +340,7 @@ public class PrisonBossLevel extends Level {
case FIGHT_ARENA:
unseal();
CustomTileVisual vis = new exitVisual();
CustomTiledVisual vis = new exitVisual();
vis.pos(11, 8);
customTiles.add(vis);
((GameScene)ShatteredPixelDungeon.scene()).addCustomTile(vis);
@ -526,15 +526,36 @@ public class PrisonBossLevel extends Level {
W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W};
public static class exitVisual extends CustomTileVisual{
public static class exitVisual extends CustomTiledVisual {
{
name = "prison exit";
private static short[] render = new short[]{
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
tx = Assets.PRISON_EXIT;
txX = txY = 0;
public exitVisual() {
super(Assets.PRISON_EXIT);
}
@Override
public CustomTiledVisual create() {
tileW = 12;
tileH = 15;
mapSimpleImage(0, 0);
return super.create();
}
//for compatibility with pre-0.4.3 saves
@ -545,8 +566,8 @@ public class PrisonBossLevel extends Level {
}
@Override
public String desc() {
return super.desc();
protected boolean needsRender(int pos) {
return render[pos] != 0;
}
}
}

View File

@ -32,7 +32,8 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.watabou.noosa.Image;
import com.watabou.utils.Random;
import java.util.ArrayList;
@ -48,7 +49,10 @@ public class MassGravePainter extends Painter {
fill(level, room, Terrain.WALL);
fill(level, room, 1, Terrain.EMPTY_SP);
level.customTiles.addAll(Bones.CustomTilesForRoom(room, Bones.class));
Bones b = new Bones();
b.setRect(room.left+1, room.top, room.width()-1, room.height());
level.customTiles.add(b);
//50% 1 skeleton, 50% 2 skeletons
for (int i = 0; i <= Random.Int(2); i++){
@ -82,22 +86,40 @@ public class MassGravePainter extends Painter {
}
}
public static class Bones extends CustomTileVisual {
{
name = Messages.get(this, "name");
public static class Bones extends CustomTiledVisual {
tx = Assets.PRISON_QUEST;
txX = 3;
txY = 0;
private static final int WALL_OVERLAP = 3;
private static final int FLOOR = 7;
public Bones(){
super(Assets.PRISON_QUEST);
}
@Override
public String desc() {
if (ofsX == 1 && ofsY == 1) {
return Messages.get(this, "desc");
} else {
return null;
public CustomTiledVisual create() {
int data[] = new int[tileW*tileH];
for (int i = 0; i < data.length; i++){
if (i < tileW) data[i] = WALL_OVERLAP;
else data[i] = FLOOR;
}
map( data, tileW );
return super.create();
}
@Override
public Image image(int tileX, int tileY) {
if (tileY == 0) return null;
else return super.image(tileX, tileY);
}
@Override
public String name(int tileX, int tileY) {
return Messages.get(this, "name");
}
@Override
public String desc(int tileX, int tileY) {
return Messages.get(this, "desc");
}
}
}

View File

@ -26,7 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.watabou.utils.Point;
public class RitualSitePainter extends Painter {
@ -56,18 +56,26 @@ public class RitualSitePainter extends Painter {
CeremonialCandle.ritualPos = c.x + (level.width() * c.y);
}
public static class RitualMarker extends CustomTileVisual{
public static class RitualMarker extends CustomTiledVisual {
{
name = Messages.get(this, "name");
tx = Assets.PRISON_QUEST;
txX = txY = 0;
tileW = tileH = 3;
public RitualMarker(){
super( Assets.PRISON_QUEST );
}
@Override
public String desc() {
public CustomTiledVisual create() {
tileH = tileW = 3;
mapSimpleImage(0, 0);
return super.create();
}
@Override
public String name(int tileX, int tileY) {
return Messages.get(this, "name");
}
@Override
public String desc(int tileX, int tileY) {
return Messages.get(this, "desc");
}
}

View File

@ -26,7 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
@ -69,24 +69,33 @@ public class WeakFloorPainter extends Painter {
well = new Point( Random.Int( 2 ) == 0 ? room.left + 1 : room.right - 1, room.top+2 );
}
set(level, well, Terrain.CHASM);
CustomTileVisual vis = new HiddenWell();
CustomTiledVisual vis = new HiddenWell();
vis.pos(well.x, well.y);
level.customTiles.add(vis);
}
public static class HiddenWell extends CustomTileVisual{
public static class HiddenWell extends CustomTiledVisual {
{
name = Messages.get(this, "name");
tx = Assets.WEAK_FLOOR;
txX = Dungeon.depth/5;
txY = 0;
public HiddenWell(){
super(Assets.WEAK_FLOOR);
}
@Override
public String desc() {
public CustomTiledVisual create() {
tileW = tileH = 1;
map( new int[]{Dungeon.depth/5}, 1);
return super.create();
}
@Override
public String name(int tileX, int tileY) {
return Messages.get(this, "name");
}
@Override
public String desc(int tileX, int tileY) {
return Messages.get(this, "desc");
}
}
}

View File

@ -25,6 +25,7 @@ import android.opengl.GLES20;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.GridTileMap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
@ -65,7 +66,6 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonWallsTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
@ -200,8 +200,8 @@ public class GameScene extends PixelScene {
customTiles = new Group();
terrain.add(customTiles);
for( CustomTileVisual visual : Dungeon.level.customTiles){
addCustomTile(visual.create());
for( CustomTiledVisual visual : Dungeon.level.customTiles){
addCustomTile(visual);
}
visualGrid = new GridTileMap();
@ -535,7 +535,7 @@ public class GameScene extends PixelScene {
}
}
public void addCustomTile( CustomTileVisual visual){
public void addCustomTile( CustomTiledVisual visual){
customTiles.add( visual.create() );
}

View File

@ -0,0 +1,131 @@
/*
* 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.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
public abstract class CustomTiledVisual extends Tilemap implements Bundlable {
protected static final int SIZE = DungeonTilemap.SIZE;
public int tileX, tileY; //x and y coords for texture within a level
public int tileW = 1, tileH = 1; //width and height in tiles
public CustomTiledVisual(Object tx) {
super(tx, new TextureFilm( tx, SIZE, SIZE ) );
}
public void pos(int pos) {
pos( pos%Dungeon.level.width(), pos/Dungeon.level.width() );
}
public void pos(int tileX, int tileY){
this.tileX = tileX;
this.tileY = tileY;
}
public void setRect(int topLeft, int bottomRight){
setRect( topLeft%Dungeon.level.width(),
topLeft/Dungeon.level.width(),
bottomRight%Dungeon.level.width() - topLeft%Dungeon.level.width(),
bottomRight/Dungeon.level.width() - topLeft/Dungeon.level.width()
);
}
public void setRect(int tileX, int tileY, int tileW, int tileH){
this.tileX = tileX;
this.tileY = tileY;
this.tileW = tileW;
this.tileH = tileH;
}
public CustomTiledVisual create(){
x = tileX*SIZE;
y = tileY*SIZE;
return this;
}
//assumes that width and height are already set.
protected void mapSimpleImage(int txX, int txY){
int data[] = new int[tileW * tileH];
int texTileWidth = texture.width/SIZE;
int x = txX, y = txY;
for (int i = 0; i < data.length; i++){
data[i] = x + (texTileWidth*y);
x++;
if ((x - txX) == tileW){
x = txX;
y++;
}
}
map(data, tileW);
}
//x and y here are the coordinates tapped within the tile visual
public Image image(int tileX, int tileY){
if (!needsRender(tileX + mapWidth*tileY)){
return null;
} else {
Image img = new Image(texture);
img.frame(tileset.get(data[tileX + mapWidth * tileY]));
return img;
}
}
public String name(int tileX, int tileY){
return null;
}
public String desc(int tileX, int tileY){
return null;
}
private static final String TILE_X = "tileX";
private static final String TILE_Y = "tileY";
private static final String TILE_W = "tileW";
private static final String TILE_H = "tileH";
@Override
public void restoreFromBundle(Bundle bundle) {
tileX = bundle.getInt(TILE_X);
tileY = bundle.getInt(TILE_Y);
tileW = bundle.getInt(TILE_W);
tileH = bundle.getInt(TILE_H);
}
@Override
public void storeInBundle(Bundle bundle) {
bundle.put(TILE_X, tileX);
bundle.put(TILE_Y, tileY);
bundle.put(TILE_W, tileW);
bundle.put(TILE_H, tileH);
}
}

View File

@ -1,124 +0,0 @@
/*
* 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.ui;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Room;
import com.watabou.noosa.Image;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
import java.util.ArrayList;
public abstract class CustomTileVisual extends Image implements Bundlable {
protected static final int TILE_SIZE = 16;
public String name;
protected String tx; //string for resource file
protected int txX, txY; //position(in tiles) within resource file
//bundleable offsets from the standard texture xy, useful for mapping larger than 1x1 textures to many tiles
//(e.g. mapping a 3x3 texture to a room, where the corners are walls and the center is the floor)
protected int ofsX = 0, ofsY = 0;
public int tileX, tileY; //x and y coords for texture within a level
public int tileW = 1, tileH = 1; //width and height in tiles
public void pos(int pos) {
pos( pos% Dungeon.level.width(), pos/Dungeon.level.width() );
}
public void pos(int tileX, int tileY){
this.tileX = tileX;
this.tileY = tileY;
}
public String desc(){
return null;
}
public CustomTileVisual create() {
texture(tx);
frame(texture.uvRect((txX + ofsX) * TILE_SIZE, (txY + ofsY) * TILE_SIZE,
(txX + ofsX + tileW) * TILE_SIZE, (txY + ofsY + tileH) * TILE_SIZE));
x = tileX*TILE_SIZE;
y = tileY*TILE_SIZE;
return this;
}
//returns a number of 1x1 tiles to fill a room, based on a 3x3 texture, not dissimilar to a ninepatch.
public static ArrayList<CustomTileVisual> CustomTilesForRoom(Room r, Class<?extends CustomTileVisual> c){
ArrayList<CustomTileVisual> result = new ArrayList<>();
try {
for (int x = r.left; x <= r.right; x++) {
for (int y = r.top; y <= r.bottom; y++) {
CustomTileVisual vis = c.newInstance();
if (x == r.right) vis.ofsX = 2;
else if (x != r.left) vis.ofsX = 1;
if (y == r.bottom) vis.ofsY = 2;
else if (y != r.top) vis.ofsY = 1;
vis.pos(x, y);
result.add(vis);
}
}
} catch (Exception e) {
throw new RuntimeException("Something went wrong while making a bunch of tile visuals for a room!", e);
}
return result;
}
private static final String TILE_X = "tileX";
private static final String TILE_Y = "tileY";
private static final String OFS_X = "ofsX";
private static final String OFS_Y = "ofsY";
@Override
public void restoreFromBundle(Bundle bundle) {
tileX = bundle.getInt(TILE_X);
tileY = bundle.getInt(TILE_Y);
//if these weren't stored they will default to 0
ofsX = bundle.getInt(OFS_X);
ofsY = bundle.getInt(OFS_Y);
}
@Override
public void storeInBundle(Bundle bundle) {
bundle.put(TILE_X, tileX);
bundle.put(TILE_Y, tileY);
//don't need to store this in all cases
if (ofsX != 0 || ofsY != 0){
bundle.put(OFS_X, ofsX);
bundle.put(OFS_Y, ofsY);
}
}
}

View File

@ -21,13 +21,13 @@
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.CustomTileVisual;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextMultiline;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.noosa.Image;
@ -49,14 +49,17 @@ public class WndInfoCell extends Window {
tile = Terrain.CHASM;
}
CustomTileVisual vis = null;
CustomTiledVisual customTile = null;
Image customImage = null;
int x = cell % Dungeon.level.width();
int y = cell / Dungeon.level.width();
for (CustomTileVisual i : Dungeon.level.customTiles){
for (CustomTiledVisual i : Dungeon.level.customTiles){
if ((x >= i.tileX && x < i.tileX+i.tileW) &&
(y >= i.tileY && y < i.tileY+i.tileH)){
if (i.desc() != null) {
vis = i;
if ((customImage = i.image(x - i.tileX, y - i.tileY)) != null) {
x -= i.tileX;
y -= i.tileY;
customTile = i;
break;
}
}
@ -66,10 +69,23 @@ public class WndInfoCell extends Window {
String desc = "";
IconTitle titlebar = new IconTitle();
if (vis != null){
titlebar.icon(new Image(vis));
titlebar.label(vis.name);
desc += vis.desc();
if (customTile != null){
titlebar.icon(customImage);
String customName = customTile.name(x, y);
if (customName != null) {
titlebar.label(customName);
} else {
titlebar.label(Dungeon.level.tileName(tile));
}
String customDesc = customTile.desc(x, y);
if (customDesc != null) {
desc += customDesc;
} else {
desc += Dungeon.level.tileDesc(tile);
}
} else {
if (tile == Terrain.WATER) {