0

Я хочу реализовать игру, как сердитые птицы, используя свинг, но простым способом. Так что всякий раз, когда пользователь нажимает кнопку стрелять, мяч будет брошен в три квадрата. И если у них есть пересечение, сообщение «столкновения» должно быть распечатано. Вот мои классы:как решить нулевую ошибку, чтобы быть успешным для обнаружения столкновений?

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. спасибо

+0

Вы инициализировали переменную 'gerd', прежде чем использовать ее в методе' shoot() '? –

+0

Похоже, он был инициализирован в paintComponent(), но я думал об одном и том же. – Addison

+0

Я не уверен, он инциализирован в классе paintComponent, но не уверен, что это до того, как стрелять методом или нет? – user2266688

ответ

0

В классе ProjectileShooterPanel все ссылки gerd, hadaf1, hadaf2, hadaf3 is null.

class ProjectileShooterPanel extends JPanel { 
    static Rectangle gerd; 
    static Rectangle hadaf1; 
    static Rectangle hadaf2; 
    static Rectangle hadaf3; 

Вы должны инициализирован его перед перевале стрелять методу

projectileShooter.shoot(gerd,hadaf1,hadaf2,hadaf3); 
+0

Примечание: это выполняется в paintComponent(). Я не уверен, что вы называете это в другом месте. – Addison

0

Вы выполнить пересекается - проверка на Event-Thread, который выполняет actionPerformed на вашем shootButton - ActionListener. Я предполагаю, что вы действительно хотите сделать, это повторить эту проверку, например, на каждой итерации цикла вашего движения или, возможно, на каждой перерисовке.

Я предлагаю вам перенести эту проверку в место, где вы знаете, что Rectangles инициализированы - например. в вашем paintComponent.

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

Смежные вопросы