Java-Java基础06之坦克大战v3.0及机票售票系统

主要内容有:Java多线程的应用,使用Java的多线程技术开发坦克大战v3.0,实现控制我方坦克、敌方坦克以及子弹的各自生命状态、颜色变化、方向、运行轨迹及爆炸效果等;开发一个可多窗口同时售票的机票售票系统。

多线程Demo10_1.java

/*
* 演示如果通过继续Thread来开发线程
*/
/*
* 在java中一个类要当作线程来使用有两种方法:
* 1.继承Thread类,并重写run函数
* 2.实现Runable接口,并重写run函数
*/
package com.test1;
public class Demo10_1 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //创建一个Cat对象
        Cat cat=new Cat();
        //启动线程,会导致run函数的运行
        cat.start();
    }
}
class Cat extends Thread
{
    int times=0;
        //重写run函数
    public void run()
    {
        while(true)
        {
            try {
        //休眠一秒
                Thread.sleep(1000);
        //1000表示1000毫秒,sleep就会让该线程进入Blocked状态,并释放资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            times++;
            System.out.println("Hello World "+times);
            if(times==10)
            {
                //退出
                break;
            }
        }
    }
}

多线程Demo10_2.java

/*
* 功能:用Runable接口实现多线程
*/
package com.test2;
public class Demo10_2 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //注意启动-------------------------------------------
        Dog dog=new Dog();
        //创建一个Thread对象
        Thread t=new Thread(dog);
        t.start();
        //---------------------------------------------------
    }
}
class Dog implements Runnable
{
    int times=0;
    public void run()
    {
        while(true)
        {
            try {
        //休眠一秒
                Thread.sleep(1000);
            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                e.printStackTrace();
            }
            times++;
            System.out.println("Hello "+times);
            if(times==10)
            {
        //退出
                break;
            }
        }
    }
}

多线程Demo10_3.java

/*
* 功能:两个线程同时运行的案例
*/
package com.test3;
public class Demo10_3 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //创建一个Pig和一个bird
        Pig pig=new Pig(10);
        Bird bird=new Bird(10);
        Thread t1=new Thread(pig);
        Thread t2=new Thread(bird);
        t1.start();
        t2.start();
    }
}
//打印
class Pig implements Runnable
{
    int n=0;
    int times=0;
    public Pig(int n)
    {
        this.n=n;
    }
    public void run()
    {
        while(true)
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            times++;
            System.out.println("pig是一个线程,在输出第"+times+"个Hello World!");
            if(times==n)
            {
                break;
            }
        }
    }
}
                //算数学题
class Bird implements Runnable
{
    int n=0;
    int res=0;                 //结果
    int times=0;
    public Bird(int n)
    {
        this.n=n;
    }
    public void run()
    {
        while(true)
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            res+=(++times);
            System.out.println("当前结果是:"+res);
            if(times==n)
            {
                System.out.println("最后结果是:"+res);
                break;
            }
        }
    }
}

坦克大战v3.0_ MyTankGame2.java

/*
* 功能:坦克大战v3.0
* 1.画出坦克
* 2.我的坦克可以上下左右移动
* 3.敌人的坦克及子弹可以自由移动
*/
package com.test4;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class MyTankGame2 extends JFrame{
    MyPanel mp=null;
        //构造函数
    public MyTankGame2()
    {
        mp=new MyPanel();
        //启动mp线程
        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);
    }
    public static void main(String[] args) {
        MyTankGame2 mtg=new MyTankGame2();
    }
}
        //我的面板
