Java小游戏——飞机大战

这是一个适合新手的Java游戏编程练习项目,通过B站教程047【飞机大战】,实现了一款简单的飞机大战游戏。游戏包含背景、我方战机、敌机、子弹、爆炸效果等元素,涉及图形绘制、碰撞检测、事件处理等核心概念。虽然存在窗口大小可调、游戏状态冲突等问题,但整体上为初学者提供了良好的实践平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本程序是跟着尚学堂敲的,非常适合新手拿来练手。B站学习链接:047【飞机大战】_介绍视频_哔哩哔哩_bilibili​​​​​​

 主类GameWin,是游戏运行的主面板(该类继承JFrame):

package Bao;

import Bao.obj.*;
import Bao.utils.GameUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GameWin extends JFrame {

//游戏状态 0未开始 1游戏中 2暂停 3通关失败 4通关成功
    public static int state=0;
    //    游戏得分
    public static int score=0;
//    双缓存的图片
    Image offScreenImage=null;
    int width=600,height=600;
//  游戏的重绘次数
    int count=1;
//    敌机出现的数量
    int enemyCount=0;


//    背景图对象
    BgObj bgObj=new BgObj(GameUtils.bgImg,0,-2000,2);
//    我方战机对象
    public PlaneObj planeObj=new PlaneObj(GameUtils.planeImg,290,550,20,30,0,this);
//  敌方boss对象
    public BossObj bossObj=null;
    public void launch(){
        //设置窗口是否可见
        this.setVisible(true);
        //设置窗口大小
        this.setSize(width,height);
        //设置窗口位置
        this.setLocationRelativeTo(null);
        //设置窗口标题
        this.setTitle("飞机大战");
        GameUtils.gameObjList.add(bgObj);
        GameUtils.gameObjList.add(planeObj);

//       游戏的点击启动事件
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton()==1&&state==0){
                    state=1;
                    repaint();
                }
            }
        });
//        暂停
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode()==32){
                    switch (state){
                        case 1:
                            state=2;break;
                        case 2:
                            state=1;break;
                        default:
                    }
                }
            }
        });
//        重复绘制
        while (true){
            if (state==1){
                createObj();
                repaint();
            }

            try {
                Thread.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g) {
        if (offScreenImage==null){
            offScreenImage=createImage(600,600);
        }
        Graphics gImage=offScreenImage.getGraphics();
        gImage.fillRect(0,0,width,height);
        if (state==0){
//            未开始
            gImage.drawImage(GameUtils.bgImg,0,0,null);
            gImage.drawImage(GameUtils.bossImg,220,120,null);
            gImage.drawImage(GameUtils.explodeImg,270,350,null);
            GameUtils.drawWord(gImage,"点击开始游戏",Color.yellow,40,180,300);

        }
        if (state==1){
            GameUtils.gameObjList.addAll(GameUtils.explodeObjList);
//         运行中
            for (int i = 0; i < GameUtils.gameObjList.size(); i++) {
                GameUtils.gameObjList.get(i).paintSelf(gImage);
            }
            GameUtils.gameObjList.remove(GameUtils.removeList);
        }
        if (state==3){
//          失败
            gImage.drawImage(GameUtils.explodeImg,planeObj.getX()-35,planeObj.getY()-50,null);
            GameUtils.drawWord(gImage,"Game Over",Color.RED,50,180,300);

        }
        if (state==4){
//          通关
            gImage.drawImage(GameUtils.explodeImg,bossObj.getX()+30,bossObj.getY(),null);
            GameUtils.drawWord(gImage,"You win!!!",Color.RED,50,190,300);


        }
        GameUtils.drawWord(gImage,score+"分",Color.green,40,30,100);
        g.drawImage(offScreenImage,0,0,null);
        count++;

    }
    void createObj() {
        //   我方子弹
        if (count % 10 == 0){
            GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg, planeObj.getX() + 3, planeObj.getY() - 16, 14, 29, 5, this));
        GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size() - 1));
    }
//        敌方飞机
        if (count % 30 == 0){
            GameUtils.enemyObjList.add(new EnemyObj(GameUtils.enemyImg,(int)(Math.random()*12)*50,0,49,39,5,this));
            GameUtils.gameObjList.add(GameUtils.enemyObjList.get(GameUtils.enemyObjList.size()-1));
            enemyCount++;

        }
