刚才在写坦克大战的时候,碰到一个很奇怪的问题。在一个无限循环的线程中,调用某个方法,方法里面的if(...)条件判断语句并没有起到作用。但是,在if里面打印出的判断语句仍然能正确显示true or false。
在纠结了一段时间后,幡然醒悟,是局部变量和全局变量的赋值引起的,只需改动一个地方就可以啦。代码如下:
主线程中:
@Override
public void run() {
//当游戏运行时进行的处理操作
while(...){
try{
synchronized (GameThread.class) {
....
//这里省略了其他不重要的东西。
bullet.explode();
....
}
Thread.sleep(1000/FPS);
}
catch(Exception e){
e.printStackTrace();
}
finally{
...
}
}
}
bullet类:
public class Bullet {
//用于记录切换图片的次数
private int i = 0;
//X轴坐标
private float x;
//Y轴坐标
private float y;
//记录当前调用的时间
private long curTime ;
//记录上一次被调用的时间
private long aftTime ;
//子弹状态
private BulletState state;
public void explode(Bitmap b,Canvas canvas,int actionCount)
{
int top = 0;
int bottom = 45;
int width = b.getWidth()/actionCount;
int curLeft = width;
curTime = System.currentTimeMillis();
if(!state.equals(BulletState.Explode) || curTime - aftTime < 80)
return;
if(b.getWidth() - curLeft > width)//
{
curLeft = width * i;
Rect src = new Rect(curLeft,top,curLeft + width,bottom);
i++;
RectF des = new RectF(x,y-20,x+bottom,y+25);
canvas.drawBitmap(b,src,des,null);
aftTime = System.currentTimeMillis();
}
else
{
setState(BulletState.None);
}
}
}
以上,基本是所有相关的代码了。在explode方法中,程序是执行不到else语句的。永远都只会进入if(...)。不知道有没有人和我犯一样的错误。
其实,问题出在int curLeft = width和 curLeft = width * i;这里,当初写的时候,把它想成了在循环中使用了(在循环外,定义一个局部变量,然后在循环内使用。)。而当,每次线程调用此方法时,curLeft 都会等于width,所以 每次都会满足if语句里面的条件,但i的值一直在增加,所以curLeft = width * i又会造成curLeft的值朝着预想的方向增加。
既然知道原因了,那么程序更改如下:
public void explode(Bitmap b,Canvas canvas,int actionCount)
{
int top = 0;
int bottom = 45;
int width = b.getWidth()/actionCount;
int curLeft = width * i;
curTime = System.currentTimeMillis();
if(!state.equals(BulletState.Explode) || curTime - aftTime < 80)
return;
if(b.getWidth() - curLeft > width)//
{
//curLeft = width * i;
Rect src = new Rect(curLeft,top,curLeft + width,bottom);
i++;
RectF des = new RectF(x,y-20,x+bottom,y+25);
canvas.drawBitmap(b,src,des,null);
aftTime = System.currentTimeMillis();
}
else
{
setState(BulletState.None);
}
}
将int curLeft = width 改成 int curLeft = width * i;且注释掉 curLeft = width * i;即可。
心得:在线程中,将全局变量和局部变量混合使用时,应多注意相关变量的初始化等问题。