class MyPanel extends JPanel implements KeyListener,Runnable
{
        //定义一个我的坦克
    Hero hero=null;
        //定义敌人的坦克组
    Vector<EnemyTank>ets=new Vector<EnemyTank>();
    int enSize=3;
        //构造函数
    public MyPanel()
    {
        hero=new Hero(100,200);
        //初始化敌人的坦克
        for(int i=0;i<enSize;i++)
        {
        //创建一个辆敌人的坦克对象
            EnemyTank et=new EnemyTank((i+1)*50,0);
            et.setColor(0);        //设置颜色
            et.setDirect(2);
        //加入
            ets.add(et);
        }
    }
        //重写paint函数
    public void paint(Graphics g)
    {
        super.paint(g);         //这句不能少
        g.fillRect(0,0,400,300);        //设置游戏面板背景
        //画出自己的坦克
        this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
        //画出子弹
        if(hero.s!=null&&hero.s.isLive==true)
        {
            g.setColor(Color.WHITE);        //设置子弹颜色
            g.fill3DRect(hero.s.x, hero.s.y, 3, 3, true);
        }
        //画出敌人的坦克
        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 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, 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);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+2, y+1, x+2, y+4);
                g.drawLine(x+5, y+1, x+5, y+4);
                g.drawLine(x+8, y+1, x+8, y+4);
                g.drawLine(x+11, y+1, x+11, y+4);
                g.drawLine(x+14, y+1, x+14, y+4);
                g.drawLine(x+17, y+1, x+17, y+4);
                g.drawLine(x+20, y+1, x+20, y+4);
                g.drawLine(x+23, y+1, x+23, y+4);
                g.drawLine(x+26, y+1, x+26, y+4);
                g.drawLine(x+2, y+16, x+2, y+19);
                g.drawLine(x+5, y+16, x+5, y+19);
                g.drawLine(x+8, y+16, x+8, y+19);
                g.drawLine(x+11, y+16, x+11, y+19);
                g.drawLine(x+14, y+16, x+14, y+19);
                g.drawLine(x+17, y+16, x+17, y+19);
                g.drawLine(x+20, y+16, x+20, y+19);
                g.drawLine(x+23, y+16, x+23, y+19);
                g.drawLine(x+26, y+16, x+27, y+19);
                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, y+10);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+2, y+1, x+2, y+4);
                g.drawLine(x+5, y+1, x+5, y+4);
                g.drawLine(x+8, y+1, x+8, y+4);
                g.drawLine(x+11, y+1, x+11, y+4);
                g.drawLine(x+14, y+1, x+14, y+4);
                g.drawLine(x+17, y+1, x+17, y+4);
                g.drawLine(x+20, y+1, x+20, y+4);
                g.drawLine(x+23, y+1, x+23, y+4);
                g.drawLine(x+26, y+1, x+26, y+4);
                g.drawLine(x+2, y+16, x+2, y+19);
                g.drawLine(x+5, y+16, x+5, y+19);
                g.drawLine(x+8, y+16, x+8, y+19);
                g.drawLine(x+11, y+16, x+11, y+19);
                g.drawLine(x+14, y+16, x+14, y+19);
                g.drawLine(x+17, y+16, x+17, y+19);
                g.drawLine(x+20, y+16, x+20, y+19);
                g.drawLine(x+23, y+16, x+23, y+19);
                g.drawLine(x+26, y+16, x+27, y+19);
                break;
            case 2:         //向下
        //画出我的坦克(到时封装成一个函数)
        //1.画出左边的矩形
                g.fill3DRect(x, y, 5, 30,false);
        //2.画出右边的矩形
                g.fill3DRect(x+15, y, 5, 30,false);
        //3.画出中间矩形
                g.fill3DRect(x+5, y+5, 10, 20,false);
        //4.画出中间的圆形
                g.fillOval(x+5, y+10, 10, 10);
        //5.画出线
                g.drawLine(x+10, y+15, x+10, y+30);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+1, y+2, x+4, y+2);
                g.drawLine(x+1, y+5, x+4, y+5);
                g.drawLine(x+1, y+8, x+4, y+8);
                g.drawLine(x+1, y+11, x+4, y+11);
                g.drawLine(x+1, y+14, x+4, y+14);
                g.drawLine(x+1, y+17, x+4, y+17);
                g.drawLine(x+1, y+20, x+4, y+20);
                g.drawLine(x+1, y+23, x+4, y+23);
                g.drawLine(x+1, y+27, x+4, y+27);
                g.drawLine(x+16, y+2, x+19, y+2);
                g.drawLine(x+16, y+5, x+19, y+5);
                g.drawLine(x+16, y+8, x+19, y+8);
                g.drawLine(x+16, y+11, x+19, y+11);
                g.drawLine(x+16, y+14, x+19, y+14);
                g.drawLine(x+16, y+17, x+19, y+17);
                g.drawLine(x+16, y+20, x+19, y+20);
                g.drawLine(x+16, y+23, x+19, y+23);
                g.drawLine(x+16, y+27, x+19, y+27);
                break;
            case 3:         //向上
        //画出我的坦克(到时封装成一个函数)
        //1.画出左边的矩形
                g.fill3DRect(x, y, 5, 30,false);
        //2.画出右边的矩形
                g.fill3DRect(x+15, y, 5, 30,false);
        //3.画出中间矩形
                g.fill3DRect(x+5, y+5, 10, 20,false);
        //4.画出中间的圆形
                g.fillOval(x+5, y+10, 10, 10);
        //5.画出线
                g.drawLine(x+10, y+15, x+10, y);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+1, y+2, x+4, y+2);
                g.drawLine(x+1, y+5, x+4, y+5);
                g.drawLine(x+1, y+8, x+4, y+8);
                g.drawLine(x+1, y+11, x+4, y+11);
                g.drawLine(x+1, y+14, x+4, y+14);
                g.drawLine(x+1, y+17, x+4, y+17);
                g.drawLine(x+1, y+20, x+4, y+20);
                g.drawLine(x+1, y+23, x+4, y+23);
                g.drawLine(x+1, y+27, x+4, y+27);
                g.drawLine(x+16, y+2, x+19, y+2);
                g.drawLine(x+16, y+5, x+19, y+5);
                g.drawLine(x+16, y+8, x+19, y+8);
                g.drawLine(x+16, y+11, x+19, y+11);
                g.drawLine(x+16, y+14, x+19, y+14);
                g.drawLine(x+16, y+17, x+19, y+17);
                g.drawLine(x+16, y+20, x+19, y+20);
                g.drawLine(x+16, y+23, x+19, y+23);
                g.drawLine(x+16, y+27, x+19, y+27);
                break;
        }
    }
    @Override
    public void keyPressed(KeyEvent e)         //键按下处理
    {
        //a表示向左,s表示向上,w表示向上,d表示向右
        if(e.getKeyCode()==KeyEvent.VK_D)
        {
            this.hero.setDirect(0);        //设置我的坦克的方向,向右
            this.hero.moveRight();
        }
        else if(e.getKeyCode()==KeyEvent.VK_A)
        {
            this.hero.setDirect(1);        //向左
            this.hero.moveLeft();
        }
        else if(e.getKeyCode()==KeyEvent.VK_S)
        {
            this.hero.setDirect(2);        //向下
            this.hero.moveDown();
        }
        else if(e.getKeyCode()==KeyEvent.VK_W)
        {
            this.hero.setDirect(3);        //向上
            this.hero.moveUp();
        }
        if(e.getKeyCode()==KeyEvent.VK_J)
        {
        //判断玩家是否按下j
        //发射子弹
            this.hero.shotEnemy();
        }
        //重绘Panel
        this.repaint();
    }
    @Override
    public void keyReleased(KeyEvent e)
    {
    }
    @Override
    public void keyTyped(KeyEvent e)
    {
    }
    @Override
    public void run() {
        //每隔100毫秒去重绘
        while(true)
        {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                e.printStackTrace();
            }
        //重绘
            this.repaint();
        }
    }
}

Members.java

package com.test4;
    //子弹类
class Shot implements Runnable
{
    int x,y,direct;
    int speed=3;
    //是否还活着
    boolean isLive=true;
    public Shot(int x,int y,int direct)
    {
        this.x=x;
        this.y=y;
        this.direct=direct;
    }
    @Override
    public void run() {
    //子弹向前跑动
        while(true)
        {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
            switch(direct)
            {
                case 0:     //子弹向右
                    x+=speed;
                    break;
                case 1:     //子弹向左
                    x-=speed;
                    break;
                case 2:     //子弹向下
                    y+=speed;
                    break;
                case 3:     //子弹向上
                    y-=speed;
                    break;
            }
            System.out.println("子弹坐标x="+x+" y="+y);
    //子弹何时死亡
    //判断该子弹是否碰到边缘
            if(x<0||x>400||y<0||y>300)
            {
                this.isLive=false;
                break;
            }
        }
    }
}
    //坦克类
class Tank
{
    //表示坦克的横坐标
    int x=0;
    //坦克纵坐标
    int y=0;
    //坦克方向
    int direct=0;    //0表示右,1表示左,2表示下,3表示上
    //坦克的速度
    int speed=1;
    //坦克的颜色
    int color;
    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 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 Tank(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}
    //敌人的坦克
class EnemyTank extends Tank
{
    public EnemyTank(int x,int y)
    {
        super(x,y);
    }
}
    //我的坦克
class Hero extends Tank
{
    //子弹
    Shot s=null;
    public Hero(int x,int y)
    {
        super(x,y);    //用父类的构造函数初始化子类的成员变量
    }
    //发射子弹
    public void shotEnemy()
    {
        switch(this.direct)
        {
            case 0:     //坦克朝右
                s=new Shot(x+30,y+9,0);
                break;
            case 1:     //坦克朝左
                s=new Shot(x,y+9,1);
                break;
            case 2:     //坦克朝下
                s=new Shot(x+9,y+30,2);
                break;
            case 3:     //坦克朝上
                s=new Shot(x+9,y,3);
                break;
        }
    //启动子弹线程
        Thread t=new Thread(s);     //因为子弹类Shot实现了Runnable接口
        t.start();
    }
    //坦克向上移动
    public void moveUp()
    {
        y-=speed;
    }
    //坦克向右移动
    public void moveRight()
    {
        x+=speed;
    }
    //坦克向下移动
    public void moveDown()
    {
        y+=speed;
    }
    //坦克向左移动
    public void moveLeft()
    {
        x-=speed;
    }
}

线程的注意事项_Demo11_1.java

/*
* 功能:演示使用线程的注意事项
*/
package com.test1;
public class Demo11_1 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //启动线程
        Cat cat1=new Cat();
        cat1.start();
        //cat1.start();//一个线程类只能启动一次
        Dog dog1=new Dog();
        Thread t=new Thread(dog1);
        Thread t2=new Thread(dog1);
        t.start();
        t2.start();
        //t2.start();//一个线程类只能启动一次
        //结论:不管是通过继承Thread,还是通实现Runnable接口创建线程,
        //它们的一个对象只能启动一次,否则就会有异常抛出。
    }
}
//猫类
class Cat extends Thread
{
    public void run()
    {
        System.out.println("11");
    }
}
//狗类
class Dog implements Runnable
{
    @Override
    public void run() {
        System.out.println("22");
    }
}

机票售票系统Demo11_2.java

/*
* 功能:模拟一个机票售票系统:有三个售票点,
* 在1天卖出2000张票。(注是一共有2000张票)
*/
package com.test2;
public class Demo11_2 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //定义三个售票窗口
        TicketWindow tw1=new TicketWindow();
        //TicketWindow tw2=new TicketWindow();
        //TicketWindow tw3=new TicketWindow();
        //创建三个线程
        Thread t1=new Thread(tw1);
        Thread t2=new Thread(tw1);
        Thread t3=new Thread(tw1);
        //启动三个卖票线程
        t1.start();
        t2.start();
        t3.start();
    }
}
        //售票窗口类
class TicketWindow implements Runnable
{
        //一共两千张票
    private static int nums=2000;
        //private Dog myDog=new Dog();
    public void run()
    {
        while(true)
        {
        //认为if else 要保证其原子性[同步代码块]
        //synchronized(myDog) //对象锁,保证同步安全
            synchronized(this)
            {
        //先判断是否还有票
                if(nums>0)
                {
                    System.out.println(Thread.currentThread().getName()+" 在售出第"+nums+"张票");
                    nums--;
        //出票速度是1秒出一张
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else
                {
        //售票结束
                    break;
                }
            }
        }
    }
}
class Dog
{
}

坦克大战v3.0优化版_ MyTankGame2.java

/*
* 功能:坦克大战v3.0
* 1.画出坦克
* 2.我的坦克可以上下左右移动
* 3.可以发射子弹,子弹连发(最多5颗)
* 4.当子弹击中敌人坦克时,敌人坦克消失(爆炸效果)
* 5.我被击中时,显示爆炸效果
*/
package com.test3;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
public class MyTankGame2 extends JFrame{
    MyPanel mp=null;
        //构造函数
    public MyTankGame2()
    {
        mp=new MyPanel();
        //启动mp线程
        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);
    }
    public static void main(String[] args) {
        MyTankGame2 mtg=new MyTankGame2();
    }
}
        //我的面板
class MyPanel extends JPanel implements KeyListener,Runnable
{
        //定义一个我的坦克
    Hero hero=null;
        //定义敌人的坦克组
    Vector<EnemyTank>ets=new Vector<EnemyTank>();
        //定义炸弹集合
    Vector<Bomb>bombs=new Vector<Bomb>();
        //初始化敌人坦克数量
    int enSize=3;
        //定义三张图片,组成成一颗炸弹
    Image image1=null;
    Image image2=null;
    Image image3=null;
        //构造函数
    public MyPanel()
    {
        hero=new Hero(100,200);
        //初始化敌人的坦克
        for(int i=0;i<enSize;i++)
        {
        //创建一个辆敌人的坦克对象
            EnemyTank et=new EnemyTank((i+1)*50,0);
            et.setColor(0);        //设置颜色
            et.setDirect(2);
        //启动敌人的坦克
            Thread t=new Thread(et);
            t.start();
        //给敌人坦克添加一颗子弹
            Shot s=new Shot(et.x+10,et.y+30,2);
        //把子弹加入给敌人
            et.ss.add(s);
        //启动子弹敌人的子弹线程
            Thread t2=new Thread(s);
            t2.start();
        //加入
            ets.add(et);
        }
        try{
            image1=ImageIO.read(new File("./src/bomb_1.gif"));
            image2=ImageIO.read(new File("./src/bomb_2.gif"));
            image3=ImageIO.read(new File("./src/bomb_3.gif"));
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        //初始化图片
        //image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
        //image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
        //image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));
    }
        //重写paint函数
    public void paint(Graphics g)
    {
        super.paint(g);         //这句不能少
        g.fillRect(0,0,400,300);        //设置游戏面板背景
        //画出自己的坦克
        if(hero.isLive)
        {
            this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
        }
        //从ss中取出每一颗子弹,并画出
        for(int i=0;i<this.hero.ss.size();i++)         //设置子弹连发
        {
        //取出一颗子弹
            Shot myShot=hero.ss.get(i);
        //画出一颗子弹
            if(hero.s!=null&&hero.s.isLive==true)
            {
                g.setColor(Color.WHITE);        //设置子弹颜色
                g.fill3DRect(myShot.x, myShot.y, 3, 3, true);
            }
            if(myShot.isLive==false)        //如果子弹已经死亡
            {
        //从ss中删除掉该子弹
                hero.ss.remove(myShot);
            }
        }
        //画出炸弹
        for(int i=0;i<bombs.size();i++)
        {
        //System.out.println("bombs.size()="+bombs.size());
        //取出炸弹
            Bomb b=bombs.get(i);
            if(b.life>6)
            {
                g.drawImage(image1, b.x, b.y, 30, 30, this);
            }
            else if(b.life>4)
            {
                g.drawImage(image2, b.x, b.y, 30, 30, this);
            }
            else
            {
                g.drawImage(image3, b.x, b.y, 30, 30, this);
            }
        //让b的生命值减小
            b.lifeDown();
            if(b.life==0)        //如果炸弹生命值为0时,就把炸弹从集合中去掉
            {
                bombs.remove(b);
            }
        }
        //画出敌人的坦克
        for(int i=0;i<ets.size();i++)
        {
            EnemyTank et=ets.get(i);
            if(et.isLive)         //画出还是活的坦克
            {
                this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0);
        //再画出敌人的子弹
                for(int j=0;j<et.ss.size();j++)
                {
        //取出子弹
                    Shot enemyShot=et.ss.get(j);
                    if(enemyShot.isLive)
                    {
                        g.setColor(Color.PINK);        //设置子弹颜色
                        g.fill3DRect(enemyShot.x, enemyShot.y, 3, 3, true);        //画子弹
                    }
                    else         //如果敌人的坦克死亡了就从Vector去掉
                    {
                        et.ss.remove(enemyShot);
                    }
                }
            }
        }
    }
        //判断我的子弹是否击中敌人的坦克
    public void hitEnemyTank()
    {
        //在这run函数里判断子弹是否击中敌人坦克
        for(int i=0;i<hero.ss.size();i++)
        {
        //取出子弹
            Shot myShot=hero.ss.get(i);
            if(myShot.isLive)        //判断子弹是否还是活的或有效
            {
        //取出每个坦克,与它判断
                for(int j=0;j<ets.size();j++)
                {
        //取出坦克
                    EnemyTank et=ets.get(j);
                    if(et.isLive)
                    {
                        this.hitTank(myShot,et);
                    }
                }
            }
        }
    }
        //敌人的子弹是否击中我
    public void hitMe()
    {
        //取出每一个敌人的坦克
        for(int i=0;i<this.ets.size();i++)
        {
        //取出坦克
            EnemyTank et=ets.get(i);
        //取出每一颗子弹
            for(int j=0;j<et.ss.size();j++)
            {
        //取出子弹
                Shot enemyShot=et.ss.get(j);
                this.hitTank(enemyShot, hero);
            }
        }
    }
        //1.写一个专门判断子弹是否击中敌人坦克的函数
    public void hitTank(Shot s,Tank et)
    {
        //判断该坦克的方向
        switch(et.direct)
        {
        //如果敌人坦克的方向是右或者是左
            case 0:
            case 1:
                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;        //敌人坦克死亡
        //创建一颗炸弹
                    Bomb b=new Bomb(et.x,et.y);
        //把炸弹放入到Vector
                    bombs.add(b);
                }
        //如果敌人坦克的方向是上或者是下
            case 2:
            case 3:
                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;        //敌人坦克死亡
        //创建一颗炸弹
                    Bomb b=new Bomb(et.x,et.y);
        //把炸弹放入到Vector
                    bombs.add(b);
                }
        }
    }
        //画出坦克的函数(扩展)
    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, 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);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+2, y+1, x+2, y+4);
                g.drawLine(x+5, y+1, x+5, y+4);
                g.drawLine(x+8, y+1, x+8, y+4);
                g.drawLine(x+11, y+1, x+11, y+4);
                g.drawLine(x+14, y+1, x+14, y+4);
                g.drawLine(x+17, y+1, x+17, y+4);
                g.drawLine(x+20, y+1, x+20, y+4);
                g.drawLine(x+23, y+1, x+23, y+4);
                g.drawLine(x+26, y+1, x+26, y+4);
                g.drawLine(x+2, y+16, x+2, y+19);
                g.drawLine(x+5, y+16, x+5, y+19);
                g.drawLine(x+8, y+16, x+8, y+19);
                g.drawLine(x+11, y+16, x+11, y+19);
                g.drawLine(x+14, y+16, x+14, y+19);
                g.drawLine(x+17, y+16, x+17, y+19);
                g.drawLine(x+20, y+16, x+20, y+19);
                g.drawLine(x+23, y+16, x+23, y+19);
                g.drawLine(x+26, y+16, x+27, y+19);
                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, y+10);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+2, y+1, x+2, y+4);
                g.drawLine(x+5, y+1, x+5, y+4);
                g.drawLine(x+8, y+1, x+8, y+4);
                g.drawLine(x+11, y+1, x+11, y+4);
                g.drawLine(x+14, y+1, x+14, y+4);
                g.drawLine(x+17, y+1, x+17, y+4);
                g.drawLine(x+20, y+1, x+20, y+4);
                g.drawLine(x+23, y+1, x+23, y+4);
                g.drawLine(x+26, y+1, x+26, y+4);
                g.drawLine(x+2, y+16, x+2, y+19);
                g.drawLine(x+5, y+16, x+5, y+19);
                g.drawLine(x+8, y+16, x+8, y+19);
                g.drawLine(x+11, y+16, x+11, y+19);
                g.drawLine(x+14, y+16, x+14, y+19);
                g.drawLine(x+17, y+16, x+17, y+19);
                g.drawLine(x+20, y+16, x+20, y+19);
                g.drawLine(x+23, y+16, x+23, y+19);
                g.drawLine(x+26, y+16, x+27, y+19);
                break;
            case 2:         //向下
        //画出我的坦克(到时封装成一个函数)
        //1.画出左边的矩形
                g.fill3DRect(x, y, 5, 30,false);
        //2.画出右边的矩形
                g.fill3DRect(x+15, y, 5, 30,false);
        //3.画出中间矩形
                g.fill3DRect(x+5, y+5, 10, 20,false);
        //4.画出中间的圆形
                g.fillOval(x+5, y+10, 10, 10);
        //5.画出线
                g.drawLine(x+10, y+15, x+10, y+30);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+1, y+2, x+4, y+2);
                g.drawLine(x+1, y+5, x+4, y+5);
                g.drawLine(x+1, y+8, x+4, y+8);
                g.drawLine(x+1, y+11, x+4, y+11);
                g.drawLine(x+1, y+14, x+4, y+14);
                g.drawLine(x+1, y+17, x+4, y+17);
                g.drawLine(x+1, y+20, x+4, y+20);
                g.drawLine(x+1, y+23, x+4, y+23);
                g.drawLine(x+1, y+27, x+4, y+27);
                g.drawLine(x+16, y+2, x+19, y+2);
                g.drawLine(x+16, y+5, x+19, y+5);
                g.drawLine(x+16, y+8, x+19, y+8);
                g.drawLine(x+16, y+11, x+19, y+11);
                g.drawLine(x+16, y+14, x+19, y+14);
                g.drawLine(x+16, y+17, x+19, y+17);
                g.drawLine(x+16, y+20, x+19, y+20);
                g.drawLine(x+16, y+23, x+19, y+23);
                g.drawLine(x+16, y+27, x+19, y+27);
                break;
            case 3:         //向上
        //画出我的坦克(到时封装成一个函数)
        //1.画出左边的矩形
                g.fill3DRect(x, y, 5, 30,false);
        //2.画出右边的矩形
                g.fill3DRect(x+15, y, 5, 30,false);
        //3.画出中间矩形
                g.fill3DRect(x+5, y+5, 10, 20,false);
        //4.画出中间的圆形
                g.fillOval(x+5, y+10, 10, 10);
        //5.画出线
                g.drawLine(x+10, y+15, x+10, y);
        //画齿轮
                g.setColor(Color.darkGray);
                g.drawLine(x+1, y+2, x+4, y+2);
                g.drawLine(x+1, y+5, x+4, y+5);
                g.drawLine(x+1, y+8, x+4, y+8);
                g.drawLine(x+1, y+11, x+4, y+11);
                g.drawLine(x+1, y+14, x+4, y+14);
                g.drawLine(x+1, y+17, x+4, y+17);
                g.drawLine(x+1, y+20, x+4, y+20);
                g.drawLine(x+1, y+23, x+4, y+23);
                g.drawLine(x+1, y+27, x+4, y+27);
                g.drawLine(x+16, y+2, x+19, y+2);
                g.drawLine(x+16, y+5, x+19, y+5);
                g.drawLine(x+16, y+8, x+19, y+8);
                g.drawLine(x+16, y+11, x+19, y+11);
                g.drawLine(x+16, y+14, x+19, y+14);
                g.drawLine(x+16, y+17, x+19, y+17);
                g.drawLine(x+16, y+20, x+19, y+20);
                g.drawLine(x+16, y+23, x+19, y+23);
                g.drawLine(x+16, y+27, x+19, y+27);
                break;
        }
    }
    @Override
    public void keyPressed(KeyEvent e)         //键按下处理
    {
        //a表示向左,s表示向上,w表示向上,d表示向右
        if(e.getKeyCode()==KeyEvent.VK_D)
        {
            this.hero.setDirect(0);        //设置我的坦克的方向,向右
            this.hero.moveRight();
        }
        else if(e.getKeyCode()==KeyEvent.VK_A)
        {
            this.hero.setDirect(1);        //向左
            this.hero.moveLeft();
        }
        else if(e.getKeyCode()==KeyEvent.VK_S)
        {
            this.hero.setDirect(2);        //向下
            this.hero.moveDown();
        }
        else if(e.getKeyCode()==KeyEvent.VK_W)
        {
            this.hero.setDirect(3);        //向上
            this.hero.moveUp();
        }
        if(e.getKeyCode()==KeyEvent.VK_J)
        {
        //判断玩家是否按下j
        //发射子弹
            if(this.hero.ss.size()<=4)        //连发子弹小于5
            {
                this.hero.shotEnemy();
            }
        }
        //重绘Panel
        this.repaint();
    }
    @Override
    public void keyReleased(KeyEvent e)
    {
    }
    @Override
    public void keyTyped(KeyEvent e)
    {
    }
    @Override
    public void run() {
        //每隔100毫秒去重绘
        while(true)
        {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                e.printStackTrace();
            }
        //2.什么地方调用-判断子弹是否击中敌人坦克的函数
            this.hitEnemyTank();        //子弹是否击中敌人坦克
            this.hitMe();        //敌人的坦克是否击中我了
        //重绘
            this.repaint();
        }
    }
}

Members.java

package com.test3;
import java.util.*;
        //炸弹类
class Bomb
{
        //定义炸弹的坐标
    int x,y;
        //炸弹的生命
    int life=9;
        //炸弹是否还是活的
    boolean isLive=true;
    public Bomb(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
        //减少炸弹生命值
    public void lifeDown()
    {
        if(life>0)
        {
            life--;
        }
        else
        {
            this.isLive=false;
        }
    }
}
        //子弹类
class Shot implements Runnable
{
    int x,y,direct;
    int speed=3;
        //是否还活着
    boolean isLive=true;
    public Shot(int x,int y,int direct)
    {
        this.x=x;
        this.y=y;
        this.direct=direct;
    }
    @Override
    public void run() {
        //子弹向前跑动
        while(true)
        {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                e.printStackTrace();
            }
            switch(direct)
            {
                case 0:         //子弹向右
                    x+=speed;
                    break;
                case 1:         //子弹向左
                    x-=speed;
                    break;
                case 2:         //子弹向下
                    y+=speed;
                    break;
                case 3:         //子弹向上
                    y-=speed;
                    break;
            }
        //System.out.println("子弹坐标x="+x+" y="+y);
        //子弹何时死亡
        //判断该子弹是否碰到边缘
            if(x<0||x>400||y<0||y>300)
            {
                this.isLive=false;
                break;
            }
        }
    }
}
        //坦克类
