Я пытаюсь отобразить позиции нескольких fighters
экране. Соответствующий код выглядит следующим образом:
public void run() {
double ns = 1000000000.0 / tps;
double delta = 0;
int frames = 0;
int updates = 0;
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
update();
updates++;
delta--;
}
frame.getContentPane().repaint();
frames++;
if(System.currentTimeMillis() - timer >= 1000) {
timer += 1000;
frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
frames = 0;
updates = 0;
}
}
stop();
}
private void update() {
if (Math.random() < .1) {
Fighter newFighter = new Fighter();
fighterList.add(newFighter);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g); // paint background
setBackground(Color.BLUE);
System.out.println(fighterList.size());
for (int i = 0; i<fighters; i++) {
System.out.println("Attempted");
g.setColor(Color.GREEN);
g.drawRect((int) fighterList.get(i).xPos,
(int) fighterList.get(i).yPos,
fighterList.get(i).radius,
fighterList.get(i).radius);
System.out.println("Rendered");
}
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setContentPane(new Game());
game.frame.setResizable(false);
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
Проблема в том, что на экран ничего не рисуется. Кроме того, работает System.out.println(fighterList.size());
дает разные выходы на основе того, где он запускается - при запуске внутри paintComponent
он всегда возвращает ноль, но при запуске внутри update
он возвращает правильную сумму. Это проблема с областью действия, или есть что-то еще, что мне не хватает?
Скорее всего, проблема синхронизации. Ваш метод paintComponent()
всегда вызывается из EDT (Thread Dispatch Thread), в то время как ваш метод run()
работает в своем отдельном потоке. Здесь вызывается update()
который добавляет новый Fighter
в список.
Вам нужна правильная синхронизация, так что обе (или все) потоки будут видеть одни и те же согласованные данные.
Кроме того, поскольку ваша модель (данные) может быть изменена во время перерисовки, вы также должны "клонировать" модель, чтобы избежать окрашивания непоследовательной модели. Или, если вы не хотите клонировать его, синхронизируйте доступ к модели, чтобы она не могла быть изменена во время ее раскраски.