2014-09-24 3 views
1

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

В этом gif символы r в верхней строке являются сущностями. blinking entities

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

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); (слой плитки обращается), прежде чем я рисовать фон плитки, она создает что-то еще смешнее.

crazy

Это класс 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

Я так не думаю? Некоторые из них во втором gif на самом деле даже не мигают, просто действуют странно. – Kyranstar

+0

Возможно, я, вероятно, ошибаюсь. –

ответ

1

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