2013-02-27 74 views
2

嗨,我刚刚搞过关于多边形和awt。我创建了一个Jframe,并可以绘制多边形,并让其中一个按键移动。创建游戏循环线程

我想知道如何启动一个gameloop线程(以及放在哪!),它将独立更新jframe。

从谷歌搜索引擎认为我应该有一个用户输入线程和一个游戏本身。

目前我已经在板类上实现了KeyListener(代码如下所示),我应该把它放到它自己的类中并让它实现可运行吗?如代码所示,我在keypressed()方法中重新绘制JFrame只是所以我可以看到它正确移动

在这一天的大部分时间,我有我自己非常困惑:) 一如既往的任何帮助非常感谢!

此外,虽然即时从它在线tutourials我应该使用JPanel而不是JFrame和paintComponent()而不是paint()?

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.geom.AffineTransform; 

import javax.swing.JFrame; 

public class Board extends JFrame implements KeyListener{ 
    AffineTransform identity = new AffineTransform(); 
    Graphics2D g2d; 

    Ship ship = new Ship(); 

    public static final int ALIENS = 3; 
    Alien[] alien = new Alien[ALIENS]; 


    Board(){ 
     super("The Board"); 
     setSize(1280,1024); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     getContentPane().setBackground(Color.BLACK); 
     for(int x=0;x<ALIENS;x++){ 
      alien[x]=new Alien(); 
     } 
    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     addKeyListener(this); 
     //draw ship 
     g2d = (Graphics2D)g;  
     g2d.setTransform(identity); 
     g2d.translate(ship.getxPos(),ship.getyPos()); 
     g2d.scale(2,2); 
     g2d.setColor(Color.ORANGE); 
     g2d.fill(ship.getShape()); 
     g2d.setColor(Color.BLACK); 
     g2d.draw(ship.getShape()); 

     // draw aliens 
     for(int x=0;x<ALIENS;x++){ 
      //if alien alive 
      if(alien[x].isAlive()){ 
       //draw alien 
       g2d = (Graphics2D)g;  
       g2d.setTransform(identity); 
       g2d.translate(alien[x].getxPos(),alien[x].getyPos()); 
       g2d.scale(2,2); 
       g2d.setColor(Color.BLUE); 
       g2d.fill(alien[x].getShape()); 
       g2d.setColor(Color.BLACK); 
       g2d.draw(alien[x].getShape()); 
      } 
     } 
    }//end paint 


    /***************************************************** 
    * key listener events 
    *****************************************************/ 
    public void keyReleased(KeyEvent k) { } 
    public void keyTyped(KeyEvent k) { } 
    public void keyPressed(KeyEvent k) { 
     int keyCode = k.getKeyCode(); 

     switch (keyCode) { 

     case KeyEvent.VK_A: 
      //move ship left 
      if(ship.getxPos()<20){ 
       ship.setxPos(20); 
      }else 
      ship.setxPos(ship.getxPos()-1); 
      break; 
     case KeyEvent.VK_D: 
      if(ship.getxPos()>1260){ 
       ship.setxPos(1260); 
      }else 
      ship.setxPos(ship.getxPos()+1); 
     } 
     repaint(); 
    }//end keypressed event 

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

回答

4

这些答案在某种程度上取决于您尝试创建的游戏类型。

从谷歌搜索我导致相信我应该有一个用户输入线程和一个游戏本身。

您创建了一个主游戏循环,它在自己的线程中运行。在psudeocode

while (running) { 
    update game model 
    draw game 
    wait x milliseconds 
} 

您的用户输入将直接更新游戏模型。游戏循环会更新游戏模型,如果计算机需要做出移动或对移动做出反应。然后,游戏循环读取游戏模型并根据模型中的值绘制游戏。

目前我已经在板类(代码如下所示)上实现了KeyListener,我应该把它放到它自己的类中并使它实现可运行吗?

是的,你应该把KeyListener放到它自己的类中。不,你不必把它作为一个单独的线程。

为了节省您未来的麻烦,您应该在Event Dispatch线程中定义和使用Swing组件。

下面是你如何做到这一点。

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new Board(); 
     } 
    }); 
} 

我应该使用的JPanel,而不是JFrame中和的paintComponent()用涂料()?

是的。

你应该在JFrame中有一个JPanel。 JPanel是使用paintComponent方法执行绘制游戏psudeocode的地方。

有些人会不同意我的看法,但是我发现如果游戏中的每个对象都有绘制方法来绘制它,那么最好。

public void draw(Graphics g) 

的博弈模型也将有一场平局方法,其中提请所有对象的模型。

JPanel中的paintComponent方法是这样的:

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    gameModel.draw(g); 
} 
+0

感谢吉尔伯特,一个晚上的休息和您的回复得到它的工作。 – SocialistPig 2013-03-01 10:54:30