0

我几乎完成了我最后一个项目的第一个小型 Java 游戏。这是一个横向卷轴,您必须在其中射击/避开小行星。我的最后一个问题是弄清楚如何让我的小行星阵列与玩家的激光相撞。这是我到目前为止所拥有的,第 137 行有一个“AWT-EventQueue-0”java.lang.NullPointerException”,我无法处理。感谢您的帮助。

编辑:我在我的其他课程中添加了,我意识到如果我没有告诉你它来自哪里,就很难判断我的代码的功能。

package ShooterGame;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.*;

public class Board extends JPanel implements ActionListener
{   
    Enemy[] baddies = new Enemy[10000];
    Player p;
    Image img;
    int y;
    Timer time;
    boolean lost = false;
    static Font font = new Font("SanSerif", Font.BOLD, 24);
    public AudioClip theme, bang, laser;    
    static ArrayList<Enemy> enemies;

    public static int score = 0;
    public static int lives = 5;

    public Board() 
    {           
        p = new Player();       
        addKeyListener(new ActionListener());
        setFocusable(true);
        ImageIcon i = new ImageIcon("images/background.png");
        img = i.getImage();

        time = new Timer(5, this);
        time.start();

        for(int j = 0; j < baddies.length; j++)
        {   
            Random ran = new Random();
            y = ran.nextInt(365)+1;
            baddies[j]= new Enemy((100*j + 700), y, "images/asteroid.gif");
        }

        theme = Applet.newAudioClip(getClass().getResource("theme.mid"));
        theme.play();

        bang = Applet.newAudioClip(getClass().getResource("bang.wav"));
    }

    public void actionPerformed(ActionEvent e)
    {
        checkCollisions();
        ArrayList<?> bullets = Player.getBullets();

        for(int i = 0; i < bullets.size(); i++)
        {
            Bullet b = (Bullet)bullets.get(i);

            if(b.isVisible() == true)
            {
                b.move();
            }
            else
            {
                bullets.remove(i);
            }
        }

        p.move();
        for(int i = 0; i < baddies.length; i++)
        {
            if(p.x > 400)
            {
                baddies[i].move(p.getdx());
            }
        }

        repaint();
    }

    public void paint(Graphics g)
    {   
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

        if(lost)
        {
            g2d.drawString("You Lose!", 300, 300);
        }

        if((p.getX() - 590) % 2400 == 0 || (p.getX() - 590) % 2400 == 1)
        {
            p.nx = 0;
        }

        if((p.getX() - 1790) % 2400 == 0 ||(p.getX() - 1790) % 2400 == 1)
        {
            p.nx2 = 0;
        }

        g2d.drawImage(img, 685-p.nx2, 0, null);

        if(p.getX() >= 590)
        {
            g2d.drawImage(img, 685-p.nx, 0, null);
        }

        g2d.drawImage(p.getImage(), p.edge, p.getY(), null);

        ArrayList<?> bullets = Player.getBullets();
        for(int i = 0; i < bullets.size(); i++)
        {
            Bullet b = (Bullet)bullets.get(i);
            g2d.drawImage(b.getImg(), b.getX(), b.getY(), null);

        }
            for(int i = 0; i < baddies.length; i++)
            {
                if(baddies[i].isAlive == true)
                {
                    g2d.drawImage(baddies[i].getImg(), baddies[i].getX(), baddies[i].getY(), null);
                }
            }

        g2d.setColor(Color.white);
        g2d.drawString("Score: " + score, 0, 320);
        g2d.drawString("Lives: " + lives, 80, 320);
    }

    public void checkCollisions()
    {       
        Rectangle[] rect = new Rectangle[baddies.length];
        for(int i = 0; i < baddies.length; i++)
        {
            Enemy e = (Enemy)baddies[i];
            rect[i] = e.getBounds();
        }

        ArrayList<?> bullets = Player.getBullets();
        for (int i = 0; i < bullets.size(); i++)
        {
            Bullet b = (Bullet) bullets.get(i);
            Rectangle b1 = b.getBounds();

            if (rect[i].intersects(b1) && baddies[i].isAlive())
            {
                score++;
                baddies[i].isAlive = false;
                baddies[i].isVisible = false;
                bang.play();
             }

            Rectangle h = p.getBounds();
            if (h.intersects(rect[i]))
            {
                if(baddies[i].isAlive() == true)
                {
                    lives--;
                    if(lives < 0)
                    {
                        lost = true;
                        theme.stop();
                        System.exit(1);
                    }
                }
            }
        }
    }

    private class ActionListener extends KeyAdapter
    {
        public void keyReleased(KeyEvent e)
        {
            p.keyReleased(e);
        }

        public void keyPressed(KeyEvent e)
        {
            p.keyPressed(e);
        }
    }
}

敌人

package ShooterGame;

import java.awt.*;

import javax.swing.ImageIcon;

public class Enemy 
{
    int x, y;
    Image img;
    boolean isAlive = true;
    boolean isVisible = true;


    public Enemy(int startX, int startY, String location)
    {
        x = startX;
        y = startY;
        ImageIcon l = new ImageIcon(location);
        img = l.getImage();
    }

    public Rectangle getBounds()
    {
        return new Rectangle(x, y, 60, 60);
    }


    public int getX() 
    {
        return x;
    }

    public int getY() 
    {
        return y;
    }

    public boolean isAlive() 
    {
        return isAlive;
    }

    public boolean isVisible() 
    {
        return isVisible;
    }

