Java bufferstrategy, графическая ошибка: буферы не созданы

Недавно я делал небольшую игру, и у меня возникла странная проблема. Хотя игра работает просто отлично, когда я не использую game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); но метод stop(), чтобы закрыть его, я получаю сообщение об ошибке, и я действительно не понимаю, почему.

Ошибка:

Exception in thread "thread" Program closed, processes halted
java.lang.IllegalStateException: Buffers have not been created
at sun.awt.windows.WComponentPeer.getBackBuffer(WComponentPeer.java:1018)
at java.awt.Component$FlipBufferStrategy.getBackBuffer(Component.java:4065)
at 
java.awt.Component$FlipBufferStrategy.updateInternalBuffers(Component.java:4
050)
at java.awt.Component$FlipBufferStrategy.revalidate(Component.java:4165)
at java.awt.Component$FlipBufferStrategy.revalidate(Component.java:4147)
at java.awt.Component$FlipBufferStrategy.getDrawGraphics(Component.java:4139)
at com.bacskai.peashooter.Game.render(Game.java:105)
at com.bacskai.peashooter.Game.run(Game.java:75)
at java.lang.Thread.run(Thread.java:748)

Пожалуйста, дайте решения, которые не слишком сложны, потому что я все еще новичок, и игра все еще находится в стадии разработки.

Полный код:

package com.bacskai.peashooter;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;

public class Game extends Canvas implements Runnable, KeyListener {

private static final long serialVersionUID = -4227990863874935837L;

JFrame frame;
static Dimension d;
Thread thread;


public static int width = 300;
public static int height = width / 16 * 9;
int scale = 3;

boolean running;

int[][] track = new int[5][900];

int playerY = 3;
int health = 3;
int score = 0;

public Game() {

    d = new Dimension(width * scale, height * scale);
    setPreferredSize(d);
    frame = new JFrame();

}

public static void main(String[] args) {

    Game game = new Game();

    game.frame.setResizable(false);
    game.frame.setTitle("Peasooter");
    game.frame.add(game);
    game.frame.pack();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setLocationRelativeTo(null);
    game.frame.setVisible(true);
    game.frame.addKeyListener(game);

    game.start();

}

private void start() {

    System.out.println("Program started");
    thread = new Thread(this, "thread");
    running = true;
    thread.start();

    System.out.println("Window width: " + getWidth() + ", height: " + 
 getHeight());

}

public void run() {

    while (running) {

        update();
        render();

    }

}

private void stop() {

    try {
        frame.dispose();
        thread.join();

    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("Program closed, processes halted");
}

public void update() {



}

private void render() {

BufferStrategy bs = getBufferStrategy();

if (bs == null) {createBufferStrategy(3); return;}

Graphics g = bs.getDrawGraphics();

// Map

g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.cyan);
g.fillRect(100, 0, 10, 490);
g.fillRect(0, 98, 900, 10);
g.fillRect(0, 196, 900, 10);
g.fillRect(0, 294, 900, 10);
g.fillRect(0, 392, 900, 10);

g.setColor(Color.red);
Font font = new Font("Default", Font.PLAIN, 50);
g.setFont(font);
g.drawString("Score: " + score, 700, 50);

// Player

g.setColor(Color.green);

// Enemies

g.setColor(Color.red);

// Projectiles
g.setColor(Color.green);



bs.show();
g.dispose();    
} // End of render


public void keyTyped(KeyEvent e) {}

public void keyPressed(KeyEvent e) {

    if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
        stop();
    }

}

public void keyReleased(KeyEvent e) {}

}

person Kristóf Bácskai    schedule 18.06.2018    source источник


Ответы (1)


Это ожидаемое поведение при использовании thread.stop();

Из старого отчета об ошибке видно, что это не проблема:

Также обратите внимание, что эту проблему сложно воспроизвести, и она не имеет других последствий , кроме дампа трассировки стека в консоли (не зависает, не сообщается о визуальных артефактах). Из-за этого я уменьшаю приоритет для этого CR.

Поэтому, если вы хотите, чтобы это было просто, измените свой блок кода, чтобы поймать и игнорировать ошибку:

private void stop() {
    try {
        frame.dispose();
        thread.join();
    } catch (IllegalStateException e) {
        //Do nothing
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("Program closed, processes halted");
}

В противном случае, если вы предпочитаете использовать решение без кода, вы можете добавить этот -Dsun.java2d.d3d=false в свою команду в качестве параметра при запуске приложения следующим образом:

java -jar путь_к/jar_file/myjar.jar -Dsun.java2d.d3d=false

person sorifiend    schedule 19.06.2018