0

Hello I have the following two Isometric tiles:

Normal tile (water):

img

Rock tile:

Imgur

I need to add some tiles like the rock tile into my game board, but the problem is, that some tiles like this rock needs a bigger height level.

Currently, the rock tile has bigger height by 18px. I tried separating the rock into 3 tiles, but it just looks ugly as you can see the lines of the floor tiles on the on the rock.

Currently, the board looks like this:

board
(source: gyazo.com)

As you can see, because of the height difference the tiles will have a different location.

My graphics code layer is designed by layers, where there is a layer named Board, and the Board layer contains a layer named Nature, which is responsible for rocks, flowers and so on.

My board drawing:

@Override
public void render(Graphics g) {
    g.translate(this.translate.getX(), this.translate.getY());

    for (int i = 0; i < tiles[0].length; i++) {
        for (int j = 0; j < tiles[1].length; j++) {
            int x = (j * sprite.getWidth() / 2) - (i * sprite.getWidth() / 2);
            int y = (j * sprite.getHeight() / 2) + (i * sprite.getHeight() / 2);
            this.tiles[i][j].render(g, x, y);
        }
    }
    
    // rendering rocks and so on..
    this.nature.render(g);
}

And that's how I render nature layer:

@Override
public void render(Graphics g) {
    for (int i = 0; i < this.tiles[0].length; i++){
        for (int j = 0; j < this.tiles[1].length; j++){
            if (this.tiles[i][j] == null)
                continue;
            int width = this.tiles[i][j].getWidth();
            int height = this.tiles[i][j].getHeight();
            int x = (j * width / 2) - (i * width / 2);
            int y = (j * height / 2) + (i * height / 2);
            
            g.drawImage(this.tiles[i][j], x, y);
        }           
    }
}

I have tried subtracting the height by 18 but still not luck, it's still messy. Are there any proper ways do draw tiles that are bigger than it's actual size?

Community
  • 1
  • 1
Artemkller545
  • 979
  • 3
  • 21
  • 55

1 Answers1

0

Make an abstraction of your tiles. You currently seem to assume a tile is simply represented as an Image and that everything is of uniform size.

As you see that doesn't always hold up. If you make an explicit Tile class you can encapsulate all its details in there and move the responsibility for handling of the odd stuff in there.

A simple Tile class could look like this:

public class Tile {
    int offsetX;
    int offsetY;
    Image image;

    // Renders the tile at logical coordinates x, y        
    public void draw(Graphics g, int x, int y) {
        g.drawImage(image, x + offsetX, y + offsetY, null);
    }
}

In short, the tile manages its oddities itself.

You could go farther and attach game related data to the tile (e.g. player passable, damaging etc.). You keep a uniform interface for working with tiles (the Tile class API), but each tile can alter rendering as needed (using offsetX/Y to adjust for its image size).

Edit: Change the formula for calulating x/y in render to work with the size of the basic floor tile (112, 56 i guess), independtly of how large the actual tile sprite is. You don't want the sprite size to mess up positioning in the grid (the grid size is dictated by the basic floor tile size). The tile only compensates for the difference between its sprite and the basic size (with the offsets).

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • I did this, but look what happens: http://gyazo.com/d7c772a760001d4bb4c9bcf6fd96ddc4, they both have same Y offset, and they get to a different point. I made the water tiles black to see where are the real indexes. first one is [0][0] second is [5][5]. tiles[5][5] = new Tile(0, -112, Tiles.ROCK); tiles[0][0] = new Tile(0, -112, Tiles.ROCK); – Artemkller545 Jul 03 '14 at 17:14
  • From your code fragments its hard to tell what kind of coordinate system you're using and what state your Graphics is in (you are using translate, that doesn't magically undo itself when you call the next render method. When applied repeatedly it *stacks*). And you need to change your formula for x/y. Tiles are all the same size (conceptually) independent of how much they "over"-render the assigned size. The inner for-loop works with the wrong array length: it should be tiles[i].length not tiles[1].length (it probably works because both dimensions are the same currently). – Durandal Jul 03 '14 at 17:35
  • Check out the live source https://github.com/BenBeri/GoPirate/tree/master/src/com/il/ben/go/pirate/graphics – Artemkller545 Jul 03 '14 at 17:43
  • Located at impl/battle/Nature – Artemkller545 Jul 03 '14 at 17:44
  • @BenBeri Stackoverflow is not a debug service :/ But as I said, you're calculating x/y based on sprite size. Of course that does give you odd results with varying sizes. My guess is thats the main problem causing the irregular positioning. – Durandal Jul 03 '14 at 17:49
  • I've tried so many formula changing, nothing helps.. works for few coordinates, and gets bad in further coords. really annoying – Artemkller545 Jul 03 '14 at 22:55
  • @BenBeri One does not *try* formulas. If youre doing that, you could roll a dice just as well. Take a piece of paper and work out the geometry transformation there (you know drawing lines, putting notes where that number comes from and what its for). Then optimize the expressions. You'll end up with something as simple as x = (j * 56) - (i * 28); y = (j * 56) + (i * 28); – Durandal Jul 04 '14 at 13:23