上一篇中,我们已经成功的绘制了背景,用户飞机,敌机,子弹,那么这篇我们将检查碰撞,回收资源
1.碰撞
//检查子弹和敌船是否相撞
List<ZiDan> ziDanCop = new ArrayList<>();
for (int i = 0; i <mZiDanList.size() ; i++) {
ziDanCop.add(mZiDanList.get(i));
mZiDanList.get(i).CheckPengZhuang(ziDanCop);
}
//复制的子弹集合贴到当前集合中
mZiDanList = ziDanCop;
private boolean CheckPengZhuang(List<ZiDan> list){
for (int i = 0; i <mEnemyList.size() ; i++) {
Enemy e = mEnemyList.get(i);
if (x+mZiDuanBitMap.getWidth()<e.getX()||x>e.getX()+mEnemyBitMap.getWidth()/4){
continue;
}
if (y-e.getY()+mEnemyBitMap.getHeight()<=0){
mEnemyList.remove(i);
e.recycle();
list.remove(this);
recycle();
return true;
}
}
return false;
}
}
在这里,我们要移除碰撞的子弹和敌机,在集合循环中移除是不可取的,那么,就copy除一份子弹的集合,移除副本中的碰撞的子弹,这样就解决了一部分内存OOM的问题,在已出完后,将copy的集合交给党建子弹集合,完成移除动作。每个子弹都要与地基比较,一旦相撞,跳出循环。
解决了相撞的问题,还要考虑子弹移除屏幕外的问题,当最前的子弹还没移除的话就不在进行判断了,否则移除该子弹,继续往下判断
private void moveZiDan(){
//移除子弹
if (mZiDanList.size()==0){
return;
}
ZiDan zz = mZiDanList.get(0);
if (zz.getY() <-mZiDuanBitMap.getHeight()) {
mZiDanList.remove(0);
zz.recycle();
//递归
moveZiDan();
} else {
return;
}
}
采用了递归的思想,当相撞了,移除继续调用该方法,记住一点,永远是比较最前面的子弹.
在就是,敌机的判断,当敌机飞过屏幕,就要移除,这里我是要重新开始游戏
private void moveEmemy(){
//移除屏幕外的
if (mEnemyList.size()==0){
return;
}
float y = mEnemyList.get(0).getY();
if (y > getMeasuredHeight()) {
mEnemyList.get(0).recycle();
mEnemyList.remove(0);
reStart();
return;
//moveEmemy();
}
}
这个就没什么好说了,当当前集合中有敌机移除屏幕外就restart()
private void reStart() {
mEnemyList.clear();
mZiDanList.clear();
mUserPlane.reset();
bg.reset();
}
线程方法的代码
@Override
public void run() {
int flag = 0;
int flagE = 100;
while (!isGameover) {
//检查子弹和敌船是否相撞
List<ZiDan> ziDanCop = new ArrayList<>();
for (int i = 0; i <mZiDanList.size() ; i++) {
ziDanCop.add(mZiDanList.get(i));
mZiDanList.get(i).CheckPengZhuang(ziDanCop);
}
//复制的子弹集合贴到当前集合中
mZiDanList = ziDanCop;
//循环绘制图片,将图片贴到mPicture上
for (ImageErji imageErji : listErji) {
Bitmap b = imageErji.draw();
mCanvas.setBitmap(mPicture);
mCanvas.drawBitmap(b, imageErji.getX(), imageErji.getY(), mPaint);
}
creatEnemyPoint();
//循环绘制敌机
for (Enemy e : mEnemyList) {
Bitmap b = e.draw();
mCanvas.setBitmap(mPicture);
mCanvas.drawBitmap(b, e.getX(), e.getY(), mPaint);
e.setY(e.getY() + getMeasuredHeight()/flagE);
}
if (flag==2) {
creatZiDan();
}
//循环绘制子弹
for (ZiDan z : mZiDanList) {
Bitmap b = z.draw();
mCanvas.setBitmap(mPicture);
mCanvas.drawBitmap(b, z.getX(), z.getY(), mPaint);
z.setY(z.getY()-getMeasuredHeight()/50);
}
//移除屏幕外的子弹
moveZiDan();
//将mPicture贴到View上
Canvas ca = mHolder.lockCanvas(mRect);
ca.drawBitmap(mPicture, 0, 0, mPaint);
mHolder.unlockCanvasAndPost(ca);
//线程循环
flag++;
flagE--;
if (flagE<10){
flagE = 100;
}
if (flag>2){
flag = 0;
}
//移除屏幕外的敌机
moveEmemy();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
本次的飞机大战,逻辑还是比较复杂的,有兴趣的可以留言,项目地址:https://github.com/yzzAndroid/PlaneWar,谢谢,晚安。