سؤال

I've just started developing a 2d side-scrolling plane shooter. For a couple of days now i've had a problem with the movement of the plane. For some reason, every second or so, the sprite seems to stutter. It's almost as if it jumped back a frame or something, and then continued from where it left off. I have had no luck finding what is causing this. Any thoughts? The entire project can be found here: http://www.upload.ee/files/3975636/planes.zip.html

Main class:

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);
    }

}

Frame class:

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);
    }

}
هل كانت مفيدة؟

المحلول

Do not draw on or access GUI components from the main thread (or any other thread for that matter). You can only safely render components from Swing's EDT. With the way your program is structured right now (your loop on the main thread constantly directly repainting the component), all bets are off. You should use the infrastructure that Swing provides you; in particular, render in paint() and trigger updates properly via repaint().

I suggest you move your drawing code into the component's paint(Graphics), then either drive game logic on a timer or keep it in the main thread, and use repaint() to trigger redraws (it can be called from any thread, and will cause paint() to happen on the EDT).

Also, when you initially create your frame, do it on the EDT via e.g. SwingUtilities.invokeAndWait()

From http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html:

Programs that ignore this rule may function correctly most of the time, but are subject to unpredictable errors that are difficult to reproduce.

Have a read of the official tutorial on concurrency in Swing. It will give you a good starting point.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top