Just store the position in the entity object as well. For dynamic objects I am using both arrays and I store the position of the object inside the object as well for various reasons. One reason is to use the array for drawing, if I only want to draw from coordinate (10,10) to (26, 19) because my screen does not reach the others anyway I can use the various arrays. But if I have an object and want to know it's position I have to iterate the whole array if I do not store it inside it.
Sometimes I just use vectors for storing the position but a much better way is to create your own point/coordinate class with equals and hashtag overrides to compare. You can put (static) methods in this class to convert from screen and camera coordinates which are often vectors to your points for easy shifting between them.
You know what? Here is a basic one I use:
public class Point {
public int x;
public int y;
/**
* Creates point
* @param x X - coordinate
* @param y Y - coordinate
*/
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
/**
* Creates point from world vector
* @param v World vector
*/
public Point(Vector2 v)
{
this.x = (int)(v.x / tileWidth);
this.y = (int)(v.y / tileHeight);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
if (x != point.x) return false;
if (y != point.y) return false;
return true;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
@Override
public String toString() {
return "Point: (" + x + ", " + y;
}
/**
* Returns the world coorinate of the point.
* @return world vector.
*/
public Vector2 toWorld()
{
return new Vector2(x * tileWidth, y* tileHeight);
}
/**
* Returns point from world vector
* @param v World vector
* @return
*/
public static Point getPoint(Vector2 v)
{
return new Point((int)(v.x / tileWidth), (int)(v.y / tileHeight));
}
/**
* Returns point from Vector3 where Z is discarded.
* @param v world vector
* @return
*/
public static Point getPoint(Vector3 v)
{
return new Point((int)(v.x / tileWidth), (int)(v.y / tileHeight));
}
}
The only thing you need is to hookup tileWidth
and tileHeight
to your variables. You might want to change the variables to private with get/set, but since they are only coordinates I like to have quick access to them.
-Edit-
Here is a basic example of how a Tile class looks like.
public class Tile {
boolean walkable;
//here I make use of "your way" to lookup the texture of this tile.
int textureId;
}
when I want to create the map, I populate and draw the array:
Tile[][] tileMap = new Tile[width][height];
for (int y = 0; y < width; y++)
{
for (int x = 0; x <= height; x++)
{
spriteBatch.draw(textureDictionary.get(tileMap[x][y].textureId), position, etc);
}
}
Now this is not much different then your method, only mine stores if the tile can be walked upon too. Your walls should probably never be walked upon and floors should so why bother changing to my method?
Scalability is the answer. What if you decide that you want to add objects to your map? If you have say 10 objects like tables, chairs, pillars, etc then for each int that represents a floor you need 10 more of those. Where I just add another int for the objects texture or perhaps the object itself if it has more properties like a tile.
Yes you could add another array to represent your objects and draw that over your tiles. But then you decide that object a can damage the player in a certain state. Now you need to make another array or a extra int to refer too. Where I change the behavior of a object in it's class. This is why you use a object oriented language anyway.