代码之家  ›  专栏  ›  技术社区  ›  user2822797

Java游戏口吃

  •  0
  • user2822797  · 技术社区  · 11 年前

    我刚刚开始开发一款2d侧滚平面射击游戏。几天来,我一直对飞机的运动有问题。出于某种原因,每隔一秒钟左右,精灵似乎就会结巴。这几乎就像它跳回了一帧什么的,然后从它停下来的地方继续。我一直没有找到导致这种情况的原因。有什么想法吗? 整个项目可以在这里找到: http://www.upload.ee/files/3975636/planes.zip.html

    主要类别:

    package planes;
    
    import javax.swing.JFrame;
    
    import planes.Entities.Player;
    
    public class Game extends JFrame{
    
        private static final long serialVersionUID = 1L;
        private boolean isRunning = true;
        public static int fps = 60;
    
        private Frame frame;
        private InputHandler input;
        public static Player player;
    
        public static void main(String[] args) {
            Game game = new Game();
            game.run();
            System.exit(0);
        }
    
        public void update() {
            player.update();
        }
    
        public void draw() {
            frame.draw();
        }
    
        public void initialize() {
    
            Sprites.init();
            frame = new Frame();
            input = new InputHandler(frame);
            player = new Player(0, 0, Sprites.player, input);
    
        }
    
        public void run() {
            initialize();
    
            while (isRunning) {
                long time = System.currentTimeMillis();
    
                update();
                draw();
                time = (1000 / fps) - (System.currentTimeMillis() - time);
    
                if (time > 0) {
                    try {
                        Thread.sleep(time);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
    
            }
            setVisible(false);
        }
    
    }
    

    框架类别:

    package planes;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Insets;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.awt.image.ImageObserver;
    
    import javax.swing.JFrame;
    
    public class Frame extends JFrame{
    
        private Insets insets;
        private BufferedImage backBuffer;   
    
        Frame(){
            setTitle("Planes");
            setSize(Const.windowWidth, Const.windowHeight);
            setResizable(false);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            setVisible(true);
    
            insets = getInsets();
            setSize(insets.left + Const.windowWidth + insets.right, insets.top
                    + Const.windowHeight + insets.bottom);
            backBuffer = new BufferedImage(Const.windowWidth, Const.windowHeight,
                    BufferedImage.TYPE_INT_RGB);
        }
    
    
    
        public void draw(){
            Graphics2D g = (Graphics2D) getGraphics();
            Graphics2D bbg = (Graphics2D) backBuffer.getGraphics();
    
            bbg.setColor(Color.WHITE);
            bbg.fillRect(0, 0, Const.windowWidth, Const.windowHeight);
    
            Game.player.draw(bbg);
            bbg.drawRect(32, 32, 32, 32);
    
            g.drawImage(backBuffer, insets.left, insets.top, this);
        }
    
    }
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   Jason C    11 年前

    不要从主线程(或任何其他线程)绘制或访问GUI组件。只能安全地从Swing的 EDT 。按照你的程序现在的结构(你在主线程上的循环不断地直接重新绘制组件),所有的赌注都没有了。你应该使用Swing提供的基础设施;尤其是渲染 paint() 并通过 repaint() .

    我建议您将图形代码移动到组件的 paint(Graphics) ,然后在计时器上驱动游戏逻辑或将其保存在主线程中,然后使用 repaint() 触发重绘(它可以从任何线程调用,并将导致 油漆() 将在EDT上发生)。

    此外,当您最初创建帧时,请在EDT上通过例如。 SwingUtilities.invokeAndWait()

    从…起 http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html :

    忽略此规则的程序可能在大多数情况下正常运行,但会出现难以再现的不可预测错误。

    阅读官方教程 concurrency in Swing 。这会给你一个好的起点。