Java重绘gui

时间:2015-12-09 17:20:46

标签: java paint frame-rate

在我的2D游戏中我有主类和gameWindow类,在主类我有一个更新方法,每秒更新60次,我想从gameWindow类调用重绘方法并在主要调用它更新时的课程

主要类别:

private static final int FPS = 60;

public static void main(String[] args){

    new Main().startGame();

    gameWindow g = new gameWindow();
    g.setSize(900, 700);
    g.setVisible(true);
    g.setDefaultCloseOperation(EXIT_ON_CLOSE);
    g.setResizable(true);
}

/**
 * they main method that will run the gameWindow and also runs on the FPS and to maintain the same FPS
 */
private void startGame() {

    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    executor.scheduleAtFixedRate(new Runnable(){

        public void run(){

            updateGame();
        }

    },0, 1000 / FPS, TimeUnit.MILLISECONDS);
}

/**
 * what should be include when the game is updated by the FPS method
 */
public void updateGame() {

    //here where i wanna call the repaint method
    repaint();
}

gameWindow Class中没有什么我想要的是在gameUpdate()中调用重绘方法

1 个答案:

答案 0 :(得分:0)

这可能有些过分,但我使用FPS实现可重绘组件的策略是使用OOP模式的四个步骤。

注意前两个步骤可以用于任何对象,而不仅仅是GUI组件。

用于委派手动刷新的界面

public interface IRefreshable {
    public void refresh();
}

接受IRefreshable实现和FPS

的Thread对象
public class Repainter extends Thread {
    private int fps;
    private final IRefreshable comp;

    public Repainter(IRefreshable comp, int fps) {
        this.comp = comp;
        this.fps = fps;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(1000 / this.fps);
                this.comp.refresh();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void setFPS(int fps) {
        this.fps = fps;
    }
} 

维护FPS的抽象JComponent和重绘组件的线程

public abstract class RepaintableComponent extends JComponent implements IRefreshable {

    private static int FPS = 60;
    protected Repainter repainterThread;

    public RepaintableComponent(boolean continuousRedraw) {
        if (continuousRedraw) {
            repaintAtFPS(FPS);
        }
    }

    public RepaintableComponent() {
        this(true);
    }

    protected void repaintAtFPS(int fps) {
        if (this.repainterThread == null) {
            this.repainterThread = new Repainter(this, fps);
            this.repainterThread.start();
        } else {
            this.repainterThread.setFPS(fps);
        }
    }

    @Override
    public void refresh() {
        repaint();
        revalidate();
    }
}

最后,RepaintableComponent的(未经测试的)具体实现。此面板上对setColor的任何以下调用都应更新其背景颜色。

public class ColoredPanel extends RepaintableComponent {
    private Color bg;

    public ColoredPanel(Color c) {
        super();
        this.bg = c;
        initGUI();
    }

    private void initGUI() {
        BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
        setLayout(layout);
    }

    public void setColor(Color c) {
        this.bg = c;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(bg);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}