实验五数据结构综合应用 20162310

分析系统架构

Sprite精灵类

  • ISprite精灵类是所有类的父类

CombatAircraft战斗机类

  • 首先确保战斗机完全位于Canvas范围内,每隔7帧发射单发黄色子弹。
protected void beforeDraw(Canvas canvas, Paint paint, GameView gameView) {
        if(!isDestroyed()){
            //确保战斗机完全位于Canvas范围内
            validatePosition(canvas);

            //每隔7帧发射子弹
            if(getFrame() % 7 == 0){
                fight(gameView);
            }
        }

战斗机如果被击中,执行爆炸效果,具体来说,首先隐藏战斗机,然后创建爆炸效果,爆炸用28帧渲染完成,爆炸效果完全渲染完成后,爆炸效果消失。然后战斗机会进入闪烁模式,战斗机闪烁一定次数后销毁。

        //在飞机当前还没有被击中时,要判断是否将要被敌机击中
        if(!collide){
            List<EnemyPlane> enemies = gameView.getAliveEnemyPlanes();
            for(EnemyPlane enemyPlane : enemies){
                Point p = getCollidePointWithOther(enemyPlane);
                if(p != null){
                 //p为战斗机与敌机的碰撞点,如果p不为null,则表明战斗机被敌机击中
                    explode(gameView);
                    break;
                }
            }
        }

        //beginFlushFrame初始值为0,表示没有进入闪烁模式
        //如果beginFlushFrame大于0,表示要在第如果beginFlushFrame帧进入闪烁模式
        if(beginFlushFrame > 0){
            long frame = getFrame();
            //如果当前帧数大于等于beginFlushFrame,才表示战斗机进入销毁前的闪烁状态
            if(frame >= beginFlushFrame){
                if((frame - beginFlushFrame) % flushFrequency == 0){
                    boolean visible = getVisibility();
                    setVisibility(!visible);
                    flushTime++;
                    if(flushTime >= maxFlushTime){
                        //如果战斗机闪烁的次数超过了最大的闪烁次数,那么销毁战斗机
                        destroy();
                        //Game.gameOver();
                    }
                }
            }

AutolSprite

  • AutoISprite是一个走直线的精灵,其位置只能直上直下,且向下为正。在y轴方向移动speed像素,检查Sprite是否超出了Canvas的范围,如果超出,则销毁Sprite。其中RectF为坐标类,判断位置。
//检查Sprite是否超出了Canvas的范围,如果超出,则销毁Sprite
            RectF canvasRecF = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
            RectF spriteRecF = getRectF();
            if(!RectF.intersects(canvasRecF, spriteRecF)){
                destroy();

敌机类EnemyPlane

  • 敌机类,从上向下沿直线运动。设置一个敌机的抗打击能力(通俗说是血量)和打一个敌机的得分。敌机在绘制完成后要判断是否被子弹打中,判断方法为判断敌机在坐标轴上是否与子弹相交。若敌机已经没有能量了,执行爆炸效果。
//创建爆炸效果,爆炸由敌机中心点开始爆炸
        float centerX = getX() + getWidth() / 2;   // 得到敌机中心坐标
        float centerY = getY() + getHeight() / 2;
        Bitmap bitmap = gameView.getExplosionBitmap();
        Explosion explosion = new Explosion(bitmap);
        explosion.centerTo(centerX, centerY);
        gameView.addSprite(explosion);

        //创建爆炸效果完成后,向GameView中添加得分并销毁敌机
        gameView.addScore(value);
        destroy();

爆炸类Explosion

  • 爆炸效果类Explosion,可以显示动态的爆炸效果。爆炸效果由14个片段组成,每个爆炸片段绘制2帧。当绘制完所有的爆炸片段后,销毁爆炸效果。得到绘制完整爆炸效果需要的帧数,即28帧。
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView) {
        if(!isDestroyed()){
            if(getFrame() % explodeFrequency == 0){
                //level自加1,用于绘制下个爆炸片段
                level++;
                if(level >= segment){
                    //当绘制完所有的爆炸片段后,销毁爆炸效果
                    destroy();
                }
            }
        }

编译、运行、测试系统

第一步,将码云上的代码克隆下来

第二步,编译,运行

修改系统

分析数据结构,排序,查找算法的应用

List线性表

  • 主要使用了线性表来获取处于活动状态的敌机、存储所有的精灵等。
public List<EnemyPlane> getAliveEnemyPlanes(){
    List<EnemyPlane> enemyPlanes = new ArrayList<EnemyPlane>();
    for(ISprite s : sprites){
        if(!s.isDestroyed() && s instanceof EnemyPlane){
            EnemyPlane sprite = (EnemyPlane)s;
            enemyPlanes.add(sprite);
        }
    }
    return enemyPlanes;
}
  • 将所有敌机存储在list中,并进行for循环查找是否与战斗机有交点。若有交点则战斗机摧毁。
 List<EnemyPlane> enemies = gameView.getAliveEnemyPlanes();
            for(EnemyPlane enemyPlane : enemies){
                Point p = getCollidePointWithOther(enemyPlane);
                if(p != null){
                    //p为战斗机与敌机的碰撞点,如果p不为null,则表明战斗机被敌机击中
                    explode(gameView);
                    break;
                }
            }
posted @ 2017-12-17 22:26  林臻  阅读(475)  评论(0编辑  收藏  举报