//        敌方子弹
        if (count % 15== 0&&bossObj!=null){
            GameUtils.bulletObjList.add(new BulletObj(GameUtils.bulletImg,bossObj.getX()+76,bossObj.getY()+85,15,25,5,this));
          GameUtils.gameObjList.add(GameUtils.bulletObjList.get(GameUtils.bulletObjList.size()-1));
        }
        if (enemyCount>20&&bossObj==null){
           bossObj=new BossObj(GameUtils.bossImg,250,35,155,100,5,this);
            GameUtils.gameObjList.add(bossObj);
        }
    }
    public static void main(String[] args) {
        GameWin gameWin=new GameWin();
        gameWin.launch();
    }

}

 类GameUtills,是本程序的工具类

package Bao.utils;

import Bao.obj.*;

import java.awt.*;
import java.util.*;
import java.util.List;

public class GameUtils {
//    背景图片
    public static Image bgImg=Toolkit.getDefaultToolkit().getImage("imgs/bg.jpg");
    //    boss图片
    public static Image bossImg=Toolkit.getDefaultToolkit().getImage("imgs/boss.png");
    //    爆炸图片
    public static Image explodeImg=Toolkit.getDefaultToolkit().getImage("imgs/explode/e6.gif");
    //  我方战机图片
    public static Image planeImg=Toolkit.getDefaultToolkit().getImage("imgs/plane.png");
    //  我方子弹图片
    public static Image shellImg=Toolkit.getDefaultToolkit().getImage("imgs/bulletGreen.png");
    //  敌方子弹图片
    public static Image bulletImg=Toolkit.getDefaultToolkit().getImage("imgs/bulletYellow.png");
    //  敌方战机图片
    public static Image enemyImg=Toolkit.getDefaultToolkit().getImage("imgs/enemy.png");
    //    所有游戏物体的集合
    public static List<GameObj> gameObjList=new ArrayList<>();
//    要删除的元素集合
    public static List<GameObj> removeList=new ArrayList<>();
//    我方子弹的集合
    public static List<ShellObj> shellObjList=new ArrayList<>();
    //    敌方子弹的集合
    public static List<BulletObj> bulletObjList=new ArrayList<>();
    //    敌机的集合
    public static List<EnemyObj> enemyObjList=new ArrayList<>();
    //    爆炸的集合
    public static List<ExplodeObj> explodeObjList=new ArrayList<>();
//    绘制字符串的工具类
    public static void drawWord(Graphics gImage,String str,Color color,int size,int x,int y){
    gImage.setColor(color);
    gImage.setFont(new Font("仿宋",Font.BOLD,size));
    gImage.drawString(str,x,y);

}

}

 类BgObj,用来制作背景

package Bao.obj;

import java.awt.*;

public class BgObj extends GameObj{
    public BgObj() {
        super();
    }

    public BgObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        y+=speed;
        if (y>0){
            y=-2000;
        }
    }
}

 类BossObj,用来定义敌方boss

package Bao.obj;

import Bao.GameWin;
import Bao.utils.GameUtils;

import java.awt.*;

public class BossObj extends GameObj {
    int life=50;
    public BossObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        if (x>550||x<-50){
            speed=-speed;
        }
        x+=speed;
        for (ShellObj shellObj: GameUtils.shellObjList){
            if (this.getRec().intersects(shellObj.getRec())){
                shellObj.setX(-100);
                shellObj.setY(100);
                GameUtils.removeList.add(shellObj);
                life--;
            }
            if (life<=0){
                GameWin.state=4;
            }
        }
//        血条的白色背景
        gImage.setColor(Color.white);
        gImage.fillRect(20,40,100,10);
//        血条的绘制
        gImage.setColor(Color.red);
        gImage.fillRect(20,40,life*10,10);
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

 类BulletObj,用来定义敌方子弹

package Bao.obj;

import Bao.GameWin;
import Bao.utils.GameUtils;

import java.awt.*;

public class BulletObj extends GameObj{
    public BulletObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        y+=speed;
//        敌方子弹与我方战机的碰撞检测
        if (this.getRec().intersects(this.frame.planeObj.getRec())){
            GameWin.state=3;
        }
//        敌方子弹越界消失
        if (y<0){
            this.x=-300;
            this.y=300;
            GameUtils.removeList.add(this);
        }

    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

类EnemyObj,用来定义敌方小型战机 

package Bao.obj;

import Bao.GameWin;
import Bao.utils.GameUtils;

import java.awt.*;

public class EnemyObj extends GameObj{
    public EnemyObj() {
        super();
    }