class Tank
{
        //表示坦克的横坐标
    int x=0;
        //坦克纵坐标
    int y=0;
        //坦克方向
    int direct=0;        //0表示右,1表示左,2表示下,3表示上
        //坦克的速度
    int speed=1;
        //坦克的颜色
    int color;
    boolean isLive=true;
    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 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 Tank(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}
        //敌人的坦克,把敌人坦克做成线程类
class EnemyTank extends Tank implements Runnable
{
        //boolean isLive=true;//是否死亡
    int times=0;
        //定义一个向量,可以存放敌人的子弹
    Vector<Shot>ss=new Vector<Shot>();
        //敌人添加子弹,应当在刚刚创建坦克和敌人的坦克子弹是死亡之后
    public EnemyTank(int x,int y)
    {
        super(x,y);
    }
    @Override
    public void run() {
        //让敌人坦克坐标不停的变化
        while(true)
        {
            switch(this.direct)
            {
                case 0:         //说明坦克正在向右移动
                    for(int i=0;i<30;i++)
                    {
                        if(x<400)        //限制坦克不移出边界
                        {
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            x+=speed;
                        }
                    }
                    break;
                case 1:         //说明坦克正在向左移动
                    for(int i=0;i<30;i++)
                    {
                        if(x>0)        //限制坦克不移出边界
                        {
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            x-=speed;
                        }
                    }
                    break;
                case 2:         //说明坦克正在向下移动
                    for(int i=0;i<30;i++)
                    {
                        if(y<280)        //限制坦克不移出边界
                        {
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            y+=speed;
                        }
                    }
                    break;
                case 3:         //说明坦克正在向上移动
                    for(int i=0;i<30;i++)
                    {
                        if(y>0)        //限制坦克不移出边界
                        {
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            y-=speed;
                        }
                    }
                    break;
            }
            this.times++;
            if(times%2==0)        //3秒时间到了
            {
                if(isLive)
                {
                    if(ss.size()<5)
                    {
                        Shot s=null;
        //添加子弹
                        switch(direct)
                        {
                            case 0:         //坦克朝右
        //创建一颗子弹
                                s=new Shot(x+30,y+9,0);
        //把子弹加入集合向量
                                ss.add(s);
                                break;
                            case 1:         //坦克朝左
                                s=new Shot(x,y+9,1);
        //把子弹加入向量
                                ss.add(s);
                                break;
                            case 2:         //坦克朝下
                                s=new Shot(x+9,y+30,2);
        //把子弹加入向量
                                ss.add(s);
                                break;
                            case 3:         //坦克朝上
                                s=new Shot(x+9,y,3);
        //把子弹加入向量
                                ss.add(s);
                                break;
                        }
        //启动子弹线程
                        Thread t=new Thread(s);
                        t.start();
                    }
                }
            }
        //让坦克随机产生一个新的方向
            this.direct=(int)(Math.random()*4);
        //判断敌人坦克是否死亡
            if(this.isLive==false)
            {
        //让坦克死亡后退出线程
                break;
            }
        }
    }
}
        //我的坦克
class Hero extends Tank
{
        //子弹
    Shot s=null;
        //定义一个用于存放子弹的集合
    Vector<Shot> ss=new Vector<Shot>();
    public Hero(int x,int y)
    {
        super(x,y);        //用父类的构造函数初始化子类的成员变量
    }
        //发射子弹
    public void shotEnemy()
    {
        switch(this.direct)
        {
            case 0:         //坦克朝右
        //创建一颗子弹
                s=new Shot(x+30,y+9,0);
        //把子弹加入集合向量
                ss.add(s);
                break;
            case 1:         //坦克朝左
                s=new Shot(x,y+9,1);
        //把子弹加入向量
                ss.add(s);
                break;
            case 2:         //坦克朝下
                s=new Shot(x+9,y+30,2);
        //把子弹加入向量
                ss.add(s);
                break;
            case 3:         //坦克朝上
                s=new Shot(x+9,y,3);
        //把子弹加入向量
                ss.add(s);
                break;
        }
        //启动子弹线程
        Thread t=new Thread(s);         //因为子弹类Shot实现了Runnable接口
        t.start();
    }
        //坦克向上移动
    public void moveUp()
    {
        y-=speed;
    }
        //坦克向右移动
    public void moveRight()
    {
        x+=speed;
    }
        //坦克向下移动
    public void moveDown()
    {
        y+=speed;
    }
        //坦克向左移动
    public void moveLeft()
    {
        x-=speed;
    }
}

版权所有,转载请注明出处 luowei.github.io.