2014-06-04 15 views
0
public class Screen extends Canvas implements Runnable { 
    private static final int MAX_FPS = 60; 
    private static final int FPS_SAMPLE_SIZE = 6; 

    private boolean[] keysPressed = new boolean[256]; 

    private ArrayList<Character> characters = new ArrayList<>(); 
    private ArrayList<Character> ai = new ArrayList<>(); 
    private Thread thread; 
    private BufferedImage bg; 

    //for testing putposes 
    private Player slime = new Player("Slime.png", 100, 100); 
    private Player bird = new Player("Bird.png", 250, 250); 
    private Player giant = new Player("Giant.png", 250, 500); 
    private Player swordsman = new Player("Swordsman.png", 500, 250); 

    //screen dimensions 
    private int height = ((Toolkit.getDefaultToolkit().getScreenSize().height-32)/5*4); 
    private int width = Toolkit.getDefaultToolkit().getScreenSize().width; 

    private long prevTick = -1; 
    private LinkedList<Long> frames = new LinkedList<>(); 
    private int averageFPS; 
    private boolean running; 


    public Screen() { 
    setSize(width, height); 
    try {bg = ImageIO.read(new File("GUI Images/success.jpg"));} 
    catch (Exception e) {Utilities.showErrorMessage(this, e);} 
    characters.add(slime); 
    // ai.add(bird); 
    //ai.add(giant); 
    // ai.add(swordsman); 
    addKeyListener(new KeyListener() { 
     public void keyPressed(KeyEvent e) {keysPressed[e.getKeyCode()] = true;} 
     public void keyReleased(KeyEvent e) {keysPressed[e.getKeyCode()] = false;} 
     public void keyTyped(KeyEvent e) {} 
     }); 
    addMouseListener(new MouseListener() { 
     public void mouseClicked(MouseEvent e) {} 
     public void mouseEntered(MouseEvent e) {} 
     public void mouseExited(MouseEvent e) {} 
     public void mousePressed(MouseEvent e) {} 
     public void mouseReleased(MouseEvent e) {} 
     }); 
    addMouseMotionListener(new MouseMotionListener() { 
     public void mouseDragged(MouseEvent e) {} 
     public void mouseMoved(MouseEvent e) {} 
     }); 
    addMouseWheelListener(new MouseWheelListener() { 
     public void mouseWheelMoved(MouseWheelEvent e) {} 
     }); 

    setVisible(true); 
    start(); 
    } 

    public void paint(Graphics g){ 
    BufferStrategy bs = getBufferStrategy(); 
    if(getBufferStrategy() == null){ 
     createBufferStrategy(3); 
     return; 
    } 
    g = bs.getDrawGraphics(); 
    g.drawImage(bg,0,0,width,height, null); 
    g.drawString(String.valueOf(averageFPS), 0, 0); 
    for (Character character : ai){ 
     character.setY(character.getY() + (int)(Math.random() * 10 - 5)); 
     character.setX(character.getX() + (int)(Math.random() * 10 - 5)); 
    } 
    for (Character character : ai) {g.drawImage(character.getImage(), character.getX(), character.getY(), null);} 
    for (Character character : characters) {g.drawImage(character.getImage(), character.getX(), character.getY(), null);} 
    g.dispose(); 
    bs.show(); 
    } 

    public void run() { 
    while (running) { 
     tick(); 
     repaint(); 
    } 
    } 

    public synchronized void start() { 
    running = true; 
    thread = new Thread(this); 
    thread.start(); 
    } 

    public synchronized void stop() { 
    try {thread.join();} 
    catch (InterruptedException e) {Utilities.showErrorMessage(this, e);} 
    } 

