Hmm, I am writing a tiled game engine right now (isometric) but logic like this is exactly the same regardless - so I believe I may be able to help you here.
I am not sure if I quite understand your question - but I believe I can give you a solid explanation to how I do it, and it may help you.
First of all, because you seem to be new to programming in general, here are some tips I will throw at you right away that will make your life a lot easier:
(You can skip this if you are just looking for an explanation to your problem, but I highly suggest some time later going over this and looking in to what I am saying here)
Variable names should usually start with a lower-case so you can differentiate them between a class name (which should usually start with an upper-case) and a variable name. Consider you have a class named Tile, you now end up with a declaration that looks like:
Tile Tile = new Tile();
Tile.x = 5; //etc
and 'Tile' because ambiguous because 'x' could be a static variable you are accessing in Tile, or it could be a member variable you are accessing that belongs to the instance of Tile named Tile (even that is confusing to comprehend!) - while Java resolves this appropriately it is still very confusing to any programming looking at the code.
Member variables usually start with some indication to suggest that they are a member variable that exists in the entire scope of the class. Some people prefer not to do this (and it is somewhat controversial among programmers) but I would say it can't hurt and it makes your code look cleaner. Most people either prefix member variables with _ or m_
Public member variables are usually avoided just because it's dangerous to expose these members directly unless the class is very simple (like a Vector, Matrix, Rectangle or Point). Instead people use get\set accessors. Some code (code that performs a dense and large amount of iterations over a time critical period like collision detection) can greatly benefit from directly access variables rather than using accessors - but I would say the rule of thumb should be to use get\set accessors - and then only if your profiler tells you that you can benifit from removing the accessors from the algorithm, do it.
Now on to the actual problem:Like I said, I don't quite understand your question, so instead I will explain the process, and you can ask for details if you'd like. This describes a simple tiled map implementation, however the implementation would be different for something more complex (if you want more details on that just ask):
Your map is going to consists of a series of tiles, tiles contain information such as location, image (source image), maybe a rectangle describing what part of that image constitutes the visual depiction of the tile, some basic attributes like isBlocking, and a location. So lets make the problem simpler by creating a Tile class to describe our tile.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Tile { private Image m_sourceImage; private Rectangle m_sourceRectangle; private boolean m_isBlocking;
public Tile(Image srcImage, Rectangle srcRectangle, boolean isBlocking) { m_sourceImage = srcImage; m_sourceRectangle = srcRectangle; m_isBlocking = isBlocking; } public void render(Graphics2D g, int x, int y) { } public boolean isBlocking() { return m_isBlocking; } } |
Great, now we have a tile class that mostly takes care of itself. Now, lets think about our world.
Our world is going to consists of a series of tiles. We'll store our tiles in a single-dimensional array.
Here is how your world might look:
(I don't gurantee that this code works, my algorithm may be wrong, but it will at least give you a head-start.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| public class World { private int m_worldWidth; private int m_worldHeight; private int m_tileWidth; private int m_tileHeight; private Tile[] m_tiles; public World(int worldWidth, int worldHeight, int tileWidth, int tileHeight) { m_worldWidth = worldWidth; m_worldHeight = worldHeight; m_tileWidth = tileWidth; m_tileHeight = tileHeight; m_tiles = new Tile[worldWidth * worldHeight]; for(int i = 0; i < m_tiles.length; i++) { m_tiles[i] = new Tile(...); } } public Tile getTile(int iX, int iY) { int tileIndex = iY * m_worldWidth + iX; if(tileIndex > m_tiles.length) return null; return m_tiles[tileIndex]; } public Tile pick(int iX, int iY) { return getTile(iX / m_tileWidth, iY / m_tileHeight); } public void render(Graphics2D g, int offsetX, int offsetY) { for(int y = 0; y < m_worldHeight; y++) { for(int x = 0; x < m_worldWidth; x++) { getTile(x, y).render(g, x * m_tileWidth + offsetX, y * m_tileHeight + offsetY); } } } } |