我们上次实现了击毁敌人坦克的功能,但是敌人坦克秒消失,没带一点效果好像不给力,这次我们来做爆炸效果,主要分为四步: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();
}
}
这时运行程序,敌人坦克就可以自由移动了
接下来的任务是让敌人的坦克可以自由发射子弹