使用JavaAWT实现简易版飞机大战

@飞机大战总结
飞机大战

JavaAWT实现“飞机大战”

具体实现效果图:
实现效果图

主要需要的类:(解释取自Java JDK 中文文档.)

1.Frame -java.awt.Frame 是带有标题和边框 的顶层窗口
2.Graphics-java.awt.Graphics是所有图形上下文的抽象基类,允许应用程序在组件以及闭屏图像上进行绘制,通俗的说,就是Graphics类提供一个画笔
4.Image-java.awt.Image 是以特定平台的方式获取图形
5.BufferedImage-java.awt.image.BufferedImage 是Image的子类,描述具有可访问图像数据缓冲区的Image
6.ImageIO-javax.imageio.ImageIO 该类包含一些用来查找 ImageReader 和 ImageWriter 以及执行简单编码和解码的静态便捷方法
7.WindowAdapter-java.awt.event.WindowAdapter 是抽象类,此类中的方法为空,此类存在的目的是方便创建侦听器对象
8.WindowEvent-java.awt.event.WindowEvent 是窗口状态改变的低级别事件,比如打开,关闭,激活,停用等
9.KeyAdapter-java.awt.event.KeyAdapter 抽象类,目的是方便创建侦听键盘对象,KeyAdapter 对象实现 KeyListener 接口
10.KeyEvent-java.awt.event.KeyEvent 表示组件中发生键击的事件,当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener 方法注册,以接收此类事件,发生事件时,所有此类侦听器对象都将获得此 KeyEvent
11.URL-java.net.URL 代表一个统一资源定位符,它是指向互联网“资源”的指针,资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,比如对数据库或者搜索引擎的查询
12.IOException-java.io.IOException 当发生某种 I/O 异常时,抛出此异常
13.Thread -java.lang.Thread 线程 是程序中的执行线程,Java 虚拟机允许应用程序并发地运行多个执行线程

代码实现

模拟飞机大战,首先我们需要两个类,飞机类plane子弹类Bullet,封装了各自对象的属性和方法 ,分析飞机属性方法,向上延伸出一个父类PictureBase,以便于创建不同的飞机。常量类Constant来存放游戏的数据,便于代码管理,工具类GameTools在本项目中存放调取图片的方法,爆炸类Blast,显示当飞机和子弹碰撞的时候。主界面MyPlaneWarFrame

代码关系

1.父类PictureBase

public class PictureBase
{
    Image img;//图片

    int x,y,wide,high;//图片的起始位置,宽高

    int speed;//物体速度

    public PictureBase(){}//构造器初始化

    public PictureBase(int x, int y, int wide, int high, int speed,Image img)//飞机
    {
        this.x = x;
        this.y = y;
        this.wide = wide;
        this.high = high;
        this.speed = speed;
        this.img=img;
    }
   //有绘画功能,传入参数理解为传入了一个画笔
    public void paintMyself(Graphics g)
    {
        g.drawImage(img,x,y,wide,high,null);
    }

    //所有的物体都是矩形,当你获得对应的矩形的时候,我们就可以做一些相关的判断的操作
    public Rectangle getRec()
    {
        return new Rectangle((int)x,(int)y,wide,high);
    }
}

2.飞机类Plane

作为一个飞机首先得有个形状,这里用一张图片实现,设置它的长宽,起始坐标,飞机要上下左右移动,其实就是操作它的坐标,用布尔值判断飞机飞向哪个方向,然后对坐标值进行增减,以及布尔值判断飞机生死

飞机类所要实现的方法,第一,需要在我们的窗口将它自己展现出来;第二,它移动时对坐标相应的操作;第三,我们需要实现的效果是按下键盘的上下左右键,飞机对应的上下左右移动,松开键盘,飞机就停止移动;第四,为了判断飞机的生死需要返回可容纳飞机的最小矩形,这里就是容纳飞机的最小矩形如果和子弹最小矩形有相交,则飞机死亡

飞机继承自父类的属性:长宽,起始坐标,速度,图片
飞机继承自父类的方法:getRec();

飞机独特的属性有:1.是否存活 2.飞行方向,
飞机的独特方法是:1.通过键入上下左右,可以改变飞机方向的boolean值, 2.飞机具有独特的飞行方法(复写drawMyself方法)。