    public EnemyObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        y+=speed;
//        敌我飞机碰撞检测
        if (this.getRec().intersects(this.frame.planeObj.getRec())){
            GameWin.state=3;

        }
//        敌机越界消失
        if (y>600){
            this.x=-200;
            this.y=200;
            GameUtils.removeList.add(this);
        }
//      敌机与我方子弹消失前移动
        for (ShellObj shellObj: GameUtils.shellObjList) {
            if (this.getRec().intersects(shellObj.getRec())){
                ExplodeObj explodeObj=new ExplodeObj(x,y);
                GameUtils.explodeObjList.add(explodeObj);
                GameUtils.removeList.add(explodeObj);
                shellObj.setX(-100);
                shellObj.setY(100);
                this.x=-200;
                this.y=200;
                GameUtils.removeList.add(shellObj);
                GameUtils.removeList.add(this);
                GameWin.score++;
            }
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

 类ExplodeObj,用来制作爆炸时的特效

package Bao.obj;

import java.awt.*;

public class ExplodeObj extends GameObj{
    static Image[]pic=new Image[16];
    int explodeCount=0;

    static {
        for (int i = 0; i < pic.length; i++) {
            pic[i]=Toolkit.getDefaultToolkit().getImage("imgs/explode/e"+(i+1)+".gif");
        }
    }

    public ExplodeObj(int x, int y) {
        super(x, y);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        if (explodeCount<16){
            img=pic[explodeCount];
            super.paintSelf(gImage);
            explodeCount++;
        }
    }
}

 GameObj,同样也是个工具类

package Bao.obj;

import Bao.GameWin;

import java.awt.*;

public class GameObj{
    Image img;
    int x,y,width,height;
    double speed;
    GameWin frame;

    public Image getImg() {
        return img;
    }

    public void setImg(Image img) {
        this.img = img;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public GameWin getFrame() {
        return frame;
    }

    public void setFrame(GameWin frame) {
        this.frame = frame;
    }

    public GameObj() {
    }

    public GameObj(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public GameObj(Image img, int x, int y, double speed) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.speed = speed;
    }

    public GameObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.speed = speed;
        this.frame = frame;
    }
    public void paintSelf(Graphics gImage){
        gImage.drawImage(img,x,y,null);
    }
    public Rectangle getRec(){
        return new Rectangle(x,y,width,height);
    }
}

 类PlaneObj,定义我方战机

package Bao.obj;

import Bao.GameWin;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class PlaneObj extends GameObj{
    @Override
    public Image getImg() {
        return super.getImg();
    }

    public PlaneObj() {
        super();
    }

    public PlaneObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
        this.frame.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                PlaneObj.super.x=e.getX()-11;
                PlaneObj.super.y=e.getY()-16;
            }
        });
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
//        我方战机与敌方boss的碰撞检测
        if (this.frame.bossObj!=null&&this.getRec().intersects(this.frame.bossObj.getRec())){
            GameWin.state=3;
        }

    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

 类ShellObj用来定义我方子弹

package Bao.obj;

import Bao.GameWin;
import Bao.utils.GameUtils;

import java.awt.*;

public class ShellObj extends GameObj {
    @Override
    public Image getImg() {
        return super.getImg();
    }

    public ShellObj() {
        super();
    }

    public ShellObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        y-=speed;
//        我方子弹越界消失
        if (y<0){
            this.x=-100;
            this.y=100;
            GameUtils.removeList.add(this);
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

以上便是飞机大战的程序了,虽然有很多漏洞,例如窗口大小可随意调整、点击开始游戏的鼠标监听与我方战机的鼠标跟随有冲突......但这套程序拿来练手还是非常不错的,这个小游戏冲分实现了我们前面学习的知识,是个很好的实践方式。效果图如下:

 前面不太恰当的望大神指教【抱拳】【抱拳】【抱拳】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木辛厂小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值