Java从遗忘到入门——Day03

今天完成了飞机小游戏。代码结构如下:
代码结构
其中GameObject类为目标根类,代码为:

public class GameObject {

    Image img;
    double x,y;
    int speed,width,height;

    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() {}

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

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

飞机类Plane为:

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);
    }

    @Override
    public void drawMyself(Graphics g) {
        if (live) {
            super.drawMyself(g);
            if (left) {
                this.x -= this.speed;
            }
            if (right) {
                this.x += this.speed;
            }
            if (up) {
                this.y -= this.speed;
            }
            if (down) {
                this.y += this.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 minisDirection(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;
        }
    }
}

子弹类Shell为:

public class Shell extends GameObject {

    double degree;

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

    @Override
    public void drawMyself(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 > 500 - height || y < 30) {
            degree = -degree;
        }
        if (x < 0 || x > 500 - width) {
            degree = Math.PI - degree;
        }
        //返回给外部,变回以前的颜色
        g.setColor(c);
    }
}

爆炸类Explode为:

public class Explode extends GameObject {
    
    double x,y;
    int count;
    static Image[] imgs = new Image[16];
    
    static {
        for (int i = 0;i < 16;i++) {
            imgs[i] = GameUtil.getImage("Image/explode/e" + (i + 1) + ".gif");
        }
    }

    @Override
    public void drawMyself(Graphics g) {
        if (count < 16) {
            g.drawImage(imgs[count++],(int)x,(int)y,null);
        }
    }

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

工具类GameUtil为:

public class GameUtil {

    //构造器私有
    private GameUtil() {}

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

主类MyGameFrame为:

public class MyGameFrame extends Frame {
    
    Image planeImage = GameUtil.getImage("Image/plane.png");
    Image bg = GameUtil.getImage("Image/bg.jpg");
    Plane plane = new Plane(planeImage,100,100,7);
    Shell[] shells = new Shell[50];
    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);
        plane.drawMyself(g);

        for (int i = 0;i < 50;++i) {
            shells[i].drawMyself(g);
            boolean peng = shells[i].getRectangle().intersects(plane.getRectangle());
            if(peng) {
                plane.live = false;
                if (explode == null) {
                    explode = new Explode(plane.x,plane.y);
                }
                explode.drawMyself(g);
            }
        }
        drawTime(g);
    }

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

    //初始化窗口
    public void launchFrame() {
        this.setTitle("飞机大战");
        setVisible(true); //窗口是否可见
        setSize(500, 500); //窗口大小
        setLocation(400, 100);  //窗口打开位置
        for (int i = 0;i < 50;++i) {
            shells[i] = new Shell();
        }
        // 增加关闭窗口的动作
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0); //正常退出程序
            }
        });
        new MyPaint().start();
        this.addKeyListener(new KeyMoniter());
    }

    class MyPaint extends Thread {
        @Override
        public void run() {
            while(true) {
                repaint();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class KeyMoniter extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            plane.addDirection(e);
        }

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

    private Image offScreenImage = null;

    public void update(Graphics g) {
        if(offScreenImage == null)
            offScreenImage = this.createImage(500,500);//这是游戏窗口的宽度和高度

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

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

2个飞机&背景素材链接:提取码:k44l
16个爆炸图片素材链接:提取码:9zkk

发布了33 篇原创文章 · 获赞 9 · 访问量 8688

猜你喜欢

转载自blog.csdn.net/Serena0814/article/details/104885977