Java实现飞机大战小游戏|Java入门结课作业

** 如有错误,感谢指正**

请根据目录寻找自己需要的段落

导语:本博客为个人整理Java学习记录帖,如有错误,感谢指正。系统学习,欢迎持续关注,后续陆陆续续更新Java后端项目,Java部分我不打算更新基础部分知识,会从JavaWeb开始更新文章。
Java交流QQ群 383245788
代码布局如下图代码布局

项目分析

通过键盘控制飞机前后移动,躲避炮弹,有时间计数器,计算游戏时间,飞机触碰炮弹,游戏结束,计时停止,显示本次游戏时长。

目前项目存在一个问题,运行时总是会对炮弹有空指针异常,但不影响游戏运行

下一步,博主会在次项目基础上完善登录系统。自主选择游戏难度等DIY,欢迎大家评论讨论实现。

Shell部分

package atluofu;

import java.awt.*;

/**
 * @program: com.atbaizhan
 * @description: 炮弹类
 * @author: atLuoFu
 * @create: 2021-07-17 22:41
 **/
public class Shell extends GameObject {
    double degree; //角度,炮弹沿着指定角度飞行

    public Shell() {
        x = 200;
        y = 200;
        degree = Math.random() * Math.PI * 2;
        width = 10;
        height = 10;
        speed = 7;
    }

    @Override
    public void drawMySelf(Graphics g) {
        Color color = g.getColor();
        g.setColor(Color.yellow);
        g.fillOval((int) x, (int) y, width, height);
        g.setColor(color);
        x += speed * Math.cos(degree);
        y += speed * Math.sin(degree);
        if (y >= Constant.GAME_HEIGHT - this.height || y <= 40) {
            degree = -degree;
        }
        if (x <= 0 || x >= Constant.GAME_WIDTH - this.width) {
            degree = Math.PI - degree;
        }
    }
}

Plane类

package atluofu;

import java.awt.*;
import java.awt.event.KeyEvent;

/**
 * @program: com.atbaizhan
 * @description: 飞机类
 * @author: atLuoFu
 * @create: 2021-07-17 11:54
 **/
public class Plane extends GameObject {

    boolean left, right, up, down; // 飞机方向的控制

    boolean live = true;

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


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

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

    @Override
    public void drawMySelf(Graphics g) {
        if (live) {
            super.drawMySelf(g);
            if (left) {
                x -= speed;
            }
            if (right) {
                x += speed;
            }
            if (up) {
                y -= speed;
            }
            if (down) {
                y += speed;
            }
        }
    }
}

MyGameFrame类

package atluofu;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;

/**
 * @program: com.atbaizhan
 * @description: 游戏主窗口
 * @author: atLuoFu
 * @create: 2021-07-17 07:30
 **/
public class MyGameFrame extends Frame {

    Image planeImg = GameUtil.getImage("images/plane.png");
    Image bg = GameUtil.getImage("images/bg.jpg");

    Plane plane = new Plane(planeImg, 100, 100, 7);
    Shell shell = new Shell();
    Shell[] shells = new Shell[30];
    Explode explode;

    Date start = new Date();
    Date end;
    long period = 0;

    @Override
    public void paint(Graphics g) {     // g当作是一个画笔

        g.drawImage(bg, 0, 0, 500, 500, null);

        drawTime(g);
        plane.drawMySelf(g);
        shell.drawMySelf(g);
        for (int i = 0; i < shells.length; i++) {
            shells[i].drawMySelf(g);
            boolean isCollision = shells[i].getRec().intersects(plane.getRec());
            if (isCollision) {
                plane.live = false;
                if (explode == null) {
                    explode = new Explode(plane.x, plane.y);
                }
                explode.drawMySelf(g);
            }
        }
    }

    public void drawTime(Graphics g) {
        Color color = g.getColor();
        Font font = g.getFont();
        if (plane.live) {
            g.setColor(Color.green);
            period = (System.currentTimeMillis() - start.getTime()) / 1000;
            g.drawString("坚持了" + period + "秒", 100, 100);
        } else {
            g.setColor(Color.red);
            if (end == null) {
                end = new Date();
                period = (end.getTime() - start.getTime()) / 1000;
            }
            g.setFont(new Font("微软雅黑", Font.BOLD, 30));
            g.drawString("坚持了" + period + "秒", 200, 200);
        }
        g.setColor(color);
        g.setFont(font);
    }

    //初始化窗口
    public void launchFrame() {
        this.setTitle("飞机大战-atLuoFu");
        setVisible(true);
        setSize(500, 500);
        setLocation(400, 400);

        // 正常退出程序
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

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

        for (int i = 0; i < shells.length; i++) {
            shells[i] = new Shell();
        }
    }

    /**
     * 定义了一个重画窗口的线程
     * 定义成内部类是为了方便直接使用窗口类的相关方法
     */
    class PainThread extends Thread {
        @Override
        public void run() {
            while (true) {
                repaint();

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

    /**
     * 内部类 实现键盘监听处理
     */
    class KeyMonitor extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            plane.addDirection(e);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            plane.minusDirection(e);

        }
    }

    // 双缓冲技术,解决屏幕闪烁问题
    private Image offScreenImage = null;

    public void update(Graphics g) {
        if (offScreenImage == null) {
            offScreenImage = this.createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); //这是游戏窗口的宽度和高度
        }
        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage, 0, 0, null);
    }

    public static void main(String[] args) {
        MyGameFrame myGameFrame = new MyGameFrame();
        myGameFrame.launchFrame();
    }
}

GameUtil

package atluofu;


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

/**
 * @program: com.atbaizhan
 * @description: 游戏工具类
 * @author: atLuoFu
 * @create: 2021-07-17 07:46
 **/
public class GameUtil {

    // 构造器私有 防止创建此类对象
    private GameUtil(){

    }

    public static BufferedImage getImage(String path) {
        BufferedImage image = null;
        URL u = GameUtil.class.getClassLoader().getResource(path);
        try {
            image = ImageIO.read(u);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    public static void main(String[] args) {
        Image img= GameUtil.getImage("images/plane.png");
        System.out.println(img);
    }
}

GameObject类

package atluofu;

import java.awt.*;

/**
 * @program: com.atbaizhan
 * @description: 游戏物体的根类
 * @author: atLuoFu
 * @create: 2021-07-17 11:43
 **/
public class GameObject {
    Image img;
    double x, y;
    int speed;
    int width, height;


    public GameObject() {
    }

    public GameObject(Image img, double x, double y, int speed) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.speed = speed;
        this.width = img.getWidth(null);
        this.height = img.getHeight(null);
    }

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

    public void drawMySelf(Graphics g) {
        g.drawImage(img, (int) x, (int) y, width, height, null);
    }

    public Rectangle getRec() {
        return new Rectangle((int) x, (int) y, width, height);
    }
}

Explode类

package atluofu;

import java.awt.*;

/**
 * @program: com.atbaizhan
 * @description: 爆炸特效实现类
 * @author: atLuoFu
 * @create: 2021-07-17 23:12
 **/
public class Explode {
    double x, y;
    static Image[] images = new Image[16];

    int count;

    static {
        for (int i = 0; i < images.length; i++) {
            images[i] = GameUtil.getImage("images/explode/e" + (i + 1) + ".gif");
            //images[i].getWidth(null);
        }
    }

    public Explode() {

    }

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

    public void drawMySelf(Graphics g) {
        if (count < 16) {
            g.drawImage(images[count], (int) x, (int) y, null);
            count++;
        }
    }
}

Constant

package atluofu;

/**
 * @program: com.atbaizhan
 * @description: 存放相关常量
 * @author: atLuoFu
 * @create: 2021-07-17 08:14
 **/
public class Constant {
    public static final int GAME_WIDTH = 500;
    public static final int GAME_HEIGHT = 500;
}

Image资源

图片资源链接

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

墨竹菊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值