• 坦克大战编程


    坦克大战1.0:

    1.首先建立我的面板Mypanel,继承JPanel ,引用 import javax.swing;

    2.主函数要显示面板,使用Demo1类需要extends JFrame

    3.绘图 Graphics 需要引用 import java.awt.*;

    4.初始化不要忘了初始化 x y

    5.整个Myframe 作为坦克的图形,设计好面板最终放入到框架中JFrame

    6.Myframe中的画笔画出所有的图形,而JFrame只是设定一个显示框架

    7.g.fillRect是为了将背景颜色进行修改

    8.编写drawTank函数用g来画出坦克的形状,每调用一个drawTank只能画一个坦克

    初步显示静止图形代码:

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
    
            this.add(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel {
        Hero hero;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, 0, 1);
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.CYAN);
            case 1:// 我的坦克
                g.setColor(Color.YELLOW);
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:
            case 2:
            case 3:
            }
        }
    }
    View Code

     怎么样让坦克动起来?

    事件监听:

    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;

    1.想要坦克动起来,首先需要设置KeyListener,在Myframe中定义接口,自动生成接口函数

    2.在Hero中设置move函数 实现上下左右移动

    3.为什么坦克还没有动?主函数加入加入 this.addKeyListener(mp),但是还没有动,还需要在 keyPressed函数中加入this.repeat()函数将面板重画

    4.坦克的方向还未改变,switch(direct) 编写完整

     可以移动的坦克代码:

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
    
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener {
        Hero hero;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.CYAN);
            case 1:// 我的坦克
                g.setColor(Color.YELLOW);
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

    坦克大战2.0版本:(线程机制,编写敌方动态坦克)

    package demo1;
    
    //横着x 竖着y
    import java.awt.*;
    import javax.swing.*;
    import java.awt.Event.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    public class Demo2 extends JFrame {
        Myframe mp;
    
        public static void main(String[] args) {
            Demo2 demo = new Demo2();
        }
    
        public Demo2() {
            mp = new Myframe();
            // 启动mp线程
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.setSize(400, 300);
            this.addKeyListener(mp);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // Myframe定义的面板用于绘图
    class Myframe extends JPanel implements KeyListener, Runnable {
        // 定义我的坦克
        Hero hero;
        // 定义敌人的坦克
        Vector<EnemyTank> ets = new Vector<EnemyTank>();
        int ensize = 3;
    
        public void paint(Graphics g) {
            super.paint(g);
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, this.hero.getDirect(), 1);// 可以实现坦克的类型0
    
            // 画出自己的子弹
            if (hero.p != null && hero.p.islive == true) {
                g.draw3DRect(hero.p.x, hero.p.y, 3, 3, false);
    
            }
            // 画出敌人的坦克
            for (int i = 0; i < ets.size(); i++) {
                this.drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get(i).getDirect(), 0);
            }
        }
    
        public Myframe() {
            hero = new Hero(100, 50);// 初始化坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                EnemyTank et = new EnemyTank((i + 1) * 50, 0);
                et.setColor(0);
                et.setDirect(2);
                ets.add(et);
            }
        }
    
        // 画出坦克的函数
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            switch (type) {
            case 0:// 我的坦克
                g.setColor(Color.CYAN);
                break;
            case 1:// 敌人的坦克
                g.setColor(Color.YELLOW);
                break;
            }
            // 判断方向
            switch (direct) {
            // 向上
            case 0:
                // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 画出中间矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出圆形
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 画出上面的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 画出中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                g.fillOval(x + 10, y + 5, 10, 10);
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 画出中间矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出圆形
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 画出中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                g.fillOval(x + 10, y + 5, 10, 10);
                g.drawLine(x + 0, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                //
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                //
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                //
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                //
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
            if (e.getKeyCode() == KeyEvent.VK_J) {
                // 判断玩家是否按下
                this.hero.shote();
            }
            // 重新绘制panel
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                this.repaint();
            }
        }
    }
    
    class Tank {
        int x;
        int y;
        int direct = 0;// 0 表示上 1表示右 2表示下 3表示左
        int speed = 5;
        int color = 0;
    
        public int getColor() {
            return color;
        }
    
        public void setColor(int color) {
            this.color = color;
        }
    
        public int getSpeed() {
            return speed;
        }
    
        public void setSpeed(int speed) {
            this.speed = speed;
        }
    
        public int getDirect() {
            return direct;
        }
    
        public void setDirect(int direct) {
            this.direct = direct;
        }
    
        public Tank(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        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;
        }
    
    }
    
    class Hero extends Tank {
        shot p = null;
    
        public Hero(int x, int y) {
            super(x, y);
    
        }
    
        // 开火
        public void shote() {
            switch (this.direct) {
            case 0:
                p = new shot(x + 10, y, 0);
                break;
            case 1:
                p = new shot(x + 30, y + 10, 1);
                break;
            case 2:
                p = new shot(x + 10, y + 30, 2);
                break;
            case 3:
                p = new shot(x, y + 10, 3);
                break;
            }
            Thread s = new Thread(p);
            s.start();
    
        }
    
        public void moveup() {
            y -= speed;
        }
    
        public void moveright() {
            x += speed;
        }
    
        public void movedown() {
            y += speed;
        }
    
        public void moveleft() {
            x -= speed;
        }
    
    }
    
    class shot implements Runnable {
        int x, y;
        int direct, speed = 3;
        boolean islive = true;
    
        public shot(int x, int y, int direct) {
            this.x = x;
            this.y = y;
            this.direct = direct;
            // this.speed=speed;
        }
    
        @Override
        public void run() {
    
            while (true) {
    
                try {
                    Thread.sleep(50);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                switch (direct) {
                case 0:
                    y -= speed;
                    break;
                case 1:
                    x += speed;
                    break;
                case 2:
                    y += speed;
                    break;
                case 3:
                    x -= speed;
                }
                // 子弹坐标
                System.out.println("子弹坐标x= " + x + "y=" + y);
                // 判断该子弹是否碰到边缘
                if (x < 0 || x > 400 || y < 0 || y > 300) {
                    this.islive = false;
                    break;
                }
            }
        }
    }
    View Code

    首先增加敌方坦克

    1.面板中定义敌方坦克容器

    2.构造函数对敌方坦克进行初始化

    3.绘图g画出坦克模型,

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
    
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener {
        Hero hero;
        // 初始化我的敌人
        Vector<EnemyTank> ets = new Vector<EnemyTank>();
        int ensize = 3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出子弹
            if (hero.s != null) {
                g.draw3DRect(hero.x, hero.y, 1, 1, false);
            }
            // 画出敌人的坦克
            for (int i = 0; i < ets.size(); i++) {
                this.drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get(i).getDirect(), 0);
            }
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 这里进行设坦克的数目
            for (int i = 0; i < ensize; i++) {
                EnemyTank et = new EnemyTank((i + 1) * 50, 0);
                et.setColor(0);
                et.setDirect(2);
                ets.add(et);// 放入容器
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.CYAN);
                break;
            case 1:// 我的坦克
                g.setColor(Color.YELLOW);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
            // 判断玩家是否发射了炮弹J
            if (e.getKeyCode() == KeyEvent.VK_J) {
                // 开火
                this.hero.shot();
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

    标准代码;

    主函数Demo1:

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
    
            // 画出自己的子弹
            if (hero.p != null && hero.p.islive == true) {
                g.draw3DRect(hero.p.x, hero.p.y, 3, 3, false);
    
            }
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.CYAN);
            case 1:// 我的坦克
                g.setColor(Color.YELLOW);
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
            if (e.getKeyCode() == KeyEvent.VK_J) {
                // 判断玩家是否按下
                this.hero.shote();
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                this.repaint();
            }
        }
    }
    View Code

    Tank:

    package demo1;
    public class Tank {
        int x;
        int y;
        int direct = 0;// 0 表示上 1表示右 2表示下 3表示左
        int speed = 5;
        int color = 0;
    Shot p=null;
    //开火
    public void shote() {
        switch (this.direct) {
        case 0:
            p = new Shot(x + 10, y, 0);
            break;
        case 1:
            p = new Shot(x + 30, y + 10, 1);
            break;
        case 2:
            p = new Shot(x + 10, y + 30, 2);
            break;
        case 3:
            p = new Shot(x, y + 10, 3);
            break;
        }
        Thread s = new Thread(p);
        s.start();
    
    }
        public int getColor() {
            return color;
        }
    
        public void setColor(int color) {
            this.color = color;
        }
    
        public int getSpeed() {
            return speed;
        }
    
        public void setSpeed(int speed) {
            this.speed = speed;
        }
    
        public int getDirect() {
            return direct;
        }
    
        public void setDirect(int direct) {
            this.direct = direct;
        }
    
        public Tank(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        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 void moveup() {
            y -= speed;
        }
    
        public void moveright() {
            x += speed;
        }
    
        public void movedown() {
            y += speed;
        }
    
        public void moveleft() {
            x -= speed;
        }
    }
    class Hero extends Tank {
    
        public Hero(int x, int y) {
            super(x, y);
    
        }
    }
    
        
    View Code

    炮弹Shot

    package demo1;
    
    class Shot implements Runnable {
        int x, y;
        int direct, speed = 3;
        boolean islive = true;
    
        public Shot(int x, int y, int direct) {
            this.x = x;
            this.y = y;
            this.direct = direct;
            // this.speed=speed;
        }
    
        @Override
        public void run() {
    
            while (true) {
    
                try {
                    Thread.sleep(50);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                switch (direct) {
                case 0:
                    y -= speed;
                    break;
                case 1:
                    x += speed;
                    break;
                case 2:
                    y += speed;
                    break;
                case 3:
                    x -= speed;
                }
                // 子弹坐标
                System.out.println("子弹坐标x= " + x + "y=" + y);
                // 判断该子弹是否碰到边缘
                if (x < 0 || x > 400 || y < 0 || y > 300) {
                    this.islive = false;
                    break;
                }
            }
        }
    }
    View Code

    怎么实现连发?

     子弹是坦克的属性,设计弹夹,然后绘制

    可以连发后最多连发五颗子弹?

    连发五颗后就没子弹了,怎么上子弹? 从弹夹中删除弹壳

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        // 加入敌人的坦克(数量不确定用容器)
        Vector<Enemy> enemy = new Vector<Enemy>();
        int ensize = 3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出敌方的坦克
            for (int i = 0; i < ensize; i++) {
                this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0);
            }
            // 从弹夹中取出每一颗子弹
            for (int i = 0; i < this.hero.m.size(); i++) {
                Shot myshot = hero.m.get(i);
                // 画出自己的子弹 (一颗)
                if (myshot != null && myshot.islive == true) {
                    // g.setColor(Color.red);
                    g.draw3DRect(myshot.x, myshot.y, 3, 3, false);
                } else {
                    // 从m中删除子弹
                    hero.m.remove(myshot);// 为什么不用i
                }
            }
    
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 初始化敌方坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                Enemy et = new Enemy((i + 1) * 50, 0);
                // et.set
                enemy.add(et);
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.cyan);
                break;// 注意break
            case 1:// 我的坦克
                g.setColor(Color.yellow);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
    
            if (e.getKeyCode() == KeyEvent.VK_J) {
                if (this.hero.m.size() <= 5) {
                    // 判断玩家是否按下
                    this.hero.shote();
                }
    
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                this.repaint();
            }
        }
    }
    View Code

     打中坦克后消失,怎么判断打中坦克?

     1.选中一个函数判断是否打中,位置在Mypanel中

    s.islive=false;
    et.islive=false;

    在什么地方调用判断函数,随时判断run函数

    定义完成后,修改Mypanel的画坦克函数

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        // 加入敌人的坦克(数量不确定用容器)
        Vector<Enemy> enemy = new Vector<Enemy>();
        int ensize = 3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出敌方的坦克
            for (int i = 0; i < ensize; i++) {
                Enemy et = enemy.get(i);
                if (et.islive) {
                    // 这里用et代替
                    this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0);
                }
            }
            // 从弹夹中取出每一颗子弹
            for (int i = 0; i < this.hero.m.size(); i++) {
                Shot myshot = hero.m.get(i);
                // 画出自己的子弹 (一颗)
                if (myshot != null && myshot.islive == true) {
                    // g.setColor(Color.red);
                    g.draw3DRect(myshot.x, myshot.y, 3, 3, false);
                } else {
                    // 从m中删除子弹
                    hero.m.remove(myshot);// 为什么不用i
                }
            }
    
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 初始化敌方坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                Enemy et = new Enemy((i + 1) * 50, 0);
                // et.set
                enemy.add(et);
            }
        }
    
        // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克
        public void hitTank(Shot s, Enemy et) {
            // 判断坦克的方向 主要是向上 向下 两种位置状态
            switch (et.direct) {
            case 0:
            case 2:
                if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                }
                break;
            case 1:
            case 3:
                if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                }
                break;
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.cyan);
                break;// 注意break
            case 1:// 我的坦克
                g.setColor(Color.yellow);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
    
            if (e.getKeyCode() == KeyEvent.VK_J) {
                if (this.hero.m.size() <= 5) {
                    // 判断玩家是否按下
                    this.hero.shote();
                }
    
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                // 判断是否击中
                for (int i = 0; i < hero.m.size(); i++) {
                    // 取出子弹
                    Shot myshot = hero.m.get(i);
                    // 判断子弹是否有效
                    if (myshot.islive) {
                        // 取出每一个坦克与他判断
                        for (int j = 0; j < enemy.size(); j++) {
                            // 取出坦克
                            Enemy et = enemy.get(j);
                            if (et.islive) {
                                this.hitTank(myshot, et);
                            }
                        }
                    }
                }
                this.repaint();
            }
        }
    }
    View Code

    怎么产生爆炸效果?

    炸弹好多可能都会爆炸,

     1.准备三张照片

    2.定义bom类

    3.在击中敌人坦克时把炸弹放入

    4.绘制

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        // 加入敌人的坦克(数量不确定用容器)
        Vector<Enemy> enemy = new Vector<Enemy>();
        // 定义炸弹集合
        Vector<Bom> bom = new Vector<Bom>();
        int ensize = 3;
        // 定义三张图片,才能组成一炸弹
        Image img1, img2, img3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出敌方的坦克
            for (int i = 0; i < ensize; i++) {
                Enemy et = enemy.get(i);
    
                if (et.islive) {
                    this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0);
                }
            }
            // 画出炸弹
            for (int i = 0; i < bom.size(); i++) {
                System.out.println("你妈个比比比" + bom.size());
                // 取出炸弹
                Bom b = bom.get(i);
                if (b.life > 6) {
                    g.drawImage(img1, b.x, b.y, 30, 30, this);
                } else if (b.life > 4) {
                    g.drawImage(img2, b.x, b.y, 30, 30, this);
                } else {
                    g.drawImage(img3, b.x, b.y, 30, 30, this);
                }
                b.lifeDown();
                if (b.life == 0) {
                    bom.remove(b);
                }
            }
            // 从弹夹中取出每一颗子弹
            for (int i = 0; i < this.hero.m.size(); i++) {
                Shot myshot = hero.m.get(i);
                // 画出自己的子弹 (一颗)
                if (myshot != null && myshot.islive == true) {
                    // g.setColor(Color.red);
                    g.draw3DRect(myshot.x, myshot.y, 3, 3, false);
                } else {
                    // 从m中删除子弹
                    hero.m.remove(myshot);// 为什么不用i
                }
            }
    
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 初始化敌方坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                Enemy et = new Enemy((i + 1) * 50, 0);
                // et.set
                enemy.add(et);
            }
            // 初始化图片
            img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
    
        }
    
        // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克
        public void hitTank(Shot s, Enemy et) {
            // 判断坦克的方向 主要是向上 向下 两种位置状态
            switch (et.direct) {
            case 0:
            case 2:
                if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹,
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            case 1:
            case 3:
                if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.cyan);
                break;// 注意break
            case 1:// 我的坦克
                g.setColor(Color.yellow);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
    
            if (e.getKeyCode() == KeyEvent.VK_J) {
                if (this.hero.m.size() <= 5) {
                    // 判断玩家是否按下
                    this.hero.shote();
                }
    
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                // 判断是否击中
                for (int i = 0; i < hero.m.size(); i++) {
                    // 取出子弹
                    Shot myshot = hero.m.get(i);
                    // 判断子弹是否有效
                    if (myshot.islive) {
                        // 取出每一个坦克与他判断
                        for (int j = 0; j < enemy.size(); j++) {
                            // 取出坦克
                            Enemy et = enemy.get(j);
                            if (et.islive) {
                                this.hitTank(myshot, et);
                            }
                        }
                    }
                }
                this.repaint();
            }
        }
    }
    View Code

    让敌人的坦克也可以自由的移动:

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        // 加入敌人的坦克(数量不确定用容器)
        Vector<Enemy> enemy = new Vector<Enemy>();
        // 定义炸弹集合
        Vector<Bom> bom = new Vector<Bom>();
        int ensize = 3;
        // 定义三张图片,才能组成一炸弹
        Image img1, img2, img3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出敌方的坦克
            for (int i = 0; i < ensize; i++) {
                Enemy et = enemy.get(i);
    
                if (et.islive) {
                    this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0);
                }
            }
            // 画出炸弹
            for (int i = 0; i < bom.size(); i++) {
                System.out.println("你妈个比比比" + bom.size());
                // 取出炸弹
                Bom b = bom.get(i);
                if (b.life > 6) {
                    g.drawImage(img1, b.x, b.y, 30, 30, this);
                } else if (b.life > 4) {
                    g.drawImage(img2, b.x, b.y, 30, 30, this);
                } else {
                    g.drawImage(img3, b.x, b.y, 30, 30, this);
                }
                b.lifeDown();
                if (b.life == 0) {
                    bom.remove(b);
                }
            }
            // 从弹夹中取出每一颗子弹
            for (int i = 0; i < this.hero.m.size(); i++) {
                Shot myshot = hero.m.get(i);
                // 画出自己的子弹 (一颗)
                if (myshot != null && myshot.islive == true) {
                    // g.setColor(Color.red);
                    g.draw3DRect(myshot.x, myshot.y, 3, 3, false);
                } else {
                    // 从m中删除子弹
                    hero.m.remove(myshot);// 为什么不用i
                }
            }
    
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 初始化敌方坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                Enemy et = new Enemy((i + 1) * 50, 0);
                // 启动敌人的坦克
                Thread t = new Thread(et);
                t.start();
                enemy.add(et);
            }
            // 初始化图片
            img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
    
        }
    
        // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克
        public void hitTank(Shot s, Enemy et) {
            // 判断坦克的方向 主要是向上 向下 两种位置状态
            switch (et.direct) {
            case 0:
            case 2:
                if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹,
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            case 1:
            case 3:
                if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.cyan);
                break;// 注意break
            case 1:// 我的坦克
                g.setColor(Color.yellow);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
    
            if (e.getKeyCode() == KeyEvent.VK_J) {
                if (this.hero.m.size() <= 5) {
                    // 判断玩家是否按下
                    this.hero.shote();
                }
    
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                // 判断是否击中
                for (int i = 0; i < hero.m.size(); i++) {
                    // 取出子弹
                    Shot myshot = hero.m.get(i);
                    // 判断子弹是否有效
                    if (myshot.islive) {
                        // 取出每一个坦克与他判断
                        for (int j = 0; j < enemy.size(); j++) {
                            // 取出坦克
                            Enemy et = enemy.get(j);
                            if (et.islive) {
                                this.hitTank(myshot, et);
                            }
                        }
                    }
                }
                this.repaint();
            }
        }
    }
    View Code

    怎么样平缓的移动?坦克在范围内移动

    package demo1;
    
    import java.util.*;
    
    public class Tank {
        int x;
        int y;
        int direct = 0;// 0 表示上 1表示右 2表示下 3表示左
        int speed = 5;
        int color = 0;
        boolean islive=true;
    //Shot p=null;   关键点是建立容器
        Vector<Shot> m=new Vector<Shot>();
        Shot p;
    //开火
    public void shote() {
        switch (this.direct) {
        //创建子弹加入弹夹
        case 0:
            p = new Shot(x + 10, y, 0);
            m.add(p);
            break;
        case 1:
            p = new Shot(x + 30, y + 10, 1);
            m.add(p);
            break;
        case 2:
            p = new Shot(x + 10, y + 30, 2);
            m.add(p);
            break;
        case 3:
            p = new Shot(x, y + 10, 3);
            m.add(p);
            break;
        }
        Thread s = new Thread(p);
        s.start();
    
    }
        public int getColor() {
            return color;
        }
    
        public void setColor(int color) {
            this.color = color;
        }
    
        public int getSpeed() {
            return speed;
        }
    
        public void setSpeed(int speed) {
            this.speed = speed;
        }
    
        public int getDirect() {
            return direct;
        }
    
        public void setDirect(int direct) {
            this.direct = direct;
        }
    
        public Tank(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        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 void moveup() {
            y -= speed;
        }
    
        public void moveright() {
            x += speed;
        }
    
        public void movedown() {
            y += speed;
        }
    
        public void moveleft() {
            x -= speed;
        }
    }
    class Hero extends Tank {
    
        public Hero(int x, int y) {
            super(x, y);
    
        }
    }
    
    class Enemy extends Tank implements Runnable{
    
        public Enemy(int x, int y) {
            super(x, y);
    //    this.ensize=ensize;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(true){
                try {
                    Thread.sleep(50);
                    
                } catch (Exception e) {
                    // TODO: handle exception
                }
    //            Math.random();
                switch(this.direct){
                case 0://向上走
                    
                    for(int i=0;i<20;i++){
                        if(y>0){
                            y-=speed;}
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        
                    }
                
                    break;
                case 1://向右走
                    for(int i=0;i<20;i++){
                        if(x<400){
                            x+=2*speed;}
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        
                    }
                    break;
                case 2:
                    for(int i=0;i<20;i++){
                        if(y<200){
                            y+=speed;}
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        
                    }
    
                    break;
                case 3:
                    for(int i=0;i<20;i++){
                        if(x>0){
                            x-=speed;}
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    
                    }
    
                    break;
                }
                //让坦克产生一个随机的方向
                this.direct=(int) (Math.random()*4);
                //判断敌人坦克是否死亡
                if(this.islive==false){
                    //让坦克死亡后退出
                    break;
                }
                
            }
        }
    }
    
        
    View Code

     让敌人的坦克也可以发射子弹:

    package demo1;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.*;
    
    /**
     * 设计坦克形状
     * 
     * @author 王志
     */
    public class Demo1 extends JFrame {
    
        Myframe mp = null;
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
        }
    
        public Demo1() {
            mp = new Myframe();
            Thread t = new Thread(mp);
            t.start();
            this.add(mp);
            this.addKeyListener(mp);
            this.setSize(400, 300);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    }
    
    // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状
    class Myframe extends JPanel implements KeyListener, Runnable {
        Hero hero;
    
        // 加入敌人的坦克(数量不确定用容器)
        Vector<Enemy> enemy = new Vector<Enemy>();
        // 定义炸弹集合
        Vector<Bom> bom = new Vector<Bom>();
        int ensize = 3;
        // 定义三张图片,才能组成一炸弹
        Image img1, img2, img3;
    
        public void paint(Graphics g) {// JPanel的画图功能
            g.fillRect(0, 0, 400, 300);
            this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1);
            // 画出敌方的坦克
            for (int i = 0; i < ensize; i++) {
                Enemy et = enemy.get(i);
    
                if (et.islive) {
                    this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0);
                    for(int j=0;j<et.m.size();j++){
                        //取出子弹
                        Shot  xx=et.m.get(j);
                        if(xx.islive){
                            g.draw3DRect(xx.x, xx.y, 3, 3, false);
                        }
                    }
                }
            }
            // 画出炸弹
            for (int i = 0; i < bom.size(); i++) {
                System.out.println("你妈个比比比" + bom.size());
                // 取出炸弹
                Bom b = bom.get(i);
                if (b.life > 6) {
                    g.drawImage(img1, b.x, b.y, 30, 30, this);
                } else if (b.life > 4) {
                    g.drawImage(img2, b.x, b.y, 30, 30, this);
                } else {
                    g.drawImage(img3, b.x, b.y, 30, 30, this);
                }
                b.lifeDown();
                if (b.life == 0) {
                    bom.remove(b);
                }
            }
            // 从弹夹中取出每一颗子弹
            for (int i = 0; i < this.hero.m.size(); i++) {
                Shot myshot = hero.m.get(i);
                // 画出自己的子弹 (一颗)
                if (myshot != null && myshot.islive == true) {
                    // g.setColor(Color.red);
                    g.draw3DRect(myshot.x, myshot.y, 3, 3, false);
                } else {
                    // 从m中删除子弹
                    hero.m.remove(myshot);// 为什么不用i
                }
            }
    
        }
    
        public Myframe() {
            hero = new Hero(200, 100);// 设定位置
            // 初始化敌方坦克
            // 初始化敌人的坦克
            for (int i = 0; i < ensize; i++) {
                // 生产坦克
                Enemy et = new Enemy((i + 1) * 50, 0);
                // 启动敌人的坦克
                Thread t = new Thread(et);
                t.start();
                //给敌人的坦克加子弹
                Shot s=new Shot(et.x+10,et.y+30,2);
                et.m.add(s);
                Thread t2=new Thread(s);
                t2.start();
                enemy.add(et);
            }
            // 初始化图片
            img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
            img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg"));
    
        }
    
        // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克
        public void hitTank(Shot s, Enemy et) {
            // 判断坦克的方向 主要是向上 向下 两种位置状态
            switch (et.direct) {
            case 0:
            case 2:
                if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹,
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            case 1:
            case 3:
                if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) {
                    // 击中 子弹死亡 敌人的坦克死亡
                    s.islive = false;
                    et.islive = false;
                    // 创建一颗炸弹
                    Bom b = new Bom(et.x, et.y);
                    // 放入到vector
                    bom.add(b);
                }
                break;
            }
        }
    
        // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            // 为坦克上色
            switch (type) {
            case 0:// 敌人的坦克
                g.setColor(Color.cyan);
                break;// 注意break
            case 1:// 我的坦克
                g.setColor(Color.yellow);
                break;
            }
            // 判断方向
            switch (direct) {
            case 0:// 向上
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y, x + 10, y + 15);
                break;
            case 1:// 向右
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:// 向下面
                    // 左边的矩形
                g.fill3DRect(x, y, 5, 30, false);
                // 右边的矩形
                g.fill3DRect(x + 15, y, 5, 30, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 10, 20, false);
                // 画出中间的圆
                g.fillOval(x + 5, y + 10, 10, 10);
                // 画出横线
                g.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:// 向左边
                    // 上边的矩形
                g.fill3DRect(x, y, 30, 5, false);
                // 下面的的矩形
                g.fill3DRect(x, y + 15, 30, 5, false);
                // 中间的矩形
                g.fill3DRect(x + 5, y + 5, 20, 10, false);
                // 画出中间的圆
                g.fillOval(x + 10, y + 5, 10, 10);
                // 画出横线
                g.drawLine(x, y + 10, x + 15, y + 10);
                break;
            }
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_W) {
                // W 表示上
                this.hero.setDirect(0);
                this.hero.moveup();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                // D 表示右
                this.hero.setDirect(1);
                this.hero.moveright();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                // S 表示下
                this.hero.setDirect(2);
                this.hero.movedown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                // A 表示左
                this.hero.setDirect(3);
                this.hero.moveleft();
            }
    
            if (e.getKeyCode() == KeyEvent.VK_J) {
                if (this.hero.m.size() <= 5) {
                    // 判断玩家是否按下
                    this.hero.shote();
                }
    
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void run() {// 重绘
            // TODO Auto-generated method stub
            // 每100毫秒进行重绘制
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    // TODO: handle exception
                }
                // 判断是否击中
                for (int i = 0; i < hero.m.size(); i++) {
                    // 取出子弹
                    Shot myshot = hero.m.get(i);
                    // 判断子弹是否有效
                    if (myshot.islive) {
                        // 取出每一个坦克与他判断
                        for (int j = 0; j < enemy.size(); j++) {
                            // 取出坦克
                            Enemy et = enemy.get(j);
                            if (et.islive) {
                                this.hitTank(myshot, et);
                            }
                        }
                    }
                }
                this.repaint();
            }
        }
    }
    View Code

    修改后能敌人随便打子弹:

  • 相关阅读:
    ueditor单独调用图片上传
    百度Ueditor多图片上传控件
    linux基础之vim编辑器
    linux基础之进阶命令二
    linux基础之基础命令一
    Python基础之PyCharm快捷键大全
    IT菜鸟之VTP应用项目
    IT菜鸟之总结(Du teacher)
    IT菜鸟之DHCP
    IT菜鸟之路由器基础配置(静态、动态、默认路由)
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10753476.html
Copyright © 2020-2023  润新知