Remade item and tile basic system.

Still not funcitonal but the shape is final. Sort of.
This commit is contained in:
Ondřej Hruška
2014-04-19 18:32:14 +02:00
parent ccbc95c74a
commit 65ad97994b
176 changed files with 1561 additions and 1616 deletions
+5 -7
View File
@@ -24,9 +24,8 @@ import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
import mightypork.rogue.screens.test_render.ScreenTestRender;
import mightypork.rogue.world.WorldMap;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.ItemData;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileData;
import mightypork.rogue.world.tile.TileItems;
import mightypork.util.control.eventbus.EventBus;
import mightypork.util.control.eventbus.events.Event;
import mightypork.util.files.ion.Ion;
@@ -108,11 +107,10 @@ public final class App extends BaseApp {
@Override
protected void preInit()
{
Ion.registerIonizable(Tile.ION_MARK, Tile.class); // 700
Ion.registerIonizable(Item.ION_MARK, Item.class); // 701
Ion.registerIonizable(WorldMap.ION_MARK, WorldMap.class); // 702
Ion.registerIonizable(TileData.ION_MARK, TileData.class); // 703
Ion.registerIonizable(ItemData.ION_MARK, ItemData.class); // 704
Ion.registerIonizable(Tile.ION_MARK, Tile.class);
Ion.registerIonizable(Item.ION_MARK, Item.class);
Ion.registerIonizable(WorldMap.ION_MARK, WorldMap.class);
Ion.registerIonizable(TileItems.ION_MARK, TileItems.class); // used by tile to store contained items
}
+4 -2
View File
@@ -19,7 +19,8 @@ import mightypork.util.logging.Log;
public final class MainLoop extends GameLoop implements ActionRequest.Listener {
public MainLoop(BaseApp app) {
public MainLoop(BaseApp app)
{
super(app);
}
@@ -83,7 +84,8 @@ public final class MainLoop extends GameLoop implements ActionRequest.Listener {
private final Screenshot scr;
public TaskTakeScreenshot() {
public TaskTakeScreenshot()
{
scr = getDisplay().takeScreenshot();
}
+2 -2
View File
@@ -67,7 +67,7 @@ public final class Res {
texture = textures.loadTexture("test.kitten", "/res/img/kitten.png", FilterMode.LINEAR, WrapMode.CLAMP);
texture = textures.loadTexture("gui1", "/res/img/gui1.png", FilterMode.NEAREST, WrapMode.CLAMP);
QuadGrid gui = texture.grid(4, 4);
final QuadGrid gui = texture.grid(4, 4);
textures.addQuad("item_frame", gui.makeQuad(0, 0));
textures.addQuad("sword", gui.makeQuad(1, 0));
textures.addQuad("meat", gui.makeQuad(2, 0));
@@ -78,7 +78,7 @@ public final class Res {
textures.addQuad("panel", gui.makeQuad(0, 3.75, 4, .25));
texture = textures.loadTexture("tiles", "/res/img/map_tiles.png", FilterMode.NEAREST, WrapMode.CLAMP);
QuadGrid tiles = texture.grid(32, 32);
final QuadGrid tiles = texture.grid(32, 32);
textures.addSheet("tile.mossy_bricks.wall", tiles.makeSheet(4, 0, 7, 1));
textures.addSheet("tile.mossy_bricks.floor", tiles.makeSheet(16, 5, 7, 1));
@@ -16,7 +16,8 @@ public class ActionRequest implements Event<ActionRequest.Listener> {
private final RequestType type;
public ActionRequest(RequestType request) {
public ActionRequest(RequestType request)
{
type = request;
}
@@ -47,7 +47,8 @@ public class CrossfadeOverlay extends Overlay implements CrossfadeRequest.Listen
};
public CrossfadeOverlay(AppAccess app) {
public CrossfadeOverlay(AppAccess app)
{
super(app);
final QuadPainter qp = new QuadPainter(color);
@@ -15,7 +15,8 @@ public class CrossfadeRequest implements Event<CrossfadeRequest.Listener> {
/**
* @param screen screen key to show. Null = exit the app.
*/
public CrossfadeRequest(String screen) {
public CrossfadeRequest(String screen)
{
super();
this.screen = screen;
}
+2 -1
View File
@@ -22,7 +22,8 @@ public class FpsOverlay extends Overlay {
TextPainter tp;
public FpsOverlay(AppAccess screen) {
public FpsOverlay(AppAccess screen)
{
super(screen);
/*
@@ -16,7 +16,8 @@ import mightypork.util.math.color.PAL16;
public class GameGui extends ScreenLayer {
public GameGui(Screen screen) {
public GameGui(Screen screen)
{
super(screen);
final Num h = root.height();
@@ -28,7 +28,8 @@ public class HeartBar extends VisualComponent {
* @param img_off
* @param align
*/
public HeartBar(int total, int active, TxQuad img_on, TxQuad img_off, AlignX align) {
public HeartBar(int total, int active, TxQuad img_on, TxQuad img_off, AlignX align)
{
super();
this.total = total;
this.active = active;
@@ -24,7 +24,8 @@ public class NavItemSlot extends ClickableComponent implements MouseMotionEvent.
private boolean wasInside = false;
public NavItemSlot(TxQuad image) {
public NavItemSlot(TxQuad image)
{
this.image = image;
this.frame = Res.getTxQuad("item_frame");
@@ -7,7 +7,8 @@ import mightypork.gamecore.gui.screens.LayeredScreen;
public class ScreenGame extends LayeredScreen {
public ScreenGame(AppAccess app) {
public ScreenGame(AppAccess app)
{
super(app);
addLayer(new GameGui(this));
@@ -31,7 +31,8 @@ class MenuButton extends ClickableComponent {
private final NumVar alphaMulSh = Num.makeVar(SH_ALPHA_OFF);
public MenuButton(String text, Color color) {
public MenuButton(String text, Color color)
{
this.color = color.withAlpha(alphaMul);
this.painter = new TextPainter(font, AlignX.CENTER, this.color, text);
@@ -17,7 +17,8 @@ import mightypork.util.math.color.PAL16;
class MenuLayer extends ScreenLayer {
public MenuLayer(BaseScreen screen) {
public MenuLayer(BaseScreen screen)
{
super(screen);
init();
@@ -7,7 +7,8 @@ import mightypork.gamecore.gui.screens.LayeredScreen;
public class ScreenMainMenu extends LayeredScreen {
public ScreenMainMenu(AppAccess app) {
public ScreenMainMenu(AppAccess app)
{
super(app);
addLayer(new MenuLayer(this));
@@ -23,7 +23,8 @@ public class BouncyBox extends VisualComponent implements Updateable {
private final NumAnimated pos = new NumAnimated(0, Easing.BOUNCE_OUT);
public BouncyBox() {
public BouncyBox()
{
super();
enableCaching(true);
@@ -23,7 +23,8 @@ public class LayerBouncyBoxes extends ScreenLayer {
private RowHolder layout;
public LayerBouncyBoxes(BaseScreen screen) {
public LayerBouncyBoxes(BaseScreen screen)
{
super(screen);
bindKey(new KeyStroke(true, Keys.RIGHT), new Runnable() {
@@ -10,7 +10,8 @@ public class ScreenTestBouncy extends LayeredScreen {
private final LayerBouncyBoxes layer;
public ScreenTestBouncy(AppAccess app) {
public ScreenTestBouncy(AppAccess app)
{
super(app);
layer = new LayerBouncyBoxes(this);
@@ -9,7 +9,8 @@ import mightypork.util.math.color.Color;
public class LayerColor extends ScreenLayer {
public LayerColor(BaseScreen screen, Color color) {
public LayerColor(BaseScreen screen, Color color)
{
super(screen);
root.add(new QuadPainter(color));
@@ -29,7 +29,8 @@ public class LayerFlyingCat extends ScreenLayer implements MouseButtonEvent.List
private final Random rand = new Random();
public LayerFlyingCat(BaseScreen screen) {
public LayerFlyingCat(BaseScreen screen)
{
super(screen);
// timing
@@ -12,7 +12,8 @@ import mightypork.rogue.events.ActionRequest.RequestType;
public class ScreenTestCat extends LayeredScreen {
public ScreenTestCat(AppAccess app) {
public ScreenTestCat(AppAccess app)
{
super(app);
addLayer(new LayerFlyingCat(this));
@@ -14,7 +14,8 @@ public class LayerTestGradient extends ScreenLayer {
private final RectBound pos2;
public LayerTestGradient(BaseScreen screen) {
public LayerTestGradient(BaseScreen screen)
{
super(screen);
pos1 = root.topEdge().growDown(64);
@@ -7,7 +7,8 @@ import mightypork.gamecore.gui.screens.LayeredScreen;
public class ScreenTestRender extends LayeredScreen {
public ScreenTestRender(AppAccess app) {
public ScreenTestRender(AppAccess app)
{
super(app);
addLayer(new LayerTestGradient(this));
-130
View File
@@ -1,130 +0,0 @@
package mightypork.rogue.world;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.control.timing.Updateable;
import mightypork.util.files.ion.Ion;
import mightypork.util.files.ion.Ionizable;
/**
* Abstract entity
*
* @author MightyPork
* @param <D> Data object class
* @param <M> Model class
* @param <R> Render context class
*/
public abstract class Entity<D, M extends EntityModel<D, R>, R extends RectBound> implements Ionizable, Updateable {
protected M model;
protected D data;
/**
* Used by Ion for loading.
*/
public Entity() {
}
/**
* Create from model
*
* @param model model
*/
public Entity(M model) {
setModel(model);
}
@Override
public final void loadFrom(InputStream in) throws IOException
{
final int id = Ion.readInt(in);
setModel(id);
model.load(data, in); // load saved data
}
private void initData()
{
data = model.createData();
}
/**
* @return data
*/
public final D getData()
{
return data;
}
/**
* @return entity model
*/
public final M getModel()
{
return model;
}
/**
* Assign a model.
*
* @param id model id
*/
public final void setModel(int id)
{
setModel(getModelForId(id));
}
/**
* Assign a model.
*
* @param model model
*/
public final void setModel(M model)
{
this.model = model;
initData();
}
@Override
public final void saveTo(OutputStream out) throws IOException
{
Ion.writeInt(out, model.getId());
model.save(data, out);
}
public void render(R context)
{
model.render(data, context);
}
@Override
public void update(double delta)
{
model.update(data, delta);
}
/**
* Get model for ID
*
* @param id id
* @return model for the ID
*/
protected abstract M getModelForId(int id);
}
@@ -1,75 +0,0 @@
package mightypork.rogue.world;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mightypork.util.annotations.DefaultImpl;
import mightypork.util.constraints.rect.proxy.RectBound;
/**
* Entity model. Provides concrete implementation to an entity, working with
* it's data object.
*
* @author MightyPork
* @param <D> Data object class
* @param <R> Render context class
*/
public abstract class EntityModel<D, R extends RectBound> {
/** Model id */
private final int id;
/**
* Create a model. The caller must then register this instance in a Model
* registry for the particular entity type.
*
* @param id model id
*/
public EntityModel(int id) {
this.id = id;
}
/**
* Get the model id.
*
* @return id
*/
public final int getId()
{
return id;
}
/**
* Create a data object and populate it with default values.<br>
* It's allowed to return null for no data.
*
* @return data object
*/
public abstract D createData();
/**
* Render the item according to given context.
*
* @param data rendered item
* @param context rendering context
*/
public abstract void render(D data, R context);
/**
* Update the item (animation, decay etc)
*
* @param item item to update
* @param delta delta time
*/
@DefaultImpl
public abstract void update(D item, double delta);
}
+26 -22
View File
@@ -7,7 +7,9 @@ import java.io.OutputStream;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileGrid;
import mightypork.rogue.world.tile.Tiles;
import mightypork.util.files.ion.Ion;
import mightypork.util.files.ion.IonConstructor;
import mightypork.util.files.ion.Ionizable;
@@ -21,12 +23,14 @@ public class WorldMap implements TileGrid, Ionizable {
private Tile[][] tiles;
public WorldMap() {
// constructor for ION
@IonConstructor
public WorldMap()
{
}
public WorldMap(int width, int height) {
public WorldMap(int width, int height)
{
this.width = width;
this.height = height;
buildArray();
@@ -36,6 +40,12 @@ public class WorldMap implements TileGrid, Ionizable {
private void buildArray()
{
this.tiles = new Tile[height][width];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
tiles[y][x] = Tiles.NONE.create();
}
}
}
@@ -73,35 +83,27 @@ public class WorldMap implements TileGrid, Ionizable {
@Override
public void loadFrom(InputStream in) throws IOException
public void load(InputStream in) throws IOException
{
width = Ion.readInt(in);
height = Ion.readInt(in);
buildArray();
while (true) {
final short mark = Ion.readMark(in);
if (mark == Ion.END) {
break;
} else if (mark == Ion.ENTRY) {
final int x = Ion.readInt(in);
final int y = Ion.readInt(in);
final Tile tile = (Tile) Ion.readObject(in);
setTile(tile, x, y);
} else {
throw new IOException("Invalid mark encountered while reading tile map.");
}
while (Ion.hasNextEntry(in)) {
final int x = Ion.readInt(in);
final int y = Ion.readInt(in);
final Tile tile = (Tile) Ion.readObject(in);
setTile(tile, x, y);
}
}
@Override
public void saveTo(OutputStream out) throws IOException
public void save(OutputStream out) throws IOException
{
Ion.writeInt(out, width);
Ion.writeInt(out, height);
@@ -109,7 +111,8 @@ public class WorldMap implements TileGrid, Ionizable {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
final Tile t = getTile(x, y);
if (t != null) {
// skip null tiles
if (!t.getModel().isNullTile()) {
Ion.writeMark(out, Ion.ENTRY);
Ion.writeInt(out, x);
Ion.writeInt(out, y);
@@ -118,6 +121,7 @@ public class WorldMap implements TileGrid, Ionizable {
}
}
// end of sequence
Ion.writeMark(out, Ion.END);
}
+79 -10
View File
@@ -1,34 +1,87 @@
package mightypork.rogue.world.item;
import mightypork.rogue.world.Entity;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mightypork.rogue.world.tile.TileRenderContext;
import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.control.timing.Animator;
import mightypork.util.control.timing.AnimatorBounce;
import mightypork.util.control.timing.Updateable;
import mightypork.util.files.ion.Ion;
import mightypork.util.files.ion.IonBundle;
import mightypork.util.files.ion.IonConstructor;
import mightypork.util.files.ion.Ionizable;
import mightypork.util.math.Easing;
public final class Item extends Entity<ItemData, ItemModel, RectBound> {
public class Item implements Updateable, Ionizable {
public static final short ION_MARK = 701;
private transient ItemModel model;
public transient Object modelData;
public transient Animator anim;
public Item() {
super();
public int id;
public boolean[] flags;
public int[] numbers;
public Item(int id)
{
this(Items.get(id));
}
public Item(ItemModel model) {
super(model);
@IonConstructor
public Item()
{
}
public Item(int id) {
super(Items.get(id));
public Item(ItemModel model)
{
this.model = model;
this.id = model.id;
this.anim = new AnimatorBounce(2, Easing.SINE_BOTH);
}
public void render(RectBound context)
{
model.render(this, context);
}
@Override
protected ItemModel getModelForId(int id)
public void save(OutputStream out) throws IOException
{
return Items.get(id);
final IonBundle ib = new IonBundle();
ib.put("id", id);
ib.put("flags", flags);
ib.put("numbers", numbers);
Ion.writeObject(out, ib);
}
@Override
public void load(InputStream in) throws IOException
{
final IonBundle ib = (IonBundle) Ion.readObject(in);
id = ib.get("id", id);
flags = ib.get("flags", flags);
numbers = ib.get("numbers", numbers);
if (id != model.id) {
model = Items.get(id);
}
}
@@ -38,4 +91,20 @@ public final class Item extends Entity<ItemData, ItemModel, RectBound> {
return ION_MARK;
}
@Override
public void update(double delta)
{
if (anim != null) {
anim.update(delta);
}
}
public void renderOnTile(TileRenderContext context)
{
model.renderOnTile(this, context);
}
}
@@ -1,13 +0,0 @@
package mightypork.rogue.world.item;
/**
* Item data object.
*
* @author MightyPork
*/
public final class ItemData {
public static final int ION_MARK = 704;
}
+40 -9
View File
@@ -1,19 +1,50 @@
package mightypork.rogue.world.item;
import mightypork.rogue.world.EntityModel;
import mightypork.rogue.world.tile.TileRenderContext;
import mightypork.util.annotations.DefaultImpl;
import mightypork.util.constraints.num.proxy.NumBoundAdapter;
import mightypork.util.constraints.rect.Rect;
import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.constraints.rect.proxy.RectBoundAdapter;
/**
* An item model
*
* @author MightyPork
*/
public abstract class ItemModel extends EntityModel<ItemData, RectBound> {
public abstract class ItemModel {
public ItemModel(int id) {
super(id);
public final int id;
private final RectBoundAdapter tileRect = new RectBoundAdapter();
private final NumBoundAdapter yOffset = new NumBoundAdapter();
private final Rect itemRect = tileRect.shrink(tileRect.height().perc(10)).moveY(yOffset.neg());
public ItemModel(int id)
{
Items.register(id, this);
this.id = id;
}
/**
* @return new tile with this model
*/
@DefaultImpl
public Item create()
{
return new Item(this);
}
public abstract void render(Item item, RectBound context);
public void renderOnTile(Item item, TileRenderContext context)
{
tileRect.setRect(context.getRect());
yOffset.setNum(item.anim);
render(item, itemRect);
}
}
+10 -8
View File
@@ -1,25 +1,27 @@
package mightypork.rogue.world.item;
import java.util.HashMap;
import java.util.Map;
/**
* Item registry
*
* @author MightyPork
*/
public final class Items {
private static final Map<Integer, ItemModel> registered = new HashMap<>();
private static final ItemModel[] items = new ItemModel[256];
static void register(int id, ItemModel model)
{
if (registered.containsKey(id)) throw new IllegalArgumentException("Item ID " + id + " already in use.");
registered.put(id, model);
if (id < 0 || id >= items.length) if (items[id] != null) throw new IllegalArgumentException("Item ID " + id + " already in use.");
items[id] = model;
}
public static ItemModel get(int id)
{
final ItemModel m = registered.get(id);
final ItemModel m = items[id];
if (m == null) throw new IllegalArgumentException("No item with ID " + id + ".");
return m;
}
+74 -76
View File
@@ -1,42 +1,94 @@
package mightypork.rogue.world.tile;
import mightypork.rogue.world.Entity;
import mightypork.rogue.world.item.Item;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mightypork.util.control.timing.Animator;
import mightypork.util.control.timing.Updateable;
import mightypork.util.files.ion.Ion;
import mightypork.util.files.ion.IonBundle;
import mightypork.util.files.ion.IonConstructor;
import mightypork.util.files.ion.Ionizable;
/**
* Concrete tile in the world.
*
* @author MightyPork
*/
public final class Tile extends Entity<TileData, TileModel, TileRenderContext> {
public final class Tile implements Ionizable, Updateable {
public static final short ION_MARK = 700;
/** Whether the tile is occupied by an entity */
private transient boolean occupied;
private transient TileModel model;
public transient Object modelData;
public transient Animator anim;
public int id;
public TileItems items;
public boolean[] flags;
public int[] numbers;
public Tile() {
super();
public Tile(int id)
{
this(Tiles.get(id));
}
public Tile(TileModel model) {
super(model);
@IonConstructor
public Tile()
{
}
public Tile(int id) {
super(Tiles.get(id));
public Tile(TileModel model)
{
this.model = model;
this.id = model.id;
this.items = new TileItems();
}
public void render(TileRenderContext context)
{
model.render(this, context);
if (!items.isEmpty()) {
items.peek().renderOnTile(context);
}
}
@Override
protected TileModel getModelForId(int id)
public void save(OutputStream out) throws IOException
{
return Tiles.get(id);
if (model.isNullTile()) throw new RuntimeException("Cannot save null tile.");
final IonBundle ib = new IonBundle();
ib.put("id", id);
ib.put("flags", flags);
ib.put("numbers", numbers);
ib.put("items", items);
Ion.writeObject(out, ib);
}
@Override
public void load(InputStream in) throws IOException
{
final IonBundle ib = (IonBundle) Ion.readObject(in);
id = ib.get("id", id);
flags = ib.get("flags", flags);
numbers = ib.get("numbers", numbers);
items = ib.get("items", items);
// renew model
if (model == null || id != model.id) {
model = Tiles.get(id);
}
}
@@ -47,72 +99,18 @@ public final class Tile extends Entity<TileData, TileModel, TileRenderContext> {
}
@Override
public void render(TileRenderContext context)
{
super.render(context);
// render laying-on-top item
if (!data.items.isEmpty()) {
final Item item = data.items.peek();
item.render(context.getRect());
}
}
@Override
public void update(double delta)
{
super.update(delta);
// update laying-on-top item
if (!data.items.isEmpty()) {
final Item item = data.items.peek();
item.update(delta);
if (!items.isEmpty()) {
items.peek().update(delta);
}
}
/**
* Try to reveal secrets of this tile
*/
public void search()
public TileModel getModel()
{
model.search(data);
return model;
}
/**
* @return true if a mob can walk through
*/
public boolean isWalkable()
{
return model.isWalkable(data);
}
public boolean hasItem()
{
return !data.items.isEmpty();
}
public Item removeItem()
{
if(!hasItem()) return null;
return data.items.pop();
}
public boolean isOccupied()
{
return occupied;
}
public void setOccupied(boolean occupied)
{
this.occupied = occupied;
}
}
@@ -1,54 +0,0 @@
package mightypork.rogue.world.tile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Stack;
import mightypork.rogue.world.item.Item;
import mightypork.util.files.ion.IonList;
import mightypork.util.files.ion.Ionizable;
/**
* Tile data object.
*
* @author MightyPork
*/
public final class TileData implements Ionizable {
public static final short ION_MARK = 703;
/** Items dropped onto this tile */
public final Stack<Item> items = new Stack<>();
public int id;
public boolean[] flags;
public int[] numbers;
@Override
public void loadFrom(InputStream in) throws IOException
{
}
@Override
public void saveTo(OutputStream out) throws IOException
{
}
@Override
public short getIonMark()
{
return 0;
}
public Tile toTile() {
Tile t = new Tile(Tiles.get(id));
t.s
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.tile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Stack;
import mightypork.rogue.world.item.Item;
import mightypork.util.files.ion.Ion;
import mightypork.util.files.ion.Ionizable;
public class TileItems extends Stack<Item> implements Ionizable {
public static final short ION_MARK = 703;
@Override
public void load(InputStream in) throws IOException
{
Ion.readSequence(in, this);
}
@Override
public void save(OutputStream out) throws IOException
{
Ion.writeSequence(out, this);
}
@Override
public short getIonMark()
{
return ION_MARK;
}
}
+38 -27
View File
@@ -1,51 +1,62 @@
package mightypork.rogue.world.tile;
import mightypork.rogue.world.EntityModel;
import mightypork.util.annotations.DefaultImpl;
public abstract class TileModel extends EntityModel<TileData, TileRenderContext> {
/**
* Singleton-like tile implementation
*
* @author MightyPork
*/
public abstract class TileModel {
public TileModel(int id) {
super(id);
Tiles.register(id, this);
}
/** Model ID */
public final int id;
@Override
public TileData createData()
public TileModel(int id)
{
return null;
Tiles.register(id, this);
this.id = id;
}
/**
* Test if this tile type is potentially walkable. Used during world
* generation.
*
* @return can be walked through (if discovered / open)
*/
public abstract boolean isWalkable();
/**
* Try to reveal a secret.
*
* @param data tile data
* @return new tile with this model
*/
@DefaultImpl
public void search(TileData data)
public Tile create()
{
// do nothing.
return new Tile(this);
}
/**
* Check if a mob can walk through.
* Render the tile.
*
* @param data tile data
* @return is walkable
* @param tile
* @param context
*/
public abstract boolean isWalkable(TileData data);
public abstract void render(Tile tile, TileRenderContext context);
/**
* @param tile
* @return is walkable at the current conditions
*/
public abstract boolean isWalkable(Tile tile);
/**
* @return true if the tile can be walkable at some conditions
*/
public abstract boolean isPotentiallyWalkable();
public boolean isNullTile()
{
return false;
}
}
@@ -16,7 +16,8 @@ public final class TileRenderContext implements RectBound {
public int x, y;
public TileRenderContext(TileGrid map, Rect drawArea, long renderNoiseSeed) {
public TileRenderContext(TileGrid map, Rect drawArea, long renderNoiseSeed)
{
this.map = map;
this.tiler = drawArea.tiles(map.getWidth(), map.getHeight());
this.noise = new NoiseGen(0.2, 0, 0.5, 1, renderNoiseSeed);
@@ -45,7 +46,7 @@ public final class TileRenderContext implements RectBound {
/**
* @return per-coord noise value 0..1
*/
public double getNoise()
public double getTileNoise()
{
return noise.valueAt(x, y);
}
@@ -56,4 +57,10 @@ public final class TileRenderContext implements RectBound {
this.x = x;
this.y = y;
}
public void renderTile(Tile t)
{
t.render(this);
}
}
+23 -7
View File
@@ -1,26 +1,42 @@
package mightypork.rogue.world.tile;
import java.util.HashMap;
import java.util.Map;
import mightypork.rogue.world.tile.models.Floor;
import mightypork.rogue.world.tile.models.NullTile;
/**
* Tile registry
*
* @author MightyPork
*/
public final class Tiles {
private static final Map<Integer, TileModel> registered = new HashMap<>();
private static final TileModel[] tiles = new TileModel[256];
public static final TileModel NONE = new NullTile(0);
public static final TileModel FLOOR_MOSSY = new Floor(1, "tile.mossy_bricks.floor");
public static final TileModel WALL_MOSSY = new Floor(2, "tile.mossy_bricks.wall");
static void register(int id, TileModel model)
{
if (registered.containsKey(id)) throw new IllegalArgumentException("Tile ID " + id + " already in use.");
registered.put(id, model);
if (id < 0 || id >= tiles.length) if (tiles[id] != null) {
throw new IllegalArgumentException("Tile ID " + id + " already in use.");
}
tiles[id] = model;
}
public static TileModel get(int id)
{
final TileModel m = registered.get(id);
if (m == null) throw new IllegalArgumentException("No tile with ID " + id + ".");
final TileModel m = tiles[id];
if (m == null) {
throw new IllegalArgumentException("No tile with ID " + id + ".");
}
return m;
}
}
@@ -1,15 +0,0 @@
package mightypork.rogue.world.tile.impl;
public class SimpleFloor extends SimpleTile {
public SimpleFloor(int id, String sheetKey) {
super(id, sheetKey);
}
@Override
public boolean isWalkable()
{
return true;
}
}
@@ -1,71 +0,0 @@
package mightypork.rogue.world.tile.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mightypork.gamecore.render.DisplaySystem;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxSheet;
import mightypork.rogue.Res;
import mightypork.rogue.world.tile.TileData;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderContext;
import mightypork.util.annotations.DefaultImpl;
public abstract class SimpleTile extends TileModel {
private TxSheet sheet;
public SimpleTile(int id, String sheetKey) {
super(id);
this.sheet = Res.getTxSheet(sheetKey);
}
@Override
@DefaultImpl
public void load(TileData data, InputStream in) throws IOException
{
// do nothing
}
@Override
@DefaultImpl
public void save(TileData data, OutputStream out) throws IOException
{
// do nothing
}
@Override
public void render(TileData data, TileRenderContext context)
{
// TODO worldmap should take care of this and break the row drawing when it encounters end of screen etc
// not in screen -> no draw
if (!context.getRect().intersectsWith(DisplaySystem.getBounds())) return;
Render.quadTextured(context.getRect(), sheet.getRandomQuad(context.getNoise()));
}
@Override
@DefaultImpl
public void update(TileData item, double delta)
{
// do nothing
}
@Override
@DefaultImpl
public boolean isWalkable(TileData data)
{
return isWalkable();
}
}
@@ -1,16 +0,0 @@
package mightypork.rogue.world.tile.impl;
public class SimpleWall extends SimpleTile {
public SimpleWall(int id, String sheetKey) {
super(id, sheetKey);
}
@Override
public boolean isWalkable()
{
return false;
}
}
@@ -0,0 +1,18 @@
package mightypork.rogue.world.tile.models;
public class Floor extends SimpleTile {
public Floor(int id, String sheetKey)
{
super(id, sheetKey);
}
@Override
public boolean isPotentiallyWalkable()
{
return true;
}
}
@@ -0,0 +1,57 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderContext;
public class NullTile extends TileModel {
private Tile inst;
public NullTile(int id)
{
super(id);
}
@Override
public void render(Tile tile, TileRenderContext context)
{
}
@Override
public boolean isWalkable(Tile tile)
{
return false;
}
@Override
public boolean isPotentiallyWalkable()
{
return true;
}
@Override
public boolean isNullTile()
{
return true;
}
@Override
public Tile create()
{
if (inst == null) {
inst = new Tile(this);
}
return inst;
}
}
@@ -0,0 +1,43 @@
package mightypork.rogue.world.tile.models;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxSheet;
import mightypork.rogue.Res;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderContext;
import mightypork.util.annotations.DefaultImpl;
public abstract class SimpleTile extends TileModel {
protected final TxSheet sheet;
public SimpleTile(int id, String sheetKey)
{
super(id);
this.sheet = Res.getTxSheet(sheetKey);
}
@Override
public void render(Tile tile, TileRenderContext context)
{
Render.quadTextured(context.getRect(), sheet.getRandomQuad(context.getTileNoise()));
}
@Override
@DefaultImpl
public boolean isWalkable(Tile tile)
{
return isPotentiallyWalkable();
}
@Override
public abstract boolean isPotentiallyWalkable();
}
@@ -0,0 +1,18 @@
package mightypork.rogue.world.tile.models;
public class Wall extends SimpleTile {
public Wall(int id, String sheetKey)
{
super(id, sheetKey);
}
@Override
public boolean isPotentiallyWalkable()
{
return false;
}
}