Java之详解坦克大战游戏(五)

来源:互联网 发布:安卓手机网络修复工具 编辑:程序博客网 时间:2024/05/22 01:56

我们上次实现了击毁敌人坦克的功能,但是敌人坦克秒消失,没带一点效果好像不给力,这次我们来做爆炸效果,主要分为四步:1.先准备三张图片 2.定义Bomb类,在击中敌人坦克时,把炸弹放入Vector 4.绘制。首先我们要以图片连续闪现来体现爆炸效果,如下:
这里写图片描述这里写图片描述这里写图片描述
首先需要定义一个爆炸类,到Members.java文件定义

//炸弹类(没有坐标改变,不用做成线程)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;        }    }}

爆炸效果还是在面板显示,我们到MyPanel定义

    //......    //定义炸弹集合    Vector<Bomb> bombs=new Vector<Bomb>();    //定义三张图片,三张图片才能组成一颗炸弹    Image image1=null;    Image image2=null;    Image image3=null;

(把三张图片复制粘贴到src目录下)
再到构造函数初始化

public MyPanel(){        //......//初始化图片,三张图片才能组成一颗炸弹image1=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));        image2=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));        image3=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));}

画炸弹的话当然还是在paint方法

public void paint(Graphics g){    //......    //画出炸弹    for(int i=0;i<bombs.size();i++)    {        //取出炸弹        Bomb b=bombs.get(i);        //给炸弹不同        if(b.life>6)        {//下列画图片的数据还是经测试比较好看才写出来的,可以自己琢磨一下            g.drawImage(image1, b.x, b.y, 30,30,this);        }else if(b.life>3)        {            g.drawImage(image2, b.x, b.y, 30,30,this);        }        else        {            g.drawImage(image3, b.x, b.y, 30,30,this);        }        //让b的生命值减小        b.lifeDown();        //如果炸弹生命值为0,就把该炸弹从bombs向量去掉        if(b.life==0)        {            bombs.remove(b);        }    }}

爆炸效果当然是击中敌人坦克时才出现的,所以我们要到hitTank方法里写段代码

//写一个函数专门判断子弹是否会击中敌人坦克    public void hitTank(Shot s,EnemyTank 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;                //创建一颗炸弹,放入Vector                Bomb b=new Bomb(et.x, et.y);                //放入Vector                bombs.add(b);            }        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;                //创建一颗炸弹,放入Vector                Bomb b=new Bomb(et.x, et.y);                //放入Vector                bombs.add(b);            }        }    }

这里写图片描述
这时就能看到爆炸效果了..接下来,我们来实现如何让敌人坦克自由移动和能发子弹…
首先得把敌人的坦克做成线程类,实现Runnable接口
(这里我们首先都想想坦克可以自由移动但是不要让它乱跑,比如跑到我们看不到的地方,所以我们一开始就得设定边界,一开始我们是setSize(400,300))

//敌人的坦克,把敌人做成线程类class EnemyTank extends Tank implements Runnable{    //...    int times=0;//作为连发子弹设下的标志  (下面将用到)    public void run() {        while(true)        {            switch(this.direct)            {            case 0:                //说明坦克正在向上移动                for(int i=0;i<30;i++)//30可以改成其他数,这里是控制坦克移动距离                {   //保证坦克不出边界   (下面思路相同)                    if(y>0)                    {                        y-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 1:                //向右                for(int i=0;i<30;i++)                {                    if(x<400)                    {                        x+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 2:                //向下                for(int i=0;i<30;i++)                {                    if(y<300)                    {                        y+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 3:                //向左                for(int i=0;i<30;i++)                {                    if(x>0)                    {                        x-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                   break;            }            //让坦克随机产生一个新的方向            this.direct=(int)(Math.random()*4);//随机产生0-3的数            //判断敌人坦克是否死亡            if(this.isLive==false)            {                //让坦克死亡后退出线程                break;            }        }    }}

老规矩,下一步要做的就是启动线程,到MyPanel类的构造函数中

public MyPanel(){        //初始化敌人的坦克        for(int i=0;i<enSize;i++)        {            //...            //启动敌人的坦克            Thread t = new Thread(et);            t.start();        }}

这时运行程序,敌人坦克就可以自由移动了
这里写图片描述
接下来的任务是让敌人的坦克可以自由发射子弹

class EnemyTank extends Tank implements Runnable{//.......public void run() {        while(true)        {            switch(this.direct)            {            case 0:                //说明坦克正在向上移动                for(int i=0;i<30;i++)                {   //保证坦克不出边界                    if(y>0)                    {                        y-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 1:                //向右                for(int i=0;i<30;i++)                {                    if(x<400)                    {                        x+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 2:                //向下                for(int i=0;i<30;i++)                {                    if(y<300)                    {                        y+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 3:                //向左                for(int i=0;i<30;i++)                {                    if(x>0)                    {                        x-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                   break;            }            this.times++;              //判断是否给坦克加入新的子弹            if(times%2==0)            {                if(isLive)                {                    if(ss.size()<5)// 够不够五颗子弹                    {                        Shot s=null;                        //没有子弹                        //添加                        switch(direct)                        {                        case 0:                            //创建一颗子弹                            s=new Shot(x+10, y,0);                            //把子弹加入向量                            ss.add(s);                            break;                        case 1:                            s=new Shot(x+30,y+10,1);                            ss.add(s);                            break;                        case 2:                            s=new Shot(x+10,y+30,2);                            ss.add(s);                            break;                        case 3:                            s=new Shot(x,y+10,3);                            ss.add(s);                            break;                        }                        //启动子弹线程                        Thread t=new Thread(s);                        t.start();                    }                }            }            //让坦克随机产生一个新的方向            this.direct=(int)(Math.random()*4);            //判断敌人坦克是否死亡            if(this.isLive==false)            {                //让坦克死亡后退出线程                break;            }        }    }}}

接下来到MyPanel类构造函数

public MyPanel(){        hero =new Hero(100,100); //坦克的初始位置(10,10)            //...                   //给敌人坦克添加一颗子弹            Shot s=new Shot(et.x+10,et.y+30,2);            //加入给敌人坦克            et.ss.add(s);            Thread t2=new Thread(s);            t2.start();}

画子弹我们选择到画敌人坦克的函数

        //画出敌人的坦克        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.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);                    }                    else                    {//如果敌人坦克死亡就从Vector去掉                        et.ss.remove(enemyShot);                    }                }            }        }

运行程序,效果如图
这里写图片描述
接下来继续完成,我们被敌人坦克击中还不会死亡,所以我们要做的是让敌人的子弹击中我们坦克我们也会死亡..为了程序的可读性良好,我们需要改动一些代码的位置,到MyPanel类的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);                }            }        }    }

再到MyPanel类添加两个函数,一个函数是把我们剪切的代码放进去

//敌人的子弹是否击中我    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);            }        }    }    //判断我的子弹是否击中敌人的坦克    public void hitEnemyTank()    {        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);                    }                }            }        }    }

这个时候就会报错了,我们只需再做一下改动:

hitTank的参数类型EnemyTank改为Tank
Members.java文件中EnemyTank的boolean isLive=true;属性可以删掉了
然后到Tank类添加属性boolean isLive=true;
这样敌人子弹对我们的攻击就有效了
这里写图片描述
最后,还是扔一堆源代码
TankGame3.java

package com.TankGame3;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Vector;public class TankGame3 extends JFrame{    MyPanel mp =null;    public static void main(String[] args)     {        TankGame3 tankgame3 = new TankGame3();    }    public TankGame3()    {        mp=new MyPanel();        Thread t = new Thread(mp);        t.start();        this.addKeyListener(mp);//注册监听        this.setVisible(true);        this.setSize(400, 300);        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.add(mp);    }}//我的面板class MyPanel extends Panel implements KeyListener,Runnable{//子弹要看到,要不停的重绘,paint函数每隔段时间久更新,重绘是在paint函数发生的,所以MyPanel要实现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,100); //坦克的初始位置(10,10)        //初始化敌人的坦克        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);        }        //初始化图片,三张图片才能组成一颗炸弹        image1=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));        image2=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));        image3=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));    }    //重新paint    public void paint(Graphics g)    {        super.paint(g);        g.fillRect(0, 0, 1200, 900);  //填充使背景变为黑色           //从ss中取出每颗子弹,并画出        for(int i=0;i<hero.ss.size();i++)        {            Shot myShot = hero.ss.get(i);            //画出一颗子弹            if(myShot!=null && myShot.isLive == true)            {                g.setColor(Color.yellow);                g.draw3DRect(myShot.x, myShot.y, 1, 1, false);            }            if(myShot.isLive==false)            {                //从ss中删除该子弹                hero.ss.remove(myShot);            }        }        //画出炸弹        for(int i=0;i<bombs.size();i++)        {            //取出炸弹            Bomb b=bombs.get(i);            if(b.life>6)            {                g.drawImage(image1, b.x, b.y, 30,30,this);            }else if(b.life>3)            {                g.drawImage(image2, b.x, b.y, 30,30,this);            }            else            {                g.drawImage(image3, b.x, b.y, 30,30,this);            }            //让b的生命值减小            b.lifeDown();            //如果炸弹生命值为0,就把该炸弹从bombs向量去掉            if(b.life==0)            {                bombs.remove(b);            }        }        //画出自己的坦克        if(hero.isLive)        {            this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);        }        //画出敌人的坦克        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.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);                    }                    else                    {//如果敌人坦克死亡就从Vector去掉                        et.ss.remove(enemyShot);                    }                }            }        }    }    //敌人的子弹是否击中我    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);            }        }    }    //判断我的子弹是否击中敌人的坦克    public void hitEnemyTank()    {        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 hitTank(Shot s,Tank 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;                //创建一颗炸弹,放入Vector                Bomb b=new Bomb(et.x, et.y);                //放入Vector                bombs.add(b);            }        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;                //创建一颗炸弹,放入Vector                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:            //画出我的坦克(到时再封装成一个函数)            //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);            break;        case 1://炮筒向右            //画出上面矩形            g.fill3DRect(x, y, 30, 5,false);            //2.画出右边矩形            g.fill3DRect(x, y+15, 30, 5,false);            //3.画出中间矩形            g.fill3DRect(x+5, y+5, 20, 10,false);            //4.画出圆形            g.fillOval(x+10, y+5, 10, 10);            //5.画直线            g.drawLine(x+15, y+10, x+30, y+10);            break;        case 2://炮筒向下            //画出上面矩形            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);            break;        case 3://炮筒向左            //画出上面矩形            g.fill3DRect(x, y, 30, 5,false);            //2.画出右边矩形            g.fill3DRect(x, y+15, 30, 5,false);            //3.画出中间矩形            g.fill3DRect(x+5, y+5, 20, 10,false);            //4.画出圆形            g.fillOval(x+10, y+5, 10, 10);            //5.画直线            g.drawLine(x+15, y+10, x, y+10);            break;        }    }/*实现KeyListener接口的方法*/    //键入某个键时调用此方法。     public void keyTyped(KeyEvent e) {    }    //释放某个键时调用此方法    public void keyReleased(KeyEvent e) {    }    //按下某个键时调用此方法: a代表向左,w代表向上,d代表向右,s代表向下    public void keyPressed(KeyEvent e) {        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();        }        //判断玩家是否按下j键        if(e.getKeyCode() == KeyEvent.VK_J)        {            //开火            if(this.hero.ss.size()<=4)  //子弹最多连发5颗            {            this.hero.shotEnemy();            }        }        this.repaint();//调用repaint()函数,来重绘页面    }    public void run() {        //每隔100毫秒来重绘        while(true)        {            try {                Thread.sleep(100);            } catch (Exception e) {                // TODO: handle exception            }            this.hitEnemyTank();            //判断敌人的子弹是否击中我            this.hitMe();            //重绘            this.repaint();        }    }}

Members.java

package com.TankGame3;import java.util.Vector;//炸弹类(没有坐标改变,不用做成线程)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 Tank{    //表示坦克的横坐标    int x=0;    //表示坦克的纵坐标    int y=0;    //坦克方向     //0表示上,1表示右,2表示下,3表示左    int direct=0;    int color;//坦克的颜色    boolean isLive=true;    public int getColor() {        return color;    }    public void setColor(int color) {        this.color = color;    }    public int getDirect() {        return direct;    }    public void setDirect(int derect) {        this.direct = derect;    }    //坦克速度    int speed=1;    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);    }    public void run() {        while(true)        {            switch(this.direct)            {            case 0:                //说明坦克正在向上移动                for(int i=0;i<30;i++)                {   //保证坦克不出边界                    if(y>0)                    {                        y-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 1:                //向右                for(int i=0;i<30;i++)                {                    if(x<400)                    {                        x+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 2:                //向下                for(int i=0;i<30;i++)                {                    if(y<300)                    {                        y+=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                break;            case 3:                //向左                for(int i=0;i<30;i++)                {                    if(x>0)                    {                        x-=speed;                    }                    try {                        Thread.sleep(50);                    } catch (Exception e) {                        e.printStackTrace();                        // TODO: handle exception                    }                }                   break;            }            this.times++;              //判断是否给坦克加入新的子弹            if(times%2==0)            {                if(isLive)                {                    if(ss.size()<5)// 够不够五颗子弹                    {                        Shot s=null;                        //没有子弹                        //添加                        switch(direct)                        {                        case 0:                            //创建一颗子弹                            s=new Shot(x+10, y,0);                            //把子弹加入向量                            ss.add(s);                            break;                        case 1:                            s=new Shot(x+30,y+10,1);                            ss.add(s);                            break;                        case 2:                            s=new Shot(x+10,y+30,2);                            ss.add(s);                            break;                        case 3:                            s=new Shot(x,y+10,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>();    Shot s=null;    public Hero(int x,int y)    {        super(x,y);    }    //开火    public void shotEnemy()    {        switch (this.direct) //子弹的方向        {//s只是代号而已,指向谁就谁,不要理解它是同一个子弹        case 0:            //创建一颗子弹            s=new Shot(x+10, y,0);            //把子弹加入向量            ss.add(s);            break;        case 1:            s=new Shot(x+30,y+10,1);            ss.add(s);            break;        case 2:            s=new Shot(x+10,y+30,2);            ss.add(s);            break;        case 3:            s=new Shot(x,y+10,3);            ss.add(s);            break;        }        //启动子弹线程        Thread t = new Thread(s);        t.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;    int y;    int direct;//子弹的方向    int speed=1; //子弹速度    boolean isLive=true;//子弹是否活着    public Shot(int x,int y,int direct)    {        this.x=x;        this.y=y;        this.direct=direct;    }    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;                break;            }            //判断子弹是否碰到边缘            if( x<0 || x>400 || y<0 || y>300)            {                this.isLive=false;                break;            }        }    }}
2 0