• 模仿微信打飞机做的程序


    学校请了达内来培训8天(其实是学校和培训机构各取所需),主要学了JPanel类。

    上主要代码:

     JPanel画板

    package com.raikou.practise.plane;
    
    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionListener;
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.ImageIcon;
    import javax.swing.Timer;
    import javax.swing.JPanel;
    
    public class PlaneJPanel extends JPanel implements MouseMotionListener,
            MouseListener {
    
        /**
         * 
         */
        private static final long serialVersionUID = -3729222788769506535L;
        private int time = 0, timepre = 0;
        private List<Enemys> newenemys;
        private List<Bullet> newbullet;
        private List<PlaneExplode> newPE;
        private List<Supplies> newS;
    private int px = 180, py = 450; //本机的坐标
        private int boomnum = 0;
        private int doubleBulletstime = 0;
        private boolean isend = false;
        private boolean isstart = false;
        private boolean issuspend = false;
        private boolean isdoubleBullets = false;
        private int score = 0;
        private Timer timer, timer2, timerpre;
        private PlaySound BGM;
        private PlaySound BulletM;
        private PlaySound ButtonM;
        private PlaySound EDM1;
        private PlaySound EDM2;
        private PlaySound EDM3;
        private PlaySound GBM;
        private PlaySound GDLM;
        private PlaySound UBM;
        private int BGy = -252;
        private int BGx;
        private Image SI;
        private Image BGI;
        private Font font;
    
        public PlaneJPanel() {
    
            BGx = 150;
            // 创建计时器
            timerpre = new Timer(1000, new TimerPre());
            timer = new Timer(80, new TimerListener());
            timer2 = new Timer(80, new Timercounter());
            // 初始化各变量
            newenemys = new ArrayList<Enemys>();
            newbullet = new ArrayList<Bullet>();
            newPE = new ArrayList<PlaneExplode>();
            newS = new ArrayList<Supplies>();
            SI = new ImageIcon("./images/shoot.png").getImage();
            BGI = new ImageIcon("./images/shoot_background.png").getImage();
           
            font = new Font("黑体", Font.BOLD, 24);
            // 创建音乐线程
            MusicInit();
            // 添加监听
            this.addMouseMotionListener(this);
            this.addMouseListener(this);
            // 开启游戏线程
            startGame();
            timerpre.start();
        }
    
        public void paint(Graphics g) {
            super.paint(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(10));
            g2.setColor(Color.BLACK);
            g2.setFont(font);
            // 背景图
            g.drawImage(BGI, 0, BGy, 480, BGy + 852, 0, 75, 480, 927, null);
            g.drawImage(BGI, 0, BGy - 852, 480, BGy, 0, 75, 480, 927, null);
            // 欢迎页
            if (!isstart) {
                g.drawImage(BGI, 22, getHeight() / 2 - 112, 456,
                        getHeight() / 2 + 113, 484, 702, 918, 927, null);
                if (timepre % 3 == 0)
                    g.drawImage(BGI, 151, getHeight() / 2 + 147, 200,
                            getHeight() / 2 + 182, 0, 38, 49, 73, null);
                else if (timepre % 3 == 1)
                    g.drawImage(BGI, 151, getHeight() / 2 + 147, 265,
                            getHeight() / 2 + 182, 0, 0, 114, 35, null);
                else
                    g.drawImage(BGI, 151, getHeight() / 2 + 147, 329,
                            getHeight() / 2 + 182, 489, 666, 667, 701, null);
                // g.drawImage(BGW1, BGx, getHeight()/2+147, null);
    
            } else {
    
                timer.start();
                timer2.start();
                for (int i = 0; i < newbullet.size(); i++) {
                    newbullet.get(i).drawBullet(g);
                }
    
                for (int i = 0; i < newenemys.size(); i++) {
                    newenemys.get(i).drawEnemys(g);
                }
    
                for (int i = 0; i < newPE.size(); i++) {
                    newPE.get(i).drawExplode(g);
                }
    
                for (int i = 0; i < newS.size(); i++) {
                    newS.get(i).drawSupplies(g);
                }
                if (boomnum >= 0) {
                    g.drawImage(SI, 10, 520, 71, 574, 812, 694, 872, 745, null);
                    g2.drawString("X" + boomnum, 75, 560);
                }
                if (!isend) {
                    g.drawImage(SI, px, py, px + 98, py + 124, 2, 100, 100, 224,
                            null);
    
                } else
                    g2.drawString("Game Over", getWidth() / 2 - 50,
                            getHeight() / 2 - 10);
                if (!issuspend)
                    g.drawImage(SI, 5, 0, 46, 41, 275, 252, 316, 293, null);
                else
                    g.drawImage(SI, 5, 0, 46, 41, 819, 648, 860, 689, null);
                g2.drawString("" + score, 60, 30);
            }
    
        }
    
        public void startGame() {
    
            new Thread() {
                public void run() {
                    try {
                        sleep(100);
                    } catch (InterruptedException e1) {
                        // TODO 自动生成的 catch 块
                        e1.printStackTrace();
                    }
                    while (true) {
                        while (isstart && !isend && !issuspend) {
                            BGy++;
                            if (BGy >= 600)
                                BGy = -252;
                            // 判断子弹和敌机的撞击,机型1撞击次数1次,机型2撞击次数6次,机型3撞击次数12次,满次数后敌机爆炸
                            for (int i = 0; i < newbullet.size(); i++) {
                                newbullet.get(i).startBullet();
                                if (newbullet.get(i).getBy() <= 0)
                                    newbullet.remove(i);
                                else
                                    for (int j = 0; j < newenemys.size(); j++) {
                                        if (newenemys.get(j).getType() == 1) {
                                            if ((newbullet.get(i).getBy()
                                                    - newenemys.get(j).getY() <= 36 && newbullet
                                                    .get(i).getBy()
                                                    - newenemys.get(j).getY() >= 0)
                                                    && (newbullet.get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() >= 0 && newbullet
                                                            .get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() <= 39)) {
                                                if (newenemys.get(j).getHit() > 0) {
                                                    newenemys.get(j).setHit(
                                                            newenemys.get(j)
                                                                    .getHit() - 1);
                                                }
                                                if (newenemys.get(j).getHit() == 0) {
                                                    newPE.add(new PlaneExplode(
                                                            newenemys.get(j).getX(),
                                                            newenemys.get(j).getY(),
                                                            newenemys.get(j)
                                                                    .getType()));
                                                    score += newenemys.get(j)
                                                            .getScore();
                                                    EDM1.Play();
                                                    newenemys.remove(j);
    
                                                }
                                                newbullet.remove(i);
    
                                                break;
                                            }
                                        } else if (newenemys.get(j).getType() == 2) {
                                            if ((newbullet.get(i).getBy()
                                                    - newenemys.get(j).getY() <= 93 && newbullet
                                                    .get(i).getBy()
                                                    - newenemys.get(j).getY() >= 0)
                                                    && (newbullet.get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() >= 0 && newbullet
                                                            .get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() <= 59)) {
                                                if (newenemys.get(j).getHit() > 0) {
                                                    newenemys.get(j).setHit(
                                                            newenemys.get(j)
                                                                    .getHit() - 1);
                                                    newenemys.get(j).setHited(
                                                            !newenemys.get(j)
                                                                    .isHited());
                                                }
                                                if (newenemys.get(j).getHit() == 0) {
                                                    newPE.add(new PlaneExplode(
                                                            newenemys.get(j).getX(),
                                                            newenemys.get(j).getY(),
                                                            newenemys.get(j)
                                                                    .getType()));
                                                    score += newenemys.get(j)
                                                            .getScore();
                                                    EDM2.Play();
                                                    newenemys.remove(j);
    
                                                }
                                                newbullet.remove(i);
    
                                                break;
                                            }
                                        } else {
                                            if ((newbullet.get(i).getBy()
                                                    - newenemys.get(j).getY() <= 256 && newbullet
                                                    .get(i).getBy()
                                                    - newenemys.get(j).getY() >= 0)
                                                    && (newbullet.get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() >= 0 && newbullet
                                                            .get(i).getBx()
                                                            - newenemys.get(j)
                                                                    .getX() <= 146)) {
                                                if (newenemys.get(j).getHit() > 0) {
                                                    newenemys.get(j).setHit(
                                                            newenemys.get(j)
                                                                    .getHit() - 1);
                                                    newenemys.get(j).setHited(
                                                            !newenemys.get(j)
                                                                    .isHited());
                                                }
                                                if (newenemys.get(j).getHit() == 0) {
                                                    newPE.add(new PlaneExplode(
                                                            newenemys.get(j).getX(),
                                                            newenemys.get(j).getY(),
                                                            newenemys.get(j)
                                                                    .getType()));
                                                    score += newenemys.get(j)
                                                            .getScore();
                                                    EDM3.Play();
                                                    newenemys.remove(j);
    
                                                }
                                                newbullet.remove(i);
    
                                                break;
                                            }
                                        }
                                    }
    
                            }
                            // 本机的爆炸效果
                            for (int i = 0; i < newenemys.size(); i++) {
                                newenemys.get(i).startMoving();
                                if (newenemys.get(i).getY() >= 600)
                                    newenemys.remove(i);
                                else {
                                    if (newenemys.get(i).getType() == 1) {
                                        if ((newenemys.get(i).getX() - px >= -28 && newenemys
                                                .get(i).getX() - px <= 48)
                                                && (py - newenemys.get(i).getY() <= 34 && py
                                                        - newenemys.get(i).getY() >= -124)) {
                                            newPE.add(new PlaneExplode(px, py, 0));
                                            isend = true;
                                        }
                                    } else if (newenemys.get(i).getType() == 2) {
                                        if ((newenemys.get(i).getX() - px >= -40 && newenemys
                                                .get(i).getX() - px <= 28)
                                                && (py - newenemys.get(i).getY() <= 93 && py
                                                        - newenemys.get(i).getY() >= -124)) {
                                            newPE.add(new PlaneExplode(px, py, 0));
                                            isend = true;
                                        }
                                    } else if (newenemys.get(i).getType() == 3) {
                                        if ((newenemys.get(i).getX() - px >= -90 && newenemys
                                                .get(i).getX() - px <= -68)
                                                && (py - newenemys.get(i).getY() <= 256 && py
                                                        - newenemys.get(i).getY() >= -124)) {
                                            newPE.add(new PlaneExplode(px, py, 0));
                                            isend = true;
                                        }
                                    }
                                }
    
                            }
                            // 显示完爆炸效果后消失
                            for (int i = 0; i < newPE.size(); i++) {
                                if (newPE.get(i).getTime() >= 6)
                                    newPE.remove(i);
                            }
                            // 控制补给品
                            for (int i = 0; i < newS.size(); i++) {
                                newS.get(i).startMoving();
                                if ((newS.get(i).getX() - px >= -newS.get(i)
                                        .getWidth() + 10 && newS.get(i).getX() - px <= 88 + newS
                                        .get(i).getWidth())
                                        && (py - newS.get(i).getY() <= newS.get(i)
                                                .getHeight() && py
                                                - newS.get(i).getY() >= -102)) {
                                    if (newS.get(i).getType() == 1) {
                                        isdoubleBullets = true;
                                        doubleBulletstime = 50;
                                        GDLM.Play();
                                    } else {
                                        GBM.Play();
                                        boomnum++;
                                    }
                                    newS.remove(i);
                                }
                            }
    
                            try {
                                sleep(20);
                            } catch (InterruptedException e) {
                                // TODO 自动生成的 catch 块
                                e.printStackTrace();
                            }
                            repaint();
                        }
                        repaint();
    
                    }
                }
            }.start();
        }
    
        public void setIsstart(boolean isstart) {
            this.isstart = isstart;
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO 自动生成的方法存根
            // 滑动开始
            if (!isstart) {
                if ((e.getY() >= getHeight() / 2 + 147 && e.getY() <= getHeight() / 2 + 182)
                        && (e.getX() >= 150 && e.getX() <= 285))
                    BGx = e.getX();
                if (BGx >= 283) {
                    isstart = true;
                    issuspend = false;
                }
            }
    
            if (isstart) {
                px = e.getX() - 49;
                py = e.getY() - 62;
    
                repaint();
            }
        }
    
        public void MusicInit() {
            BGM = new PlaySound(new File("./sound/game_music.mp3"));
            BulletM = new PlaySound(new File("./sound/bullet.mp3"));
            ButtonM = new PlaySound(new File("./sound/button.mp3"));
            EDM1 = new PlaySound(new File("./sound/enemy1_down.mp3"));
            EDM2 = new PlaySound(new File("./sound/enemy2_down.mp3"));
            EDM3 = new PlaySound(new File("./sound/enemy3_down.mp3"));
            GBM = new PlaySound(new File("./sound/get_bomb.mp3"));
            GDLM = new PlaySound(new File("./sound/get_double_laser.mp3"));
            UBM = new PlaySound(new File("./sound/use_bomb.mp3"));
            BGM.Play();
        }
    
        @Override
        public void mouseMoved(MouseEvent e) {
            // TODO 自动生成的方法存根
    
        }
    
        class Timercounter implements ActionListener {
    
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < newPE.size(); i++) {
                    newPE.get(i).setTime(newPE.get(i).getTime() + 1);
                }
            }
        }
    
        class TimerPre implements ActionListener {
    
            public void actionPerformed(ActionEvent e) {
                timepre++;
            }
        }
    
        class TimerListener implements ActionListener {
    
            public void actionPerformed(ActionEvent e) {
                time++;
                if (!isend && isstart && !issuspend) {
                    if (!isdoubleBullets) {
                        newbullet.add(new Bullet(px + 48, py, 1));
                        BulletM.Play();
                    } else {
                        if (doubleBulletstime > 0) {
                            newbullet.add(new Bullet(px + 33, py, 2));
                            newbullet.add(new Bullet(px + 63, py, 2));
                            BulletM.Play();
                            doubleBulletstime--;
                        } else
                            isdoubleBullets = false;
                    }
                    if (Math.random() > 0.9) {
                        double typerandom = Math.random();
                        if (typerandom < 0.85)
                            newenemys.add(new Enemys((int) (Math.random() * 380),
                                    -36, 1));
                        else if (typerandom < 0.99)
                            newenemys.add(new Enemys((int) (Math.random() * 430),
                                    -93, 2));
                        else
                            newenemys.add(new Enemys((int) (Math.random() * 285),
                                    -256, 3));
                    }
                    if (time > 100 && Math.random() > 0.995) {
    
                        double typerandom = Math.random();
                        if (typerandom < 0.7)
                            newS.add(new Supplies((int) (Math.random() * 380), 25,
                                    1));
                        else
                            newS.add(new Supplies((int) (Math.random() * 380), 25,
                                    2));
                    }
                }
            }
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO 自动生成的方法存根
            if ((e.getY() >= 0 && e.getY() <= 41)
                    && (e.getX() >= 5 && e.getX() <= 46)) {
                issuspend = !issuspend;
                ButtonM.Play();
            }
            if (!issuspend)
                if ((e.getY() >= 520 && e.getY() <= 574)
                        && (e.getX() >= 10 && e.getX() <= 80) && boomnum > 0) {
                    UBM.Play();
                    for (int i = 0; i < newenemys.size(); i++) {
                        newPE.add(new PlaneExplode(newenemys.get(i).getX(),
                                newenemys.get(i).getY(), newenemys.get(i).getType()));
                        score += newenemys.get(i).getScore();
    
                    }
                    newenemys.removeAll(newenemys);
                }
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
            // TODO 自动生成的方法存根
    
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO 自动生成的方法存根
    
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO 自动生成的方法存根
    
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            // TODO 自动生成的方法存根
    
        }
    
    }

    敌机,子弹,补给品,和飞机爆炸效果4个类都放在集合里,个人感觉在这里用集合比数组方便,因为并不知道会有多少个元素,而且感觉打开程序的速度也有提升(后来加上音乐后又变慢了- -).计时器控制一下如敌机,补给品和子弹的出现频率,还有控制爆炸画面不能太快。敌机和补给品的出现率还有Math.Random()控制,可以根据时间或分数来调整概率。


    敌机类(子弹类等类似)

    package com.raikou.practise.plane;
    
    import java.awt.Graphics;
    import java.awt.Image;
    import javax.swing.ImageIcon;
    
    public class Enemys {
        private int y;
        private int x;
        private int type;
        private int score;
        private int hit;
        private boolean isHited = false;
        private Image enemyplane;
    
        public Enemys(int x, int y, int type) {
            super();
            this.y = y;
            this.x = x;
    
            this.type = type;
            switch (type) {
            case 1:
                score = 1000;
                hit = 1;
                break;
            case 2:
                score = 6000;
                hit = 6;
                break;
            case 3:
                score = 30000;
                hit = 12;
                break;
            default:
                break;
            }
            enemyplane = new ImageIcon("./images/shoot.png").getImage();
        }
    
        public int getHit() {
            return hit;
        }
    
        public void setHit(int hit) {
            this.hit = hit;
        }
    
        public void drawEnemys(Graphics g) {
            if (!isHited) {
                if (type == 1)
                    g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588,
                            653, null);
                else if (type == 2)
                    g.drawImage(enemyplane, x, y, x + 69, y + 93, 0, 0, 69, 93,
                            null);
                else if (type == 3)
                    g.drawImage(enemyplane, x, y, x + 165, y + 256, 338, 750, 503,
                            1006, null);
            } else {
                if (type == 1)
                    g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588,
                            653, null);
                else if (type == 2)
                    g.drawImage(enemyplane, x, y, x + 69, y + 93, 432, 529, 501,
                            622, null);
                else if (type == 3)
                    g.drawImage(enemyplane, x, y, x + 165, y + 256, 165, 750, 330,
                            1006, null);
    
            }
        }
    
        public boolean isHited() {
            return isHited;
        }
    
        public void setHited(boolean isHited) {
            this.isHited = isHited;
        }
    
        public void startMoving() {
            if (type == 1)
                y += 4;
            else if (type == 2)
                y += 3;
            else
                y += 2;
        }
    
        public int getScore() {
            return score;
        }
    
        public int getType() {
            return type;
        }
    
        public int getY() {
            return y;
        }
    
        public int getX() {
            return x;
        }
    
    }

    这个类包含敌机的一些基本属性,如何坐标,大小,还有运动轨迹和速度。碰撞的判断写在PlaneJPanel的线程中。

    成品:
    http://yunpan.cn/QCBrHusDXyHpj  访问密码 80c7

    本人新手,欢迎各种建议和讨论,大神勿喷。

  • 相关阅读:
    JavaScript坑
    maven学习
    JAVA多线程和并发基础面试问答(转)
    Redis与Memcached的区别(一)
    poi生成execl综合
    POI操作Excel常用方法总结(转)
    java中在创建对象时候的初始化顺序
    [Java Web]敏感词过滤算法
    orcle导入导出
    js动态时间
  • 原文地址:https://www.cnblogs.com/raikouissen/p/3328539.html
Copyright © 2020-2023  润新知