【问题标题】:Screen Sometimes Blank at Game Start游戏开始时屏幕有时空白
【发布时间】:2012-11-21 05:11:25
【问题描述】:

我一直在研究一个简单的游戏引擎。一切都很顺利,我完成了基础。我的意思是,游戏设置了用户定义的显示设置,初始化内容,然后开始游戏循环。一切都很好,除了我在窗口模式和全屏模式下都有问题:

在窗口模式下,有时屏幕会显示为空白,直到我调整窗口大小或最小化窗口。

在全屏模式下,如果我使用默认显示分辨率,我只会得到一个空白屏幕。大多数其他分辨率看起来都很好。

这里是一些与显示屏幕相关的代码:

这是在用户按下显示设置对话框上的播放按钮时执行的

public void actionPerformed(ActionEvent e) {
            DisplayMode dm = modes[resolutionBox.getSelectedIndex()];
            boolean fs = fullscreenBox.getSelectedItem().equals ("Fullscreen");
            boolean vs = vSyncCheckBox.isSelected();

            game.initScreen (dm, fs, vs);
            runGame (game);

            f.dispose();
        }
    });

private final void runGame(EGame g)
{
    Thread t = new Thread (g);
    t.start();
}

这是EGame类中的run方法

public final void run() {
    start();
    isRunning = true;
    gameLoop();
    endGame();
}

引擎的用户会在start()方法中调用setGameCanvas()方法。 start() 方法中可以执行其他操作,但对于我的测试游戏,它只是该方法:

protected final void setGameCanvas(EGameCanvas c)
{
    screen.remove (canvas);
    canvas = c;
    canvas.addKeyListener (keyboard);
    screen.add (canvas);
}

最后,这里是游戏循环:

private final void gameLoop()
{
    // Final setup before starting game
    canvas.setBuffer (2);
    screen.addKeyListener (keyboard);
    canvas.addKeyListener (keyboard);

    int TARGET_FPS = screen.getTargetFps();
    final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;

    long lastLoopTime = System.nanoTime();

    long now = 0;
    long lastFpsTime = 0;
    long updateLength = 0;
    double delta = 0;

    int fps = 0;

    while (isRunning)
    {
        now = System.nanoTime();
        updateLength = now - lastLoopTime;
        lastLoopTime = now;
        delta = updateLength / ((double) OPTIMAL_TIME);

        lastFpsTime += updateLength;
        fps++;

        if (lastFpsTime >= 1000000000)
        {
            screen.setFps (fps);
            lastFpsTime = 0;
            fps = 0;
        }

        keyboard.poll();
        keyboardEvents();

        update (delta);

        render();

        try {
            Thread.sleep( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000 );
        }
        catch (Exception ex) {}
    }
}

现在,请记住,我的问题都不存在,直到我添加了 run 方法并在单独的线程中运行它。我可以保证这是一个线程问题。

但是,我不是专家,所以任何建议都将不胜感激。

【问题讨论】:

    标签: java screen


    【解决方案1】:

    我认为问题在于您试图在事件调度线程之外修改与 GUI 相关的组件 - 这是唯一允许修改图形界面的线程,否则您可能会遇到这样的问题。

    要检查此尝试是否解决了以下问题:

    try {
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeAndWait( new Runnable() {
                @Override
                public void run() {
                    // Do rendering and other stuff here...
                }
            });
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    

    如果有帮助,我建议您查看Concurrency in Swing tutorial。

    【讨论】:

    • 感谢您的回复!关于你的代码的几个问题:你到底要我把它放在哪里?另外,我应该保留对 run() 方法的其他线程调用吗?
    • 不幸的是,当您不在 Event Dispatch Thread 中并且想要操作一些 Swing 组件时,您将到处需要它。实际上,我刚刚看到您正在使用 EGameCanvas,所以如果这是问题所在,我可能是错的。
    • 是的。 EGameCanvas 扩展了 Canvas 类,这就是我进行所有绘图/渲染的地方。就像我在 OP 中所说的那样,每次运行时屏幕都会出现并完美绘制。也就是说,直到我将 run() 方法放在单独的线程中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 2011-09-20
    • 2019-02-10
    相关资源
    最近更新 更多