public class Plane extends PictureBase
{

    boolean live=true;//飞机是否活着

    boolean up, down, left , right;//飞机飞行方向

    public Plane(int x,int y,int wide,int high,int speed,Image img)
    {
        super(x,y,wide,high,speed,img);
    }

    public void drawMyself(Graphics e)
    {
        if(live)
        {
            super.paintMyself(e);
            if (left)
                x -= speed;
            if (right)
                x += speed;
            if (up)
                y -= speed;
            if (down)
                y += speed;
        }

    }

    public void addDistance(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
            case KeyEvent.VK_UP:
                up=true;
                break;
            case KeyEvent.VK_DOWN:
                down=true;
                break;
            case KeyEvent.VK_RIGHT:
                right=true;
                break;
            case KeyEvent.VK_LEFT:
                left=true;
        }
    }

    public void reduceDistance(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
            case KeyEvent.VK_UP:
                up=false;
                break;
            case KeyEvent.VK_DOWN:
                down=false;
                break;
            case KeyEvent.VK_RIGHT:
                right=false;
                break;
            case KeyEvent.VK_LEFT:
                left=false;
        }
    }
}

3.子弹类Bullet

类似于飞机类,子弹类也需要坐标控制它的飞行,子弹大小,由于子弹是无规则的在窗口随意运动,所以需要设置子弹的角度,子弹类要实现的方法比较简单,第一,画无规则从窗口中心散出的子弹;第二,返回最小矩形

子弹继承自父类的属性:长宽,起始坐标,速度,图片
子弹继承自父类的方法:无

子弹独特的属性有:方向
子弹的独特方法是:复写drawMyself方法

public class Bullet extends PictureBase
{
    double degree;//炮弹具有角度

    public Bullet()
    {
        x=200;
        y=200;

        wide=5;
        high=5;

        degree=Math.random()*Math.PI*2;//返回0~1中的随机数

        speed=10;

    }

    public void drawMyself(Graphics e)
    {
        Color c=e.getColor();

        e.setColor(Color.yellow);

        e.fillOval(x,y,wide,high);

        e.setColor(c);

        x+=speed*Math.cos(degree);
        y+=speed*Math.sin(degree);

        if(y>Constant.Game_HEIGHT-this.high||y<40)
        {
            degree=-degree;
        }
        if(x> Constant.Game_Windth-this.wide||x<0)
        {
            degree=Math.PI-degree;
        }
    }
}

4.常量类

封装了一些常量,便于修改,在飞机类和子弹类中也使用了该类

public class Constant
{
    //游戏窗口的宽度
    public static final int Game_Windth=500;
    //游戏窗口的高度
    public static final int Game_HEIGHT=500;

}

5.工具类

该工具类只封装了加载图片这个方法,为便于调用方法设置为静态

public class GameTools
{
    //构造器私有化,防止别人创建本类对象
    private GameTools(){}
    public static Image getImage(String path)
    {
        BufferedImage img=null;
        URL u=GameTools.class.getClassLoader().getResource(path);
        try
        {
            img= ImageIO.read(u);
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        return img;
    }
}

6.爆炸类

爆炸也需要爆炸地点即坐标,用一系列图片来实现爆炸,所以也需要设置图片的长度和宽度,以及存放这些图片的数组,使用static数组存放图片图片,使用静态代码块初始化,还需要设置一个int变量来计数,确保你一系类图片加载结束以后就不再爆炸,不会炸个没完没了

也要有一个drawMyself的方法,将爆炸的图片“画”到主界面上

public class Blast
{
    double x,y;//爆炸的坐标,爆炸物的宽高

    Blast(){}

    Blast(double x,double y)
    {
        this.x=x;
        this.y=y;
    }

    static Image[]blast=new Image[16];
    int count=1;
    static
    {
        for(int i=0;i<16;i++)
        {
            blast[i]=GameTools.getImage("photo/blastPhoto/e"+(i+1)+".gif");
        }
    }

