我不是很擅长编程,这是我的第一个使用Swing和AWT库的程序。我在缓冲游戏视图时遇到问题。这是我的Gra(游戏)类的代码。此类使用PropertiesGry类中的某些属性(如xPredkoscMax(xMaxVelocity)或某些坐标(在画布上构建月球和其他东西))来解析配置文件中的属性。
'''
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对象,计时器(licznikAnimacji)等的类。>>
'''
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方法没有被调用。我不知道为什么我应该在哪里传递可变缓冲策略的值以避免这种异常并显示我的飞船动画?
谢谢您的帮助。抱歉,如果有类似的问题,但是我是编程的初学者,不知道该怎么做。
我不是很擅长编程,这是我的第一个使用Swing和AWT库的程序。我在缓冲游戏视图时遇到问题。这是我的Gra(游戏)类的代码。此类使用...
由于createBufferStrategy
中定义了方法getBufferStrategy
和Canvas
,因此您可以向Gra
类中添加一个方法,然后从所需的任何地方调用它(Gra
构造函数或任务):