坦克大战编程

坦克大战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

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

原文地址:https://www.cnblogs.com/helloworld2019/p/10753476.html