    public void drawMyself(Graphics e)
    {
        if(count<16)
        {
           e.drawImage(blast[count++],(int)x,(int)y,null);
        }
    }
}

到这一步,准备工作就做完了,接下来就要把创建窗口类来实现这个游戏,窗口类需要继承Frame类,这里多加了一部,把经常使用的关于窗口的方法包装成一个独立的MyFrame类,它继承Frame类,然后让游戏窗口类直接继承MyFrame类

7.游戏主界面类

首先要创建游戏的界面

1.Frame类
a.窗口的加载,那么就得先聊聊Frame类

Frame
Frame 是带有标题和边框的顶层窗口。窗体的默认布局为 BorderLayout,

Window 对象是一个没有边界和菜单栏的顶层窗口,Windows类提供了方法来设置窗口的大小,位置等信息
在我们加载这个窗口的时候就需要设置这些值,设置好以后就可以运行出一个空白的带框窗口了

		this.setTitle("飞机大战");
        this.setBounds(100,100,500,500);//界面的初始化位置,宽高
        this.setVisible(true);
b.定义一个内部线程类,因为我们的飞机和子弹都是时刻在运动的,所以就需要不断的创建新的线程,使飞机和子弹动起来

原理通俗来讲:就是将一帧一帧的图片通过不断的刷新界面,从而拼接成一个完整的动画,而刷新就是通过创建一个线程去刷新。通过线程中的while循环,不断的调用repaint方法

class myThread extends Thread
    {
        public void run()
        {
            while(true)
            {
                repaint();//内部类可以直接调用外部类的成员。
                try {
                    Thread.sleep(50);   //1s=1000ms,1s画20次(20*50=1000),一秒画20次
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
repaint方法

repaint
repaint会尽快的去调用paint方法

c…AWT存在闪烁问题,这里使用双缓冲技术消除闪烁,在spring中无需设置,会自动消除闪烁
/**
     * 解决屏幕闪烁问题,增加双缓冲技术*/
    private Image offScreenImage=null;
    public void update(Graphics g)
    {
        if(offScreenImage==null)
            offScreenImage=this.createImage(Constant.Game_Windth, Constant.Game_HEIGHT);//游戏窗口的宽高

        Graphics gOff=offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage,0,0,null);
    }

2.游戏主界面类

往窗口里画东西,飞机,子弹,右上角的计时器
画飞机的首要条件就是飞机还是存活的,直接调用飞机对象的draw方法,
画子弹的时候,因为子弹数目比较多,所以这里需要用到集合的知识,把子弹放在一个List中(这里没有使用泛型,一般建议使用),每创建一个子弹,都要检测它是否与飞机碰撞,若是,则飞机死亡爆炸
画计时器,通过Date类不断创建新的时间对象,startTime在上文中加载窗口方法中就已经计算出确切的时间值了
游戏结束时,显示游戏时间以及Gameover,GameOver比较简单,就是在窗口固定坐标输出一行字

a.创建构造方法,通过建立对象自动调用构造方法启动窗口事件。
 public void MyPlaneWraFrame()
    {
        init();//启动窗口事件
    }
b.创建窗口事件

添加关闭窗口事件,启动键盘监听,创建炮弹。启动重画线程(只要创建了对象,重画线程就开始被调用–>paint方法就开始被调用。)

//窗口事件
    public void init()
    {
        this.setTitle("飞机大战");
        this.setBounds(100,100,500,500);//界面的初始化位置,高宽
        this.setLayout(new FlowLayout());

        this.addWindowListener(new WindowAdapter()//关闭窗口事件
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });


        new myThread().start();//启动重画线程
        this.addKeyListener(new keymonitor());//启动键盘监听

        //创建炮弹
        for(int i=0;i<BulletNum;i++)
        {
            Bullet bullet=new Bullet();
            al.add(bullet);
        }

        this.setVisible(true);

    }
c.给界面中“画”背景,飞机,炮弹,
public void paint(Graphics g)
    {
        g.drawImage(bgImg,0,0,500,500,null);//画背景
        p1.drawMyself(g);//画飞机

        System.out.println("容器目前的大小:"+al.size());

        drawTime(g);//画时间

        for(int i=0;i<BulletNum;i++)//画炮弹
        {

           Bullet b=(Bullet)al.get(i);
           b.drawMyself(g);

           //碰撞测试
           boolean boom=b.getRec().intersects(p1.getRec());
           if(boom)
           {
               GameOver=true;
               button();

               p1.live=false;
               if(blast==null)
               {
                   blast=new Blast(p1.x,p1.y);
               }
               blast.drawMyself(g);
           }
       }


    }
d.给界面中添加计时功能
public void drawTime(Graphics g)
    {
        Color c=g.getColor();
        Font f=g.getFont();

        g.setColor(Color.green);

        if(p1.live)
        {

            period=(System.currentTimeMillis()-start.getTime())/1000;
            g.drawString("坚持:"+period,30,50);
        }
        else
        {


            if(end==null)
            {
                end=new Date();
                period=(end.getTime()-start.getTime())/1000;
            }

            g.setColor(Color.ORANGE);

            g.setFont(new Font("微软雅黑",Font.BOLD,30));  //设置字体
            g.drawString("最终时间为:"+period+"s",150,150);

            g.setFont(new Font("微软雅黑",Font.BOLD,60));  //设置字体
            g.drawString("GameOver",90,250);


        }

        g.setColor(c);
        g.setFont(f);
    }
e.创建内部类,监听键盘
//监听键盘
    class keymonitor extends KeyAdapter
    {
        @Override
        public void keyPressed(KeyEvent e)
        {
            p1.addDistance(e);
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            p1.reduceDistance(e);
        }
    }
f.如果飞机坠毁,重新开始游戏
public void button()//如果飞机坠毁,那么启动按钮
    {
        if(GameOver)
        {
            if(button==null)
            {
                button = new Button("PlayNewGame");
                this.add(button);
                button.setBackground(Color.RED);
                button.setForeground(Color.orange);
                init();

                //创建按钮监听
                button.addMouseListener(new MouseAdapter()
                {
                    @Override
                    public void mouseClicked(MouseEvent e)
                    {
                        if(e.getClickCount()==2)
                        {
                            MyPlaneWarFrame myPlaneWarFrame= new MyPlaneWarFrame();
                            myPlaneWarFrame.MyPlaneWraFrame();

                        }
                    }
                });
            }
        }
    }

以上就是所有的分析代码,下面是整个界面类的完整代码

public class MyPlaneWarFrame extends Frame
{
    Image planeImg=GameTools.getImage("photo/planePhoto/plane.png");
    Image bgImg=GameTools.getImage("photo/planePhoto/bg.jpg");


    Plane p1=new Plane(400,400,20,20,6,planeImg);

    Blast blast;//创建爆炸对象

    Date start=new Date();//游戏开始的时间
    Date end;//游戏结束的时间
    long period=0;//玩了多久

    int BulletNum=10;
    ArrayList<Bullet>al=new ArrayList<Bullet>(BulletNum);

    private Button button;

    boolean GameOver=false;

    public void MyPlaneWraFrame()
    {
        init();
    }

    //窗口事件
    public void init()
    {
        this.setTitle("飞机大战");
        this.setBounds(100,100,500,500);//界面的初始化位置,高宽
        this.setLayout(new FlowLayout());

        this.addWindowListener(new WindowAdapter()//关闭窗口事件
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });


        new myThread().start();//启动重画线程
        this.addKeyListener(new keymonitor());//启动键盘监听

        //创建炮弹
        for(int i=0;i<BulletNum;i++)
        {
            Bullet bullet=new Bullet();
            al.add(bullet);
        }

        this.setVisible(true);

    }
    public void button()//如果飞机坠毁,那么启动按钮
    {
        if(GameOver)
        {
            if(button==null)
            {
                button = new Button("PlayNewGame");
                this.add(button);
                button.setBackground(Color.RED);
                button.setForeground(Color.orange);
                init();

                //创建按钮监听
                button.addMouseListener(new MouseAdapter()
                {
                    @Override
                    public void mouseClicked(MouseEvent e)
                    {
                        if(e.getClickCount()==2)
                        {
                            MyPlaneWarFrame myPlaneWarFrame= new MyPlaneWarFrame();
                            myPlaneWarFrame.MyPlaneWraFrame();

                        }
                    }
                });
            }
        }
    }

    public void paint(Graphics g)
    {
        g.drawImage(bgImg,0,0,500,500,null);//画背景
        p1.drawMyself(g);//画飞机

        System.out.println("容器目前的大小:"+al.size());

        drawTime(g);//画时间

        for(int i=0;i<BulletNum;i++)//画炮弹
        {

           Bullet b=(Bullet)al.get(i);
           b.drawMyself(g);

           //碰撞测试
           boolean boom=b.getRec().intersects(p1.getRec());
           if(boom)
           {
               GameOver=true;
               button();

               p1.live=false;
               if(blast==null)
               {
                   blast=new Blast(p1.x,p1.y);
               }
               blast.drawMyself(g);
           }
       }


    }

    public void drawTime(Graphics g)
    {
        Color c=g.getColor();
        Font f=g.getFont();

        g.setColor(Color.green);

        if(p1.live)
        {

            period=(System.currentTimeMillis()-start.getTime())/1000;
            g.drawString("坚持:"+period,30,50);
        }
        else
        {


            if(end==null)
            {
                end=new Date();
                period=(end.getTime()-start.getTime())/1000;
            }

            g.setColor(Color.ORANGE);

            g.setFont(new Font("微软雅黑",Font.BOLD,30));  //设置字体
            g.drawString("最终时间为:"+period+"s",150,150);

            g.setFont(new Font("微软雅黑",Font.BOLD,60));  //设置字体
            g.drawString("GameOver",90,250);


        }

        g.setColor(c);
        g.setFont(f);
    }

    class myThread extends Thread
    {
        public void run()
        {
            while(true)
            {
                repaint();//内部类可以直接调用外部类的成员。
                try {
                    Thread.sleep(50);   //1s=1000ms,1s画20次(20*50=1000),一秒画20次
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 解决屏幕闪烁问题,增加双缓冲技术*/
    private Image offScreenImage=null;
    public void update(Graphics g)
    {
        if(offScreenImage==null)
            offScreenImage=this.createImage(Constant.Game_Windth, Constant.Game_HEIGHT);//游戏窗口的宽高

        Graphics gOff=offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage,0,0,null);
    }

    //监听键盘
    class keymonitor extends KeyAdapter
    {
        @Override
        public void keyPressed(KeyEvent e)
        {
            p1.addDistance(e);
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            p1.reduceDistance(e);
        }
    }


    public static void main(String[] args)
    {
       MyPlaneWarFrame myPlaneWarFrame= new MyPlaneWarFrame();
       myPlaneWarFrame.MyPlaneWraFrame();
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
飞机大战是一款经典的游戏,下面我介绍一下使用Java实现飞机大战的基本思路: 1. 创建游戏窗口 使用Java中的JFrame类创建一个游戏窗口,设置窗口大小、标题、背景色等属性。 2. 加载游戏资源 使用Java中的Image类加载游戏所需的图片资源,包括背景图、飞机图、子弹图、敌机图等。 3. 创建游戏角色 创建游戏角色,包括玩家飞机、敌机、子弹等,使用Java中的JPanel类将它们添加到游戏窗口中。 4. 添加游戏事件 为游戏角色添加事件,包括玩家飞机的移动、子弹的发射、敌机的生成等。 5. 实现游戏逻辑 实现游戏的逻辑,包括碰撞检测、得分计算、游戏结束判断等。 6. 实现游戏界面 使用Java中的Graphics类绘制游戏界面,包括背景图、游戏角色、得分、生命等信息。 7. 运行游戏 将游戏窗口设置为可见状态,启动游戏。 上述是Java实现飞机大战的基本思路,具体实现可以参考以下示例代码: ```java import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; import java.util.Random; public class PlaneGame extends JFrame { private static final int WIDTH = 500; private static final int HEIGHT = 700; private final Image background = new ImageIcon("resources/background.jpg").getImage(); private final Image airplane = new ImageIcon("resources/airplane.png").getImage(); private final Image bullet = new ImageIcon("resources/bullet.png").getImage(); private final Image enemyAirplane = new ImageIcon("resources/enemy_airplane.png").getImage(); private final List<Bullet> bullets = new ArrayList<>(); private final List<EnemyAirplane> enemyAirplanes = new ArrayList<>(); private int score = 0; private int life = 3; private final Random random = new Random(); private int playerX = WIDTH / 2 - airplane.getWidth(null) / 2; private int playerY = HEIGHT - airplane.getHeight(null) - 50; private boolean isMovingLeft = false; private boolean isMovingRight = false; private boolean isFiring = false; public PlaneGame() { setSize(WIDTH, HEIGHT); setTitle("Plane Game"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: isMovingLeft = true; break; case KeyEvent.VK_RIGHT: isMovingRight = true; break; case KeyEvent.VK_SPACE: isFiring = true; break; } } @Override public void keyReleased(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: isMovingLeft = false; break; case KeyEvent.VK_RIGHT: isMovingRight = false; break; case KeyEvent.VK_SPACE: isFiring = false; break; } } @Override public void keyTyped(KeyEvent e) { } }); setVisible(true); } @Override public void paint(Graphics g) { g.drawImage(background, 0, 0, null); g.drawImage(airplane, playerX, playerY, null); for (Bullet bullet : bullets) { g.drawImage(this.bullet, bullet.getX(), bullet.getY(), null); } for (EnemyAirplane enemyAirplane : enemyAirplanes) { g.drawImage(this.enemyAirplane, enemyAirplane.getX(), enemyAirplane.getY(), null); } g.setColor(Color.WHITE); g.setFont(new Font("Arial", Font.BOLD, 20)); g.drawString("Score: " + score, 20, 30); g.drawString("Life: " + life, WIDTH - 100, 30); } public void start() { while (life > 0) { if (isMovingLeft) { playerX -= 5; } if (isMovingRight) { playerX += 5; } if (isFiring) { bullets.add(new Bullet(playerX + airplane.getWidth(null) / 2, playerY)); } for (Bullet bullet : bullets) { bullet.move(); } for (EnemyAirplane enemyAirplane : enemyAirplanes) { enemyAirplane.move(); } if (random.nextInt(100) < 10) { enemyAirplanes.add(new EnemyAirplane(random.nextInt(WIDTH - enemyAirplane.getWidth(null)), -enemyAirplane.getHeight(null))); } for (Bullet bullet : bullets) { for (EnemyAirplane enemyAirplane : enemyAirplanes) { if (bullet.isCollidedWith(enemyAirplane)) { score++; bullets.remove(bullet); enemyAirplanes.remove(enemyAirplane); break; } } } for (EnemyAirplane enemyAirplane : enemyAirplanes) { if (enemyAirplane.isCollidedWith(playerX, playerY, airplane.getWidth(null), airplane.getHeight(null))) { life--; enemyAirplanes.remove(enemyAirplane); break; } } repaint(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } JOptionPane.showMessageDialog(this, "Game Over!\nScore: " + score); System.exit(0); } private static class Bullet { private static final int SPEED = 10; private final int x; private int y; public Bullet(int x, int y) { this.x = x; this.y = y; } public void move() { y -= SPEED; if (y < -bullet.getHeight(null)) { bullets.remove(this); } } public int getX() { return x; } public int getY() { return y; } public boolean isCollidedWith(EnemyAirplane enemyAirplane) { int bulletX = getX() + bullet.getWidth(null) / 2; int bulletY = getY() + bullet.getHeight(null) / 2; int enemyAirplaneX = enemyAirplane.getX() + enemyAirplane.getWidth(null) / 2; int enemyAirplaneY = enemyAirplane.getY() + enemyAirplane.getHeight(null) / 2; int distance = (int) Math.sqrt(Math.pow(bulletX - enemyAirplaneX, 2) + Math.pow(bulletY - enemyAirplaneY, 2)); return distance < bullet.getWidth(null) / 2 + enemyAirplane.getWidth(null) / 2; } } private static class EnemyAirplane { private static final int SPEED = 5; private final int x; private int y; public EnemyAirplane(int x, int y) { this.x = x; this.y = y; } public void move() { y += SPEED; if (y > HEIGHT) { enemyAirplanes.remove(this); } } public int getX() { return x; } public int getY() { return y; } public boolean isCollidedWith(int x, int y, int width, int height) { int enemyAirplaneX = getX() + enemyAirplane.getWidth(null) / 2; int enemyAirplaneY = getY() + enemyAirplane.getHeight(null) / 2; int distance = (int) Math.sqrt(Math.pow(enemyAirplaneX - x - width / 2, 2) + Math.pow(enemyAirplaneY - y - height / 2, 2)); return distance < enemyAirplane.getWidth(null) / 2 + width / 2; } } public static void main(String[] args) { new PlaneGame().start(); } } ``` 上述代码实现了基本的飞机大战游戏,包括玩家飞机的移动、子弹的发射、敌机的生成、碰撞检测、得分计算、游戏结束等功能。可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小张develop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值