    public void tick() { 
    if (keysPressed[KeyEvent.VK_W] && (slime.getY() > 0)) {slime.setY(slime.getY() - 1);} 
    if (keysPressed[KeyEvent.VK_S] && (slime.getY() < height)) {slime.setY(slime.getY() + 1);} 
    if (keysPressed[KeyEvent.VK_A] && (slime.getY() > 0)) {slime.setX(slime.getX() - 1);} 
    if (keysPressed[KeyEvent.VK_D] && (slime.getY() < width)) {slime.setX(slime.getX() + 1);} 
    // System.out.println(slime.getX() + ", " + slime.getY()); 

     long pastTime = System.currentTimeMillis() - prevTick; 
     prevTick = System.currentTimeMillis(); 

     if (frames.size() == FPS_SAMPLE_SIZE) { 
      frames.remove(); 
     } 
     frames.add(pastTime); 

     // Calculate average FPS 
     long sum = 0; 
     for (long frame : frames) { 
      sum += frame; 
     } 
     long averageFrame = sum/FPS_SAMPLE_SIZE; 
     averageFPS = (int)(1000/averageFrame); 

     // Only if the time passed since the previous tick is less than one 
     // second divided by the number of maximum FPS allowed do we delay 
     // ourselves to give Time time to catch up to our rendering. 
    if (pastTime < 1000.0/MAX_FPS) { 
      try { 
       Thread.sleep((1000/MAX_FPS) - pastTime); 
      System.out.println(averageFPS); 
      } catch (InterruptedException e) { 
       System.out.println(e); 
     } 
    } 

    } 
} 

有我的代碼,本質上這是屏幕上看到,如果我能正確繪製對象屏幕只是測試代碼,但是有這麼繼續得到畫不穩定的白框。它們似乎並不是特別是由任何輸入引起的,它們在刷新幀時似乎是隨機發生的。任何想法可能是什麼?的Java:在油畫布白框

+1

不覆蓋塗料,然後添加緩衝策略吧。不要使用重繪,你已經改變了繪畫的完成方式,你應該將邏輯(從繪畫)移動到遊戲循環 – MadProgrammer

+0

哦,不知道在做自定義繪畫時我不應該重寫繪畫。該代碼僅僅是暫時的,因爲我還沒有開始一個正確的遊戲循環,我會在以後確定的。非常感謝,MadProgrammer – JoeyTheAsian

+0

一旦這樣做,我得到了一個異常說「組件必須有一個有效的同行」不知道這意味着什麼。 – JoeyTheAsian

回答

1

請勿覆蓋油漆,並在其中使用BufferStrategy。繪畫通常需要做基地(又稱「被動」渲染)。 BufferStrategy是一種「主動」渲染方法,您可以直接控制繪製過程並更新緩衝區,兩者不會一起玩好

從當前的paint方法中取出邏輯並將其放置在您的遊戲循環。

這將需要您在構造函數中刪除對start的調用,因爲組件不會被添加到有效的本地對等體(屏幕上顯示的組件)。

