创建游戏循环线程

时间:2013-02-27 19:00:32

标签: java game-loop

嗨,我刚刚搞砸了多边形和awt。我创建了一个Jframe,可以绘制好多边形,然后让其中一个用按键移动。

我想知道如何启动一个游戏循环线程(以及放置它的位置!),它将独立更新jframe。

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

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

一天大部分时间都在这里,我非常非常困惑:) 一如往常任何帮助非常感谢!

另外,虽然我可以使用JPanel代替JFrame和paintComponent()代替paint()吗?

来自在线tutourials
    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();
    }
}

1 个答案:

答案 0 :(得分:4)

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

  

从谷歌搜索我开始相信我应该有一个线程供用户输入,一个用于游戏本身。

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

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

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

  

目前我已在Board类上实现了KeyListener(如下所示的代码),我应该将它放到自己的类中并使其实现runnable吗?

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

为了避免将来遇到麻烦,应该在Event Dispatch线程上定义和使用Swing组件。

这是你如何做到的。

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

我应该使用JPanel代替JFrame和paintComponent()而不是paint()吗?

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

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

public void draw(Graphics g)

游戏模型还有一个绘制方法,它绘制模型中的所有对象。

JPanel paintComponent方法如下所示:

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