2015-08-10 2 views
2

Я уверен, что этот код должен нарисовать овал на экране рядом со словом. Тем не менее, слово все появляется, остальная часть экрана черная. Это, похоже, происходит с любой примитивной формой. Я хотел бы думать, что я знаю java довольно хорошо, но графические вещи действительно запутывают меня. Я с этим согласен, и любая помощь будет оценена.Невозможно нарисовать фигуры в java

import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.util.ArrayList; 

public class Game extends JPanel implements Runnable { 
    int W = 4; 
    int H = 3; 
    int windowSize = 300; 
    boolean running; 
    static boolean drawHitBoxes = true; 
    int FPSLimit = 30; 

    private Thread thread; 
    private BufferedImage buffer; 
    private Graphics2D g; 

    public Game() { 
     super(); 
     setPreferredSize(new Dimension(W * windowSize, H * windowSize)); 
     setFocusable(true); 
     requestFocus(); 
    } 

    public void addNotify() { 
     super.addNotify(); 
     if (thread == null) { 
      thread = new Thread(this); 
      thread.start(); 
     } 
    } 

    public void run() { 
     running = true; 

     buffer = new BufferedImage(W * windowSize, H * windowSize, 
       BufferedImage.TYPE_INT_RGB); 
     g = (Graphics2D) buffer.getGraphics(); 

     // citList.add(new Citizen(200, 200, "Joe")); 

     long startTime; 
     long waitTime; 

     long frameTime = 1000/FPSLimit; // /How long one frame should take 
     long currentFrameTime; 

     while (running) { 
      startTime = System.nanoTime(); // record when loop starts 

      gameUpdate(); 
      gameRender(); 
      gameDraw(); 

      // Calculate how long the current frame took 
      currentFrameTime = (System.nanoTime() - startTime)/1000000; 
      waitTime = frameTime - currentFrameTime; 

      try { 
       Thread.sleep(waitTime); 
      } catch (Exception e) { 
      } // Sleep for the remaining time 
     } 
    } 

    private void gameUpdate() { 
     // for(Citizen i:citList){i.update();} //Update citizens 
    } 

    private void gameRender() { 
     g.setColor(Color.WHITE); 
     g.drawOval(100, 100, W - 100, H - 100); 
     g.setColor(Color.WHITE); 
     g.drawString("Text.", 100, 100); 
     System.out.println("Drawing white box."); 

     // for(Citizen i:citList){i.draw(g);} //Draw citizens 
    } 

    private void gameDraw() { 
     Graphics gMain = this.getGraphics(); 
     gMain.drawImage(buffer, 0, 0, null); 
    } 
} 
+0

См. Править для ответа. Вероятно, вы хотите: «g.drawOval (100, 100, W * windowSize - 200, H * windowSize - 200);' –

+0

Боже мой, я не могу поверить, что сделал это и не мог его увидеть. Это ужасно смущает. Благодарю. – senox13

ответ

3
g.drawOval(100, 100, W-100, H-100); 

W является 4 и Н 3, и поэтому так W-100 является -96 и H-100 является -97, что делает ваш третий и 4-й параметры отрицательной, что не имеет смысла для Graphics#drawOval(...) метода, так как как ширина и высота овала могут быть отрицательными. Решение: обязательно используйте только положительные параметры, которые имеют смысл при вызове этого метода. Возможно, что вы хотите:

// but you'll also want to avoid magic numbers such as 100 & 200 as well 
g.drawOval(100, 100, W * windowSize - 200, H * windowSize - 200); 

Как и в сторону, я, я предпочитаю использовать пассивную графику, рисунок в paintComponent, и я страшно, когда я вижу Свинг код, который содержит графики или Graphics2D поле экземпляра .. Кроме того, ваш код выглядит чтобы не подчиняться правилам качания Swing, поскольку он, как представляется, заставляет Swing отменять поток событий Swing.

3

Я думаю, что лучше создать метод paintComponent и перенести свой gameRender и gameDraw там, а в вашем цикле while заменить вызовы методов с помощью repaint(). Вот код, который работает.

import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.util.ArrayList; 

public class Game extends JPanel implements Runnable { 
    int W = 4; 
    int H = 3; 
    int windowSize = 300; 
    boolean running; 
    static boolean drawHitBoxes = true; 
    int FPSLimit = 30; 

    private Thread thread; 
    private BufferedImage buffer; 
    private Graphics2D g; 

    public Game() { 
     super(); 
     setPreferredSize(new Dimension(W * windowSize, H * windowSize)); 
     setFocusable(true); 
     requestFocus(); 
    } 

    public void addNotify() { 
     super.addNotify(); 
     if (thread == null) { 
      thread = new Thread(this); 
      thread.start(); 
     } 
    } 

    public void run() { 
     running = true; 

     buffer = new BufferedImage(W * windowSize, H * windowSize, 
       BufferedImage.TYPE_INT_RGB); 
     g = (Graphics2D) buffer.getGraphics(); 

     // citList.add(new Citizen(200, 200, "Joe")); 

     long startTime; 
     long waitTime; 

     long frameTime = 1000/FPSLimit; // /How long one frame should take 
     long currentFrameTime; 

     while (running) { 
      startTime = System.nanoTime(); // record when loop starts 

      gameUpdate(); 
      //gameRender(); 
      //gameDraw(); 
      repaint(); 

      // Calculate how long the current frame took 
      currentFrameTime = (System.nanoTime() - startTime)/1000000; 
      waitTime = frameTime - currentFrameTime; 

      try { 
       Thread.sleep(waitTime); 
      } catch (Exception e) { 
      } // Sleep for the remaining time 
     } 
    } 

    private void gameUpdate() { 
     // for(Citizen i:citList){i.update();} //Update citizens 
    } 

    private void gameRender() { 
     g.setColor(Color.WHITE); 
     //g.drawOval(100, 100, W - 100, H - 100); 
     g.drawOval(100, 100, 100, 100); 
     g.setColor(Color.WHITE); 
     g.drawString("Text.", 100, 100); 
     //System.out.println("Drawing white box."); 

     // for(Citizen i:citList){i.draw(g);} //Draw citizens 
    } 

    private void gameDraw(Graphics gMain) { 
     //Graphics gMain = this.getGraphics(); 
     gMain.drawImage(buffer, 0, 0, null); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     gameRender(); 
     gameDraw(g); 
    } 
} 

Как указывают на @Hovercraft в своем ответе, W-100 и Н-100 в коде `g.drawOval (100, 100, W - 100, H - 100);» будут давать отрицательные числа. Я не знаю точно, какие значения вы хотите получить там, но я просто заменил их на 100, чтобы удалить ошибку.

+0

В отличие от программ AWT вы должны почти * никогда не называть 'updateUI()' на компонентах Swing, если только вы не делаете этого после изменения Look & Feel. –

+0

@HovercraftFullOfEels почему? Это создает задержки? –

+0

@HovercraftFullOfEels. Каков наилучший способ запуска защищенного void paintComponent (Graphics g) в этом примере? –

Смежные вопросы