    public Image getImg() 
    {
        return img;
    }   

    public void move(int dx)
    {
        x = x - dx;
    }

}

子弹

package ShooterGame;

import java.applet.Applet;
import java.awt.*;
import javax.swing.ImageIcon;
import java.applet.AudioClip;

public class Bullet 
{   
    int x, y;
    Image img;
    boolean visible;

    public Bullet(int startX, int startY)
    {
        x = startX;
        y = startY;

        ImageIcon newBullet = new ImageIcon("images/bullet.gif");
        img = newBullet.getImage();
        visible = true;
    }

    public Rectangle getBounds()
    {
        return new Rectangle(x, y, 9, 5);
    }

    public int getX() 
    {
        return x;
    }

    public int getY() 
    {
        return y;
    }

    public Image getImg() 
    {
        return img;
    }

    public boolean isVisible() 
    {
        return visible;
    }

    public void move()
    {
        x = x + 2;
        if(x > 700)
        {
            visible = false;
        }
    }

    public void setVisible(boolean isVisible)
    {
        visible = isVisible;
    }
}

播放器

package ShooterGame;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import javax.swing.ImageIcon;

public class Player 
{

    int x, dx, y, dy, nx2, nx, edge, ceiling; 
    Image player;
    ImageIcon ib = new ImageIcon("images/player1back.gif");
    ImageIcon i = new ImageIcon("images/playerstill.gif");
    ImageIcon f = new ImageIcon("images/playerforward.gif");
    ImageIcon up = new ImageIcon("images/playerup.gif");
    ImageIcon down = new ImageIcon("images/playerdown.gif");
    public AudioClip laser;
    static ArrayList<Bullet> bullets;

    public Player()
    {laser = Applet.newAudioClip(getClass().getResource("laser.wav"));
        player = ib.getImage();
        x = 75;
        nx = 0;
        nx2 = 685;
        y = 172;
        edge = 150;
        ceiling = 0;
        bullets = new ArrayList<Bullet>();
    }

    public static ArrayList<Bullet> getBullets()
    {
        return bullets;
    }

    public void fire()
    {
        Bullet z = new Bullet((edge + 60), (y+17));
        bullets.add(z); 
    }

    public Rectangle getBounds()
    {
        return new Rectangle(edge, y, 43, 39);
    }

    public void move()
    {
        y = y + dy;
        if(y < ceiling)
        {
            y = ceiling;
        }

        if(y > 290)
        {
            y = 290;
        }

        if(dx != -1)
        {
            if(edge + dx <= 151)
            {
                edge = edge + dx;
            }
            else
            {
                x = x + dx;
                nx2 = nx2 + dx;
                nx = nx + dx;
            }
        }
        else
            {
            if(edge + dx > 0)
            {
                edge = edge + dx;
            }
        }   

    }

    public int getX()
    {
        return x;
    }

    public int getdx()
    {
        return dx;
    }

    public int getY()
    {
        return y;
    }

    public Image getImage()
    {
        return player;
    }

    public void keyPressed(KeyEvent e)
    {
        int key = e.getKeyCode();

        if(key == KeyEvent.VK_RIGHT)
        {
            dx = 2;
            player = f.getImage();
        }
        if(key == KeyEvent.VK_UP)
        {
            dy = -1;
            player = up.getImage();
        }
        if(key == KeyEvent.VK_DOWN)
        {
            dy = 1;
            player = down.getImage();
        }
        if(key == KeyEvent.VK_SPACE)
        {
            fire();
            laser.play();
        }
    }

    public void keyReleased(KeyEvent e)
    {
        int key = e.getKeyCode();

        if(key == KeyEvent.VK_RIGHT)
        {
            dx = 1;
            player = ib.getImage();
        }

        if(key == KeyEvent.VK_UP)
        {
            dy = 0;
            player = ib.getImage();
        }

        if(key == KeyEvent.VK_DOWN)
        {
            dy = 0;
            player = ib.getImage();
        }
    }
}

框架

package ShooterGame;

import javax.swing.*;

public class Frame 
{
    public AudioClip theme;

        public Frame()
        {
                JFrame frame = new JFrame();
                frame.add(new Board());
                frame.setTitle("SideShooter");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(700,365);
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);

        }

        public static void main(String[] args)
        {
                new Frame();

        }
}
4

2 回答 2

0

好的,所以问题出在另一个答案中提到的那一行,但我相信所有的敌人在检查碰撞之前可能都没有被初始化。因为您从一开始就制作了 10000 个,所以我认为您执行的操作方法可能是在创建碰撞之前检查碰撞。

要尝试的一件事可能是减少敌人的数量,看看它是否仍然继续发生,尝试 100 或 1000,但这仍然无法解决问题。

不过,您确实希望将游戏更改为在自己的循环中运行,目前您仅在玩家执行操作时检查碰撞。所以如果玩家停止移动,没有碰撞检测......

我建议你找一本名为“Killer Game Programming in Java”的书,有免费的电子书版本,只需阅读关于制作游戏循环的前两章。书有点老了,但是循环的基础知识非常好。

这里的这个问题还包含一个非常简单的循环,以及评论中关于如何使其变得更好的一些建议。

于 2012-05-07T01:13:40.473 回答
0

错误在线

rect[i] = e.getBounds();

你没有Enemy正确初始化你的类的边界吗?或者,您从阵列中拉出的敌人可能为空。

于 2012-05-07T00:32:41.273 回答