2015-10-06 67 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