Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 游戏开始时屏幕有时为空白_Java_Screen - Fatal编程技术网

Java 游戏开始时屏幕有时为空白

Java 游戏开始时屏幕有时为空白,java,screen,Java,Screen,我一直在开发一个简单的游戏引擎。一切都进行得很顺利,我把地基修好了。我的意思是,游戏使用用户定义的显示设置进行设置,初始化内容,并启动游戏循环。一切都很好,除了我在窗口模式和全屏模式下都有问题: 在窗口模式下,有时屏幕将显示空白,直到我调整窗口大小或最小化窗口 在全屏显示中,如果使用默认的显示分辨率,我只会得到一个空白屏幕。其他大多数决议看起来都很好 以下是一些与显示屏幕相关的代码: 当用户按下“显示设置”对话框上的“播放”按钮时,将执行此操作 public void actionPerform

我一直在开发一个简单的游戏引擎。一切都进行得很顺利,我把地基修好了。我的意思是,游戏使用用户定义的显示设置进行设置,初始化内容,并启动游戏循环。一切都很好,除了我在窗口模式和全屏模式下都有问题:

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

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

以下是一些与显示屏幕相关的代码:

当用户按下“显示设置”对话框上的“播放”按钮时,将执行此操作

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);
}
最后,这里是gameLoop:

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方法并在单独的线程中运行它。我可以保证这是一个线程问题


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

我认为问题在于您试图在事件调度线程之外修改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();
}

如果有帮助的话,我建议您查看一下。

谢谢您的回复!关于你的代码有几个问题:你到底要我把它放在哪里?另外,我应该保留对run()方法的另一个线程调用吗?不幸的是,当您不在事件分派线程中并且想要操作某些Swing组件时,您到处都需要它。事实上,我刚刚看到你在使用EGameCanvas,所以如果这是个问题的话,我可能错了。是的。EGameCanvas扩展了Canvas类,这就是我进行所有绘图/渲染的地方。正如我在OP中所说,每次我运行它时,屏幕都会出现并完美地绘制。也就是说,直到我将run()方法放在一个单独的线程中。