相反,創建一個實例的Screen,把它添加到您的框架,然後調用啓動,例如...

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FontMetrics; 
import java.awt.Frame; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Toolkit; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.awt.event.MouseWheelEvent; 
import java.awt.event.MouseWheelListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.image.BufferStrategy; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.ArrayList; 
import java.util.LinkedList; 
import javax.imageio.ImageIO; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestScreen { 

    public static void main(String[] args) { 
     new TestScreen(); 
    } 

    public TestScreen() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       Frame frame = new Frame("Testing"); 
       frame.addWindowListener(new WindowAdapter() { 
        @Override 
        public void windowClosing(WindowEvent e) { 
         System.exit(0); 
        } 
       }); 
       Screen screen = new Screen(); 
       frame.add(screen); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
       screen.start(); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.dispose(); 
     } 

    } 

    public class Screen extends Canvas implements Runnable { 

     private static final int MAX_FPS = 60; 
     private static final int FPS_SAMPLE_SIZE = 6; 

     private boolean[] keysPressed = new boolean[256]; 

     private ArrayList<Character> characters = new ArrayList<>(); 
     private ArrayList<Character> ai = new ArrayList<>(); 
     private Thread thread; 
     private BufferedImage bg; 

     private long prevTick = -1; 
     private LinkedList<Long> frames = new LinkedList<>(); 
     private int averageFPS; 
     private boolean running; 

     public Screen() { 
      try { 
       bg = ImageIO.read(new File("GUI Images/success.jpg")); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      addKeyListener(new KeyListener() { 
       public void keyPressed(KeyEvent e) { 
        keysPressed[e.getKeyCode()] = true; 
       } 

       public void keyReleased(KeyEvent e) { 
        keysPressed[e.getKeyCode()] = false; 
       } 

       public void keyTyped(KeyEvent e) { 
       } 
      }); 
      addMouseListener(new MouseListener() { 
       public void mouseClicked(MouseEvent e) { 
       } 

       public void mouseEntered(MouseEvent e) { 
       } 

       public void mouseExited(MouseEvent e) { 
       } 

       public void mousePressed(MouseEvent e) { 
       } 

       public void mouseReleased(MouseEvent e) { 
       } 
      }); 
      addMouseMotionListener(new MouseMotionListener() { 
       public void mouseDragged(MouseEvent e) { 
       } 

       public void mouseMoved(MouseEvent e) { 
       } 
      }); 
      addMouseWheelListener(new MouseWheelListener() { 
       public void mouseWheelMoved(MouseWheelEvent e) { 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      int height = ((Toolkit.getDefaultToolkit().getScreenSize().height - 32)/5 * 4); 
      int width = Toolkit.getDefaultToolkit().getScreenSize().width; 
      return new Dimension(width, height); 
     } 

     public void run() { 

      createBufferStrategy(3); 
      BufferStrategy bs = null; 

      while (running) { 
       bs = getBufferStrategy(); 
       Graphics g = bs.getDrawGraphics(); 
       g.drawImage(bg, 0, 0, getWidth(), getHeight(), null); 
       FontMetrics fm = g.getFontMetrics(); 
       g.setColor(Color.RED); 
       g.drawString(String.valueOf(averageFPS), 0, fm.getAscent()); 
       g.dispose(); 
       bs.show(); 
       tick(); 
      } 
     } 

     public synchronized void start() { 
      running = true; 
      thread = new Thread(this); 
      thread.start(); 
     } 

     public synchronized void stop() { 
      try { 
       thread.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     public void tick() { 
//   if (keysPressed[KeyEvent.VK_W] && (slime.getY() > 0)) { 
//    slime.setY(slime.getY() - 1); 
//   } 
//   if (keysPressed[KeyEvent.VK_S] && (slime.getY() < height)) { 
//    slime.setY(slime.getY() + 1); 
//   } 
//   if (keysPressed[KeyEvent.VK_A] && (slime.getY() > 0)) { 
//    slime.setX(slime.getX() - 1); 
//   } 
//   if (keysPressed[KeyEvent.VK_D] && (slime.getY() < width)) { 
//    slime.setX(slime.getX() + 1); 
//   } 
//   // System.out.println(slime.getX() + ", " + slime.getY()); 

      long pastTime = System.currentTimeMillis() - prevTick; 
      prevTick = System.currentTimeMillis(); 

      if (frames.size() == FPS_SAMPLE_SIZE) { 
       frames.remove(); 
      } 
      frames.add(pastTime); 

      // Calculate average FPS 
      long sum = 0; 
      for (long frame : frames) { 
       sum += frame; 
      } 
      long averageFrame = sum/FPS_SAMPLE_SIZE; 
      averageFPS = (int) (1000/averageFrame); 

      // Only if the time passed since the previous tick is less than one 
      // second divided by the number of maximum FPS allowed do we delay 
      // ourselves to give Time time to catch up to our rendering. 
      if (pastTime < 1000.0/MAX_FPS) { 
       try { 
        Thread.sleep((1000/MAX_FPS) - pastTime); 
        System.out.println(averageFPS); 
       } catch (InterruptedException e) { 
        System.out.println(e); 
       } 
      } 

     } 
    } 

}