飞机躲避炮弹游戏

该文章详细介绍了如何制作飞机大战游戏,包括爆炸、常量、炮弹、游戏元素、图片加载等7个核心类的实现,以及游戏主窗口的绘制和事件处理。文章展示了利用Java编程语言创建游戏的基本结构和动画效果。
摘要由CSDN通过智能技术生成

通过自己网上学习,和网上查阅的资料所制成,其中还有很多不足,也希望得到大家指点。

首先:

飞机大战是由 7个类,18张图片所组成。

七个类分别列举在下面:

一、爆炸类

利用数组存储爆炸的帧图片,for()循环连续调用,使得爆炸呈现动画效果。图片在文章最后

public class Explode {
    double x,y;
    static Image[] imgs = new Image[16];
    static {
        for(int i=0;i<16;i++){
            imgs[i] = GameUtil.getImage("images/explode/e"+(i+1)+".gif");
            imgs[i].getWidth(null);
        }
    }
     
    int count;
     
    public void draw(Graphics g){
        if(count<=15){
            g.drawImage(imgs[count], (int)x, (int)y, null);
            count++;
        }
    }
     
    public Explode(double x,double y){
        this.x = x;
        this.y = y;
    }
}

二、Constant类

设置Constant类的主要原因是,把游戏窗口的两个常量设置好,避免后期需要调整难找。

public class Constant {
    public static final int GAME_WIDH = 500;
    public static final int GAME_HEIGTH = 500;

}

三、Shell类(炮弹类)

把炮弹封装起来,各个类之间通过封装,再调用,提高代码的可阅读性可复用性,想修改的时候随时修改。

public class Shell extends GameObject{
    double degree;

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

    public void draw(Graphics g){
        Color c = g.getColor();
        g.setColor(Color.yellow);

        g.fillOval((int)x,(int)y,width,height);
        //炮弹任意角度飞行
        x+=speed*Math.cos(degree);
        y+=speed*Math.sin(degree);

        if(y<30||y>Constant.GAME_HEIGTH-15){//500是窗口高度;40是桌子边框,30是球直径;最后一个40是标题栏的高度
            degree = -degree;
        }

        //碰到左右边界
        if(x<5||x>Constant.GAME_WIDH-15){
            degree = Math.PI - degree;
        }
//        g.setColor(c);
    }

}

四、游戏父类

存储了游戏元素的一些基本信息,使用的时候调用即可。

public class GameObject {
    Image img;
    double x,y;
    int speed ;
    int width,height;

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

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

    public GameObject(Image img, double x, double y) {
        super();
        this.img = img;
        this.x = x;
        this.y = y;
    }


    public GameObject() {
    }
    //返回物体所在矩形,便于后期碰撞检测
    public Rectangle getRect(){
        return new Rectangle((int)x,(int)y,width,height);
    }
}

五、GameUtil类:加载图片代码

1. GameUtil.class.getClassLoader().getResource(path);可以帮助我们获得程序运行类加载器,加 载 资源的根目录,从而获得相对资源位置。

2. ImageIO.read()方法是核心方法,帮助我们读取图片信息,并返回Image对象。

public class GameUtil {
    private GameUtil(){

    }
    //指定路径文件的图片对象
    public static Image getImage(String path){
        BufferedImage bi = null;
        try{
            URL u =GameUtil.class.getClassLoader().getResource(path);
            bi = ImageIO.read(u);
        }catch(IOException e){
            e.printStackTrace();
        }
        return bi;
    }
}

六、飞机类

存储飞机的一些基本变量和一些信息。

public class Plane extends GameObject{
    boolean left,up,right,down;
    boolean live = true;
    @Override
    public void drawSelf(Graphics g) {
        if (live) {
            g.drawImage(img, (int) x, (int) y, null);
            if (left) {
                x -= speed;
            }
            if (right) {
                x += speed;
            }
            if (up) {
                y -= speed;
            }
            if (down) {
                y += speed;
            }
        }else{}
    }

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


    public void addDirection(KeyEvent e){
        switch(e.getKeyCode()){
            case KeyEvent.VK_LEFT:
                left = true;
                break;
            case KeyEvent.VK_UP:
                up = true;
                break;
            case KeyEvent.VK_RIGHT:
                right = 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_UP:
                up = false;
                break;
            case KeyEvent.VK_RIGHT:
                right = false;
                break;
            case KeyEvent.VK_DOWN:
                down = false;
                break;
        }
    }
}

七、主窗口类

所有的实现几乎都在这个类里,类里有各种方法调用,模块的方法调用。

public class MyGameFrame extends Frame {

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

    //定义两个新的坐标
    Plane plane = new Plane(planeImg,250,250);
    Shell shell = new Shell();
    Explode bao;
    Date starTime = new Date();
    Date endTime;
    int period;//游戏持续时间
    @Override
    public void paint(Graphics g) {
        g.drawImage(sky,0,0,null);
        plane.drawSelf(g);//画飞机
        Color c = g.getColor();
        Font f = g.getFont();
        Font f1 = new Font("宋体",Font.BOLD,50);

        //画出所有炮弹
        for (int i = 0;i<shells.length;i++){
            shells[i].draw(g);
            boolean peng = shells[i].getRect().intersects(plane.getRect());
            if (peng){
                System.out.println("相撞了!!,你死了。");
                plane.live = false;
                if (bao == null){
                bao = new Explode(plane.x,plane.y);
                endTime = new Date();
                    period = (int)((endTime.getTime()-starTime.getTime())/1000);
                }
                if (!plane.live){
                g.setColor(Color.white);
                g.setFont(f1);
                g.drawString("时间"+period+"秒",200,250);
                bao.draw(g);
                }
            }
        }
        g.setColor(c);
    }
    //存储炮弹
    Shell[] shells = new Shell[30];

    //帮助我们额反复重画窗口
    class PaintThread extends Thread{
        @Override
        public void run() {
            while (true){
                //System.out.println("窗口被画了一次");
                repaint();
                try {
                    Thread.sleep(30); //1s = 1000ms
                } 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);
        }
    }

    //初始化窗口
    public void launchFrame(){
        this.setTitle("陶彦儒_作品");
        this.setVisible(true);//设置窗口是否可见
        this.setSize(Constant.GAME_WIDH,Constant.GAME_HEIGTH);//设置窗口大小
        this.setLocation(800,300);//从左上角(0,0),右边x,下面y
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//0表示正常结束
            }
        });
        new PaintThread().start();//启动重画窗口的线程
        addKeyListener(new KeyMonitor());
        //使用循环存入炮弹
        for (int i = 0;i<shells.length;i++){
            shells[i] = new Shell();
        }
    }

    public static void main(String[] args) {
        MyGameFrame f = new MyGameFrame();
        f.launchFrame();
    }
    private Image offScreenImage = null;

    public void update(Graphics g){
        if (offScreenImage == null)
            offScreenImage = this.createImage(Constant.GAME_WIDH,Constant.GAME_HEIGTH);

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

其中爆炸图片参考自 乓头鱼 博主。感谢阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值