Roguelike игра имеет мигающий рисунок

1

Я пишу систему рисования для игры с рогейнами, основанной на персонажах ascii (графика похожа на карликовую крепость). Я использую AsciiPanel отсюда. Моя проблема в том, что когда я рисую объекты на своей карте, они, похоже, мигают, когда они должны быть твердыми.

В этом gif символы r в верхней строке являются сущностями. Изображение 174551

Это метод рисования карты, который называется каждым фреймом.

public void draw(final Display display) {
        for (int x = getViewportX(); x < getViewportX() + viewportWidthInTiles; x++) {
            for (int y = viewportY; y < viewportY + viewportHeightInTiles; y++) {
                final char character = background[x][y].getCharacter();
                final Color foreground = background[x][y].getForeground();
                final Color backgroundColor = background[x][y].getBackground();
                final AsciiCharacterData data = new AsciiCharacterData(
                        character, foreground, backgroundColor);
                display.setCharacterAt(x - getViewportX(), y - viewportY,
                        background[x][y].getDrawingLayer(), data);
            }
        }
        display.clearLayer(DrawingLayer.PRIMARY);
        for (int i = 0; i < entities.size(); i++) {
            final Entity e = entities.get(i);

            final char character = e.getCharacter();
            final Color foreground = e.getForeground();
            final Color backgroundColor = e.getBackground();
            final AsciiCharacterData data = new AsciiCharacterData(character,
                    foreground, backgroundColor);
            display.setCharacterAt(e.getX() - getViewportX(), e.getY()
                    - viewportY, e.getDrawingLayer(), data);
        }
    }

Я думаю, что знаю, что вызывает проблему, потому что если я напишу display.clearLayer(DrawingLayer.BACKGROUND); (слой, на который нарисованы плитки), прежде чем нарисовать фоновые плитки, он создает что-то еще более смешное.

Изображение 174551

Это класс Display, в котором, я думаю, я ошибаюсь.

public class Display {
    private static final char TRANSPARENT_CHARACTER = ' ';

    private final AsciiPanel displayPanel;
    private final int widthInCharacters, heightInCharacters;

    private final static int Z_LEVELS = DrawingLayer.values().length;

    private final AsciiCharacterData[][][] characterMap;

    public Display(final AsciiPanel panel) {
        displayPanel = panel;
        widthInCharacters = panel.getWidthInCharacters();
        heightInCharacters = panel.getHeightInCharacters();

        characterMap = new AsciiCharacterData[widthInCharacters][heightInCharacters][Z_LEVELS];
        for (int x = 0; x < widthInCharacters; x++) {
            for (int y = 0; y < heightInCharacters; y++) {
                for (int z = 0; z < Z_LEVELS; z++) {
                    characterMap[x][y][z] = new AsciiCharacterData(
                            TRANSPARENT_CHARACTER,
                            displayPanel.getDefaultForegroundColor(),
                            displayPanel.getDefaultBackgroundColor());
                }
            }
        }
    }

    public void setCharacterAt(final int x, final int y, final DrawingLayer z,
            final AsciiCharacterData c) {
        if (x < 0 || x >= widthInCharacters || y < 0 || y >= heightInCharacters)
            return;
        characterMap[x][y][z.layer] = c;

        // if z is not the top level
        if (z.layer != Z_LEVELS - 1) {
            // check all levels above
            for (int i = z.layer + 1; i < Z_LEVELS; i++) {
                // if there is an opaque character
                if (characterMap[x][y][i].character != TRANSPARENT_CHARACTER)
                    // we dont need to draw anything
                    return;
            }
        }

        if (c.character == TRANSPARENT_CHARACTER) {
            // loop through all characters under the transparent character
            for (int i = z.layer - 1; i >= 0; i--) {
                // if we find a non transparent character
                if (characterMap[x][y][i].character != TRANSPARENT_CHARACTER) {
                    // display that one instead
                    displayPanel.write(characterMap[x][y][i].character, x, y,
                            characterMap[x][y][i].foregroundColor,
                            characterMap[x][y][i].backgroundColor);
                    return;
                }
            }
            // if there were no non trasparent characters
            displayPanel.write(TRANSPARENT_CHARACTER, x, y);
            // if we are a highlighter, we draw the below character and then
            // just draw on top
        } else {
            displayPanel.write(c.character, x, y, c.foregroundColor,
                    c.backgroundColor);
        }
        displayPanel.repaint();
    }

    public AsciiCharacterData getCharacterAt(final int x, final int y,
            final DrawingLayer z) {
        return characterMap[x][y][z.layer];
    }

    public int getWidth() {
        return widthInCharacters;
    }

    public int getHeight() {
        return heightInCharacters;
    }

    public void clearLayer(final DrawingLayer layer) {
        for (int x = 0; x < widthInCharacters; x++) {
            for (int y = 0; y < heightInCharacters; y++) {
                setCharacterAt(x, y, layer,
                        new AsciiCharacterData(TRANSPARENT_CHARACTER,
                                displayPanel.getDefaultForegroundColor(),
                                displayPanel.getDefaultBackgroundColor()));
            }
        }
    }
}
  • 1
    Я не знаком с AsciiPanel . Я знаю, что в старом текстовом режиме MS-DOS установка старшего бита для атрибута персонажа может вызвать его мигание или более яркий цвет. Существовало два режима, в которых мог отображаться дисплей. Возможно ли, что AsciiPanel это поведение? Просто предположение.
  • 0
    Я так не думаю? Некоторые из тех, кто во втором гифке, на самом деле даже не моргают, а ведут себя странно.
Показать ещё 2 комментария
Теги:
drawing
ascii
game-engine
roguelike

1 ответ

1
Лучший ответ

Решено! Это была одна строка в методе setCharacterAt. Я перекрашивал каждый раз, когда я устанавливал персонажа, который (хотя и неэффективен) также создает это мерцание.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню