2015-10-06 65 views
0

這是我的主要代碼的代碼。我試着用函數創建一個包來檢查鍵盤動作,但是它不起作用。所以,現在這兩個代碼都在您看到的相同文件下。到目前爲止,程序打開,我可以看到圓圈,但它不會向左或向右移動。我一直在這裏待3小時,相信與否。我不能讓我的2D遊戲對象移動

編輯:我只是意識到更新函數從名爲「input」的包中獲取數據。那是我把在相同的文件名都上課前,但即使當時有一個叫包中的類「gamesample.input。*,但它仍然是行不通的。

package gamesample; 

import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 
import javax.swing.JFrame; 

/** 
* Main class for the game 
*/ 
public class GameSample extends JFrame 
{   
    boolean isRunning = true; 
    int fps = 30; 
    int windowWidth = 500; 
    int windowHeight = 500; 

    BufferedImage backBuffer; 
    Insets insets; 
    InputHandler input; 

    int x = 0; 

    public static void main(String[] args) 
    { 
      GameSample game = new GameSample(); 
      game.run(); 
      System.exit(0); 
    } 

    /** 
    * This method starts the game and runs it in a loop 
    */ 
    public void run() 
    { 
      initialize(); 

      while(isRunning) 
      { 
        long time = System.currentTimeMillis(); 

        update(); 
        draw(); 

        // delay for each frame - time it took for one frame 
        time = (1000/fps) - (System.currentTimeMillis() - time); 

        if (time > 0) 
        { 
          try 
          { 
            Thread.sleep(time); 
          } 
          catch(Exception e){} 
        } 
      } 

      setVisible(false); 
    } 

    /** 
    * This method will set up everything need for the game to run 
    */ 
    void initialize() 
    { 
      setTitle("Game Tutorial"); 
      setSize(windowWidth, windowHeight); 
      setResizable(false); 
      setDefaultCloseOperation(EXIT_ON_CLOSE); 
      setVisible(true); 

      insets = getInsets(); 
      setSize(insets.left + windowWidth + insets.right, 
          insets.top + windowHeight + insets.bottom); 

      backBuffer = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB); 
      input = new InputHandler(this); 
    } 

    /** 
    * This method will check for input, move things 
    * around and check for win conditions, etc 
    */ 
    void update() 
    { 
      if (input.isKeyDown(KeyEvent.VK_RIGHT)) 
      { 
        x += 5; 
      } 
      if (input.isKeyDown(KeyEvent.VK_LEFT)) 
      { 
        x -= 5; 
      } 
    } 

    /** 
    * This method will draw everything 
    */ 
    void draw() 
    {    
      Graphics g = getGraphics(); 

      Graphics bbg = backBuffer.getGraphics(); 

      bbg.setColor(Color.WHITE); 
      bbg.fillRect(0, 0, windowWidth, windowHeight); 

      bbg.setColor(Color.BLACK); 
      bbg.drawOval(x, 10, 20, 20); 

      g.drawImage(backBuffer, insets.left, insets.top, this); 

    } 
} 

這是鍵盤碼

package gamesample; 

import java.awt.Component; 
import java.awt.event.*; 

/** 
* Makes handling input a lot simpler 
*/ 
public class InputHandler implements KeyListener 
{   
boolean keys[]; 
    /** 
    * Assigns the newly created InputHandler to a Component 
    * @param c Component to get input from 
    */ 


    public InputHandler(Component c) 
    { 
      c.addKeyListener(this); 
    } 

    /** 
    * Checks whether a specific key is down 
    * @param keyCode The key to check 
    * @return Whether the key is pressed or not 
    */ 
    public boolean isKeyDown(int keyCode) 
    { 


      if (keyCode > 0 && keyCode < 256) 
      { keys = new boolean [256]; 
        return keys[keyCode]; 
      } 

      return false; 
    } 

    /** 
    * Called when a key is pressed while the component is focused 
    * @param e KeyEvent sent by the component 
    */ 
    public void keyPressed(KeyEvent e) 
    { boolean keys[]; 
      if (e.getKeyCode() > 0 && e.getKeyCode() < 256) 
      { keys = new boolean [256]; 
        keys[e.getKeyCode()] = true; 
      } 
    } 

    /** 
    * Called when a key is released while the component is focused 
    * @param e KeyEvent sent by the component 
    */ 
    public void keyReleased(KeyEvent e) 
    { boolean keys[]; 
      if (e.getKeyCode() > 0 && e.getKeyCode() < 256) 
      { keys = new boolean [256]; 
        keys[e.getKeyCode()] = false; 
      } 
    } 

    /** 
    * Not used 
    */ 
    public void keyTyped(KeyEvent e){} 
} 

回答

1

Graphics g = getGraphics();也不怎麼風俗畫應該做的。搖擺採用被動渲染算法,這意味着你的UI可以在任何時候重新繪製,爲任意數量的原因,其中有許多你不擁有控制權Swing默認情況下也是雙緩衝,所以如果你實際使用JPanel並且覆蓋它的paintComponent方法,y你可以免費獲得雙倍緩衝,你會被通知任何與系統相關的繪畫事件。

更多細節

Painting in AWT and SwingPerforming Custom Painting不要使用KeyListener,這太麻煩和鍵綁定API解決了自己的一切所有的問題。有關更多詳細信息,請參見How to Use Key Bindings

請記住,Swing是一個單線程框架,不是線程安全的。這意味着你不應該以任何方式阻塞事件分派線程(比如使用永無止境的循環),你應該只在EDT的上下文中更新UI。

您的「主迴路」有兩種危險。 JVM的本質是代碼不會阻塞EDT,但這也意味着您違反了Swing的單線程本質。

有關更多詳細信息,請參見Concurrency in Swing

通常情況下,我會使用Swing Timer進行此類工作,因爲它的回調在EDT上下文中同步,但您可以使用Thread,但您必須手動將更新重新同步到EDT。

如果你想,你應該使用BufferStrategy在繪畫過程中完全控制,見BufferStrategyBufferStrategy and BufferCapabilities更多細節

由於上述概念的basic example