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

我们上次实现了击毁敌人坦克的功能,但是敌人坦克秒消失,没带一点效果好像不给力,这次我们来做爆炸效果,主要分为四步: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();
        }
}

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

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值