Проблема с NullPointerException в методе Анимация - PullRequest
0 голосов
/ 26 апреля 2020

Я не очень хорош в программировании, это моя самая первая программа, которая использует библиотеки Swing и AWT. У меня проблема при буферизации моего игрового обзора. Вот код моего класса Gra (игры). Этот класс использует некоторые атрибуты, такие как xPredkoscMax (xMaxVelocity) или некоторые координаты (для построения луны и других объектов на холсте) из класса PropertiesGry, который выполняет синтаксический анализ атрибутов из файла конфигурации.

'' '

public class Gra extends Canvas {

private BufferStrategy bufferStrategy = null;
int score = 1000;
boolean hasCrushed;
boolean hasWon;
boolean isPaused = false;
int vy;
int vx;
int x;
int y;
boolean plus300Taken = false;
boolean minus300Taken = false;
public boolean minusShipTaken = false;
public static Timer timerForBonuses;
int time = 10;

Gra(int level) throws IOException {
    PropertiesGry.wczytajPlansze(level);
    x = PropertiesGry.xStartoweStatku[0];
    //bonusesTime();
}


private void shipLocation() {
    y = y + vy;
    if (vy < abs(PropertiesGry.yPredkoscMax)) vy++;
    if (vx > abs(PropertiesGry.yPredkoscMax)) vx = PropertiesGry.yPredkoscMax;
    if (vx < -PropertiesGry.yPredkoscMax) vx = -PropertiesGry.yPredkoscMax;
    x = x + vx;
    if (x > PropertiesGry.SZEROKOSC * 0.97)
        x = (int) (PropertiesGry.SZEROKOSC * 0.97);
    if (y < 0)
        y = 0;
    if (x < 0)
        x = 0;
    if (vx > 1) vx--;
    if (vx < -1) vx++;
}

@Override
public void addNotify() {
    super.addNotify();
    createBufferStrategy(3);
    bufferStrategy = getBufferStrategy();
}


@Override
public void paint(Graphics graphics) {
    super.paint(graphics);

    Shape moon = new Polygon(PropertiesGry.xWierzcholkiPlanety, PropertiesGry.yWierzcholkiPlanety, PropertiesGry.xWierzcholkiPlanety.length);
    Shape landing = new Polygon(PropertiesGry.xLadowiska, PropertiesGry.yLadowiska, PropertiesGry.xLadowiska.length);
    Graphics2D graphics2D = (Graphics2D) graphics;
    setBackground(new Color(47, 46, 64));
    graphics.clearRect(0, 0, getWidth(), getHeight());

    AffineTransform scaleTransform = graphics2D.getTransform();
    AffineTransform scaleMatrix = new AffineTransform();
    float xScale = (1f + (getSize().width - PropertiesGry.SZEROKOSC) / (float) PropertiesGry.SZEROKOSC);
    float yScale = (1f + (getSize().height - PropertiesGry.WYSOKOSC) / (float) PropertiesGry.WYSOKOSC);
    scaleMatrix.scale(xScale, yScale);
    graphics2D.setTransform(scaleMatrix);

    Rectangle2D ship = new Rectangle2D.Float(x, y, 25, 25);
    graphics2D.setColor(Color.white);
    graphics2D.fill(ship);

    graphics2D.setColor(Color.green);
    graphics2D.fill(landing);

    graphics2D.setColor(Color.gray);
    graphics2D.fill(moon);

    if (!plus300Taken) {
        Shape bonus = new Polygon(PropertiesGry.xBonusu, PropertiesGry.yBonusu, PropertiesGry.xBonusu.length);
        graphics2D.setColor(Color.yellow);
        graphics2D.fill(bonus);
        plus300(ship, bonus);
    }

    graphics2D.setTransform(scaleTransform);
    isColliding(moon, landing, ship);
}


private void isColliding(Shape moon, Shape landing, Rectangle2D player) {
    if ((moon.intersects(player)) || (landing.intersects(player)) && Math.abs(vy) > PropertiesGry.yPredkoscLadowania) {
        hasCrushed = true;
        hasWon = false;
    }
    if (landing.intersects(player) && Math.abs(vy) <= PropertiesGry.yPredkoscLadowania && Math.abs(vx) <= Math.abs(PropertiesGry.xPredkoscLadowania)) {
        hasWon = true;
        hasCrushed = false;
    }
}


private void minus300(Rectangle2D player, Shape minus) {
    if (minus.intersects(player)) {
        score -= 300;
        minus300Taken = true;
    }
}


private void plus300(Rectangle2D player, Shape bonus) {
    if (bonus.intersects(player)) {
        score += 300;
        //plus300Taken = true;
    }
}

private void deletebonuses() {
    plus300Taken = true;

}


public void isPaused() {
    this.isPaused = true;
}


public void isResumed() {
    this.isPaused = false;
}


public class AnimationTimerTask extends TimerTask {
    int i = 0;

    public void run() {
        if (!isPaused) {
            if (i == 2) {
                shipLocation();
                i = 0;
            }
            i++;
        }
        do {
            do {
                Graphics graphics = bufferStrategy.getDrawGraphics();
                paint(graphics);
                graphics.dispose();
                if (!isPaused) score--;

                //System.out.println(score);
            } while (bufferStrategy.contentsRestored());
                bufferStrategy.show();
            } while (bufferStrategy.contentsLost());
        }
    }
}

'' '

Вот мой класс, где я создаю объект Gra, Timer (licznikAnimacji) et c.

' ''

public abstract class Logika {
Timer licznikAnimacji;

public void oknoGry(int numerPlanszy) throws IOException {
JFrame ramka = new JFrame("Gra");
ramka.setSize(PropertiesGry.SZEROKOSC,PropertiesGry.WYSOKOSC);
ramka.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
ramka.setLocationRelativeTo(null);
ramka.setLayout(new BorderLayout());

JPanel panel = new JPanel();
panel.setLayout(new GridLayout(5,1));

panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0,0,0,0),BorderFactory.createMatteBorder(5,5,5,5,new Color(94, 179, 228))));    
JButton bPauza = new JButton("PAUZA");

panel.add(bPauza);

JLabel lStatki = new JLabel("", SwingConstants.CENTER);
panel.add(lStatki);

JLabel lPaliwo = new JLabel("", SwingConstants.CENTER);
panel.add(lPaliwo);

JLabel lPredkoscX = new JLabel("", SwingConstants.CENTER);
panel.add(lPredkoscX);

JLabel lPredkoscY = new JLabel("", SwingConstants.CENTER);
panel.add(lPredkoscY);

ramka.add(panel,BorderLayout.EAST);

licznikAnimacji = new Timer();
Gra gra = new Gra(numerPlanszy);

licznikAnimacji.scheduleAtFixedRate(gra.new AnimationTimerTask(), 100, 25);
//this.setFocusable(false);
ramka.add(gra);

Klawiatura klawiatura = new Klawiatura(gra);
ramka.addKeyListener(klawiatura);

ramka.requestFocus();
//ramka.setVisible(true);

//setBackground(Color.BLACK);

new Thread(() -> {
    while (!gra.hasCrushed && !gra.hasWon) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        lPredkoscX.setText("PRĘDKOŚĆ X: " + gra.vx);
        if (Math.abs(gra.vx) > PropertiesGry.xPredkoscLadowania)
            lPredkoscX.setForeground(Color.RED);
            lPredkoscY.setText("PRĘDKOŚĆ Y: " + gra.vy);
        if (Math.abs(gra.vy) > PropertiesGry.yPredkoscLadowania)
            lPredkoscY.setForeground(Color.RED);
    }
    try {
        resetujLicznikAnimacji();
        if (gra.czyWyladowano) {

        }
        if (gra.czyRozbitoSie && gra.liczbaStatkow > 1) {

        }
        if (gra.czyRozbitoSie && gra.liczbaStatkow <= 1) {

        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    }).start();
}

public void resetujLicznikAnimacji() {
    licznikAnimacji.cancel();
    licznikAnimacji.purge();
}

}

'' '

Проблема в том, что когда я запускаю эту программу, появляется исключение:

Exception in thread "Timer-0" java.lang.NullPointerException
at Gra$AnimationTimerTask.run(Gra.java:601)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)

601-я строка

 Graphics graphics = bufferStrategy.getDrawGraphics();

Что мне делать? Похоже, что метод addNotify не был вызван. Я не знаю почему. Где я должен передать значение переменной bufferstrategy, чтобы избежать этого исключения и отобразить анимацию моего корабля?

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

1 Ответ

0 голосов
/ 26 апреля 2020

Поскольку методы createBufferStrategy и getBufferStrategy определены в Canvas, вы можете добавить метод к вашему классу Gra и вызывать его из любого места (конструктор Gra или задача):

private BufferStrategy getInitializedBufferStrategy() {
    BufferStrategy strategy = getBufferStrategy();
    if (null == strategy) {
        createBufferStrategy(3);
        strategy = getBufferStrategy();
    }
    return strategy;
}

затем в коде задачи замените вызов экземпляра:

Graphics graphics = getInitializedBufferStrategy().getDrawGraphics();
...