Java getCanvasImage и paintComponent рисует из синхронизации - PullRequest
0 голосов
/ 04 июля 2018

Цель: Я пытаюсь нарисовать ограничительные рамки вокруг NPC из игрового клиента. Мне нужно сохранить скриншот в папку и сохранить координаты поля в текстовом файле.

Проблема: Когда я поворачиваю камеру, прямоугольники, нарисованные на холсте, больше не совпадают с NPC. Похоже, что координаты NPC отстают от скриншота, на котором рисуется. Некоторые из снимков экрана также выглядят как половина предыдущего кадра и половина нового кадра. Я предполагаю, что это может быть связано с отправкой нескольких изображений для сохранения до завершения первого. Еще одна вещь, которую стоит отметить, это то, что прямоугольники не заканчивают рисовать, пока на холсте не появится следующий кадр.

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

Это первый раз, когда я работал с Java (данные, которые собирает этот сценарий, предназначены для использования с проектом Python, над которым я работаю), поэтому, пожалуйста, максимально упростите ответы.

Обновление: После возни с вещами, кажется, что разрыв экрана может быть главной проблемой. Задержка выглядит так, как будто она вызвана разрывом экрана. Ящики отображаются в правильном положении в тех частях экрана, которые не были обновлены до их сохранения.

https://media.giphy.com/media/39yEawmLBT4zKpPoz3/giphy.gif

Misaligned

Misaligned

Misaligned

Производительность в худшем:

Misaligned

Tearing:

Tearing

public class Pair {
   public String key;
   public Rectangle value;

   public Pair(String key, Rectangle value) {
      this.key = key;
      this.value = value;
   }
}

public class MyPaint extends JPanel{
    private static final long serialVersionUID = 9091790544960515120L;
    private BufferedImage paintImage = getClient().getCanvasImage();

    @Override
    protected void paintComponent(Graphics g){

        super.paintComponent(g);
        g.drawImage(paintImage, 0, 0, null);

    }

    public void updatePaint(){
        synchronized (this) {
            Graphics g = paintImage.createGraphics();

            List<NPC> rsNpcs = new NPCs(getClient()).all()
                    .stream()
                    .filter(i -> i.getName().equals(npcName)
                             &&  i.isOnScreen() == true
                             &&  inTile(i.getTile()) == false)
                    .collect(Collectors.toList());

            //Classifying the NPC in the box for the text file.
            for (NPC rsNpc : rsNpcs) {
                Rectangle bbox = rsNpc.getBoundingBox(); 
                g.drawRect(bbox.x, bbox.y, bbox.width, bbox.height);

                if (rsNpc.isInCombat() == true) {
                    Pair rsNpcPair = new Pair("CombatChicken", bbox);
                    onScreenRsNpcs.add(rsNpcPair);
                } else {
                    Pair rsNpcPair = new Pair("RegularChicken", bbox);
                    onScreenRsNpcs.add(rsNpcPair);
                }
            }

            //This bit is to save the boxes to a text file:
            for (Pair rsNpc : onScreenRsNpcs) {
                String data = (String.valueOf(rsNpc.value) + "Class Name: " + rsNpc.key + " Image Name: " + String.valueOf(count));
                globalData.add(data);
            }

            g.dispose();
            repaint();
        }
    }

    public void save() throws IOException{
            ImageIO.write(paintImage, "PNG", new File(String.format("%s/%s.jpg", getManifest().name(), count)));
            count = count + 1;
    }

    public void load() throws IOException {
        paintImage = ImageIO.read(new File(String.format("%s/%s.jpg", getManifest().name(), count)));
        repaint();
    }
}


//...


private MyPaint paint;


public void onStart() {
    paint = new MyPaint();
}


//...


@Override
public int onLoop() {   
    try {
        paint.updatePaint();
        paint.save();
        paint.load();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return 1;
}
...