Изометрическая карта тайлов. Есть тайлы большего размера?

Здравствуйте, у меня есть следующие две изометрические плитки:

Обычный тайл (вода):

img

Каменная плитка:

Имгур

Мне нужно добавить несколько плиток, например плитку с камнем, на игровое поле, но проблема в том, что для некоторых плиток, таких как этот камень, требуется больший уровень высоты.

В настоящее время тайл камня имеет большую высоту на 18 пикселей. Я попытался разделить камень на 3 плитки, но это выглядит ужасно, так как вы можете видеть линии напольной плитки на камне.

На данный момент доска выглядит так:

board
(источник: gyazo.com)

Как видите, из-за разницы в высоте плитки будут иметь разное расположение.

Мой слой графического кода спроектирован слоями, где есть слой Board, а слой Board содержит слой Nature, отвечающий за камни, цветы и так далее.

Мой рисунок доски:

@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);
}

И вот как я визуализирую слой природы:

@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);
        }           
    }
}

Я попытался вычесть высоту на 18, но все равно не повезло, все равно беспорядок. Существуют ли какие-либо правильные способы рисования тайлов, которые больше их реального размера?


person Artemkller545    schedule 03.07.2014    source источник


Ответы (1)


Сделайте абстракцию ваших плиток. В настоящее время вы, кажется, предполагаете, что плитка просто представлена ​​​​в виде изображения и что все имеет одинаковый размер.

Как видите, это не всегда выдерживает. Если вы создаете явный класс Tile, вы можете инкапсулировать в него все его детали и перенести туда ответственность за обработку нечетных вещей.

Простой класс Tile может выглядеть так:

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);
    }
}

Короче говоря, плитка сама справляется со своими странностями.

Вы можете пойти дальше и прикрепить к плитке данные, связанные с игрой (например, проходимость игрока, урон и т. д.). Вы сохраняете единый интерфейс для работы с плитками (API класса Tile), но каждая плитка может изменять визуализацию по мере необходимости (используя смещение X/Y для настройки размера изображения).

Редактировать: Измените формулу для вычисления x/y в рендере, чтобы она работала с размером основной плитки пола (112, 56, я думаю), независимо от того, насколько велик фактический спрайт плитки. Вы не хотите, чтобы размер спрайта искажал позиционирование в сетке (размер сетки диктуется базовым размером плитки пола). Тайл только компенсирует разницу между своим спрайтом и базовым размером (со смещениями).

person Durandal    schedule 03.07.2014
comment
Я сделал это, но посмотрите, что получилось: gyazo.com/d7c772a760001d4bb4c9bcf6fd96ddc4, они оба имеют одинаковое смещение по оси Y, и они добраться до другой точки. Я сделал плитки с водой черными, чтобы увидеть, где находятся настоящие индексы. первый — [0][0], второй — [5][5]. плитки[5][5] = новая плитка(0, -112, плитки.ROCK); плитки[0][0] = новая плитка(0, -112, плитки.ROCK); - person Artemkller545; 03.07.2014
comment
Из ваших фрагментов кода трудно сказать, какую систему координат вы используете и в каком состоянии находится ваша графика (вы используете перевод, который не отменяется волшебным образом при вызове следующего метода рендеринга. При повторном применении это < i>стеки). И вам нужно изменить формулу для x/y. Все плитки имеют одинаковый размер (концептуально) независимо от того, насколько они превышают назначенный размер. Внутренний цикл for работает с неправильной длиной массива: он должен быть tile[i].length, а неtiles[1].length (вероятно, он работает, потому что в настоящее время оба измерения одинаковы). - person Durandal; 03.07.2014
comment
Ознакомьтесь с живым исходным кодом github.com /BenBeri/GoPirate/tree/master/src/com/il/ben/go/ - person Artemkller545; 03.07.2014
comment
Находится в impl/battle/Nature - person Artemkller545; 03.07.2014
comment
@BenBeri Stackoverflow не является службой отладки: / Но, как я уже сказал, вы вычисляете x/y на основе размера спрайта. Конечно, это дает вам странные результаты с различными размерами. Я предполагаю, что это основная проблема, вызывающая неправильное позиционирование. - person Durandal; 03.07.2014
comment
Я пробовал так много изменений формул, ничего не помогает ... работает для нескольких координат и плохо работает в других координатах. действительно раздражает - person Artemkller545; 04.07.2014
comment
@BenBeri Никто не пробует формулы. Если вы делаете это, вы могли бы бросить кости точно так же. Возьмите лист бумаги и отработайте на нем преобразование геометрии (вы знаете, рисуете линии, делаете пометки, откуда берется это число и для чего оно). Затем оптимизируйте выражения. Вы получите что-то такое же простое, как x = (j * 56) - (i * 28); у = (j * 56) + (i * 28); - person Durandal; 04.07.2014