飞机大战(下篇:逻辑)

上一篇中,我们已经成功的绘制了背景,用户飞机,敌机,子弹,那么这篇我们将检查碰撞,回收资源

这里写图片描述

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,谢谢,晚安。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值