我想用一個簡單的方法來實現一個像憤怒的小鳥一樣的遊戲,因爲每當用戶點擊投籃按鈕時,一個球就會被扔向三個方格。如果他們有交集,應該打印出「碰撞」信息。 這裏是我的課:如何解決空值錯誤以便成功檢測碰撞?
import javax.swing.*;
public class ProjectileShooterTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ProjectileShooterPanel.createAndShowGUI();
}
});
}
}
和:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
class ProjectileShooterPanel extends JPanel {
static Rectangle gerd;
static Rectangle hadaf1;
static Rectangle hadaf2;
static Rectangle hadaf3;
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 600);
final ProjectileShooter projectileShooter = new ProjectileShooter();
ProjectileShooterPanel projectileShooterPanel = new ProjectileShooterPanel(
projectileShooter);
projectileShooter.setPaintingComponent(projectileShooterPanel);
JPanel controlPanel = new JPanel(new GridLayout(1, 0));
controlPanel.add(new JLabel("Angle"));
final JSlider angleSlider = new JSlider(0, 90, 45);
controlPanel.add(angleSlider);
controlPanel.add(new JLabel("Power"));
final JSlider powerSlider = new JSlider(0, 100, 50);
controlPanel.add(powerSlider);
JButton shootButton = new JButton("Shoot");
shootButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int angleDeg = angleSlider.getValue();
int power = powerSlider.getValue();
projectileShooter.setAngle(Math.toRadians(angleDeg));
projectileShooter.setPower(power);
projectileShooter.shoot(gerd,hadaf1,hadaf2,hadaf3);
}
});
controlPanel.add(shootButton);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(controlPanel, BorderLayout.NORTH);
f.getContentPane().add(projectileShooterPanel, BorderLayout.CENTER);
f.setVisible(true);
}
private final ProjectileShooter projectileShooter;
public ProjectileShooterPanel(ProjectileShooter projectileShooter) {
this.projectileShooter = projectileShooter;
}
@Override
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
Projectile projectile = projectileShooter.getProjectile();
if (projectile != null) {
g.setColor(Color.RED);
Point2D position = projectile.getPosition();
int x = (int) position.getX();
int y = getHeight() - (int) position.getY();
gerd = new Rectangle(x - 01, y - 10, 20, 20);
g.draw(gerd);
// g.fillOval(x-01, y-10, 20, 20);
}
hadaf1 = new Rectangle(450, 450, 50, 50);
hadaf2 = new Rectangle(500, 450, 50, 50);
hadaf3 = new Rectangle(475, 400, 50, 50);
g.draw(hadaf1);
g.draw(hadaf2);
g.draw(hadaf3);
}
}
和:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
class ProjectileShooter {
private double angleRad = Math.toRadians(45);
private double power = 50;
private Projectile projectile;
private JComponent paintingComponent;
void setPaintingComponent(JComponent paintingComponent) {
this.paintingComponent = paintingComponent;
}
void setAngle(double angleRad) {
this.angleRad = angleRad;
}
void setPower(double power) {
this.power = power;
}
void shoot(Rectangle test, Rectangle test1, Rectangle test2, Rectangle test3) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
executeShot();
}
});
t.setDaemon(true);
t.start();
if (test3.intersects(test))
{System.out.println("collision");}
}
private void executeShot() {
if (projectile != null) {
return;
}
projectile = new Projectile();
Point2D velocity = AffineTransform.getRotateInstance(angleRad).transform(
new Point2D.Double(1, 0), null);
velocity.setLocation(velocity.getX() * power * 0.5, velocity.getY() * power * 0.5);
projectile.setVelocity(velocity);
long prevTime = System.nanoTime();
while (projectile.getPosition().getY() >= 0) {
long currentTime = System.nanoTime();
double dt = 3 * (currentTime - prevTime)/1e8;
projectile.performTimeStep(dt);
prevTime = currentTime;
paintingComponent.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
projectile = null;
paintingComponent.repaint();
}
Projectile getProjectile() {
return projectile;
}
}
和:
import java.awt.geom.Point2D;
class Projectile {
private final Point2D ACCELERATION = new Point2D.Double(0, -9.81 * 0.1);
private final Point2D position = new Point2D.Double();
private final Point2D velocity = new Point2D.Double();
public Point2D getPosition() {
return new Point2D.Double(position.getX(), position.getY());
}
public void setPosition(Point2D point) {
position.setLocation(point);
}
public void setVelocity(Point2D point) {
velocity.setLocation(point);
}
void performTimeStep(double dt) {
scaleAddAssign(velocity, dt, ACCELERATION);
scaleAddAssign(position, dt, velocity);
}
private static void scaleAddAssign(Point2D result, double factor, Point2D addend) {
double x = result.getX() + factor * addend.getX();
double y = result.getY() + factor * addend.getY();
result.setLocation(x, y);
}
}
但是當我執行它,它不申報碰撞,我得到t他的錯誤:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.awt.Rectangle.intersects(Rectangle.java:786)
at ProjectileShooter.shoot(ProjectileShooter.java:34)
at ProjectileShooterPanel$1.actionPerformed(ProjectileShooterPanel.java:38)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
我應該如何解決它?請給我我的答案,我是新的Java。 謝謝
在'shoot()'方法中使用它之前,您是否初始化過'gerd'變量? –
它看起來像是在paintComponent()中初始化的,但我在想同樣的事情。 – Addison
我不確定,它在paintComponent類中初始化,但不知道它是否在方法拍攝之前? – user2266688