疯狂ios之疯狂打飞机游戏(4)

博文视点 发布于 2014/04/25 08:52
阅读 357
收藏 0
iOS

13.14.10  添加游戏积分统计

现在,我们来给玩家加入游戏积分统计功能。步骤如下。

打开HelloWorldLayer.m文件,添加变量,实现代码如下(程序清单同上)。

// 分数值标签

CCLabelTTF* scoreLabel;

// 分数

int scoreValue;

 

 找到onEnter方法,在初始化子弹和敌机数组之后初始化分数值标签和分数,实现代码如下。

 

// 初始化分数标签

scoreLabel = [CCLabelTTF labelWithString:@"00" fontName:@"Arial" fontSize:20];

scoreLabel.position = ccp(60, screenHeight-20);

[self addChild:scoreLabel];

// 初始化分数值

scoreValue = 0;

修改检查碰撞方法collisionDetection:,当敌机生命值小于0时,增加计分算法,小飞机每个计分100,小飞碟每个计分500,实现代码如下(程序清单同上)。

if (enemyPlaneSprite.lifeValue <= 0) {

    // 删除敌机精灵

    [enemyPlaneArray removeObject:enemyPlaneSprite];

    [batchNode removeChild:enemyPlaneSprite cleanup:YES];

    // 播放爆炸动画

    [self bombAnimate:@"blast" :enemyPlaneSprite.position ];

    // 播放爆炸音效

    [[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];

    if ([enemyPlaneSprite.name isEqualToString:@"e1"])

        scoreValue += 500;

    else

        scoreValue += 100;

}

在私有分类中添加一个根据分数值实时更新相应的Label的方法,实现代码如下(程序清单同上)。

-(void) updateHUD:(ccTime)delta;

updateHUD:方法实时更新生命值和分数值,地图、分数、血条、时间进度条和技能条等都是HUDHead-UpDisplay)。实现代码如下(程序清单同上)。

-(void) updateHUD:(ccTime)delta{

    [scoreLabel setString:[NSString stringWithFormat:@"%i",scoreValue]];

}

修改update方法,实现代码如下(程序清单同上)。

-(void) update:(ccTime)delta{

    count++;

    [self updateBackground:delta];

    [self updateEnemySprite:delta];

    [self removeEnemySprite:delta];

    [self updateShooting:delta];

    [self removeBulletSprite:delta];

    self collisionDetection:delta];

    [self updateHUD:delta];

}

再次编译并运行游戏,控制玩家飞机发射子弹,子弹击中敌机,左上角的分数标签不断统计玩家得分。模拟器显示效果如图13.65所示。


13.65  统计积分效果

13.14.11  添加游戏大Boss

到现在为止,一个基本的打飞机游戏已经快完成了,让我们再给它添加一个大Boss,增加一点游戏的趣味性和难度吧!增加大Boss的具体步骤如下。

打开HelloWorldLayer.m文件,添加变量,实现代码如下(程序清单同上)。

FKSprite* bossSprite;

// Boss子弹精灵数组

CCArray* bossBulletArray;

// 是否启动BossBoss是否发射子弹

BOOL isStartBoss,isMoveBoss,isShootingBoss,isTemp;

在私有分类中添加3个方法,实现代码如下(程序清单同上)。

// Boss出动

-(void) startBossSprite:(ccTime)delta;

// Boss在屏幕上不规则移动

-(void) moveBossSprite:(ccTime)delta;

// Boss更新子弹

-(void) updateBossShooting:(ccTime)delta;

startBossSprite:方法用于启动Boss。实现代码如下(程序清单同上)。

-(void) startBossSprite:(ccTime)delta{

    if(isStartBoss && !isMoveBoss && !isTemp ){

        isTemp = YES;

        CCSpriteBatchNode *batchNode = (CCSpriteBatchNode*)[self getChildByTag: kTagBatchNode];

        FKSprite* enemyPlaneSprite;

        // 删除所有敌机

        CCARRAY_FOREACH(enemyPlaneArray, enemyPlaneSprite){

            [batchNode removeChild:enemyPlaneSprite cleanup:YES];

        }

        [enemyPlaneArray removeAllObjects];

        // Boss出动

        bossSprite= [FKSprite spriteWithSpriteFrameName:@"e-10.png"];

        bossSprite.position=ccp(screenWidth/2, screenHeight+bossSprite.contentSize.height);

        bossSprite.name = @"boss";

        bossSprite.lifeValue = 600;

        // 创建一个进度条精灵

        CCSprite* barSprite = [CCSprite spriteWithFile:@"planeHP.png"];

        // 初始化一个Boss血条对象

        bossSprite.enemyPlaneHP = [CCProgressTimer progressWithSprite:barSprite];

        // setPercentage:0.0f,表示并未加载任何资源,表现在画面上就是什么也看不见

        [bossSprite.enemyPlaneHP setPercentage:0.0f];

        // 由于图片大小关系,把scale设置成0.5,即缩小一半

        bossSprite.enemyPlaneHP.scale = 0.25;

        bossSprite.enemyPlaneHP.midpoint = ccp(0,0.5);

        bossSprite.enemyPlaneHP.barChangeRate = ccp(1, 0);

        bossSprite.enemyPlaneHP.type = kCCProgressTimerTypeBar;

        bossSprite.enemyPlaneHP.percentage = 100;

        [bossSprite.enemyPlaneHP setPosition:ccp(screenWidth/2, screenHeight/2)];

        bossSprite.enemyPlaneHP.visible = NO;

        [self addChild:bossSprite.enemyPlaneHP];

        // 血条更新量,100/10=10

        bossSprite.HPInterval = 100.0 / (float)bossSprite.lifeValue;

        // Boss精灵添加到敌机数组

        [enemyPlaneArray addObject:bossSprite];

        [batchNode addChild:bossSprite z:4];

        // Boss移动到屏幕上方

        id moveTo = [CCMoveTo actionWithDuration:2

            position:ccp(screenWidth/2, screenHeight-bossSprite.contentSize.height-20)];

        id action = [CCSequence actions:moveTo,[CCCallBlock actionWithBlock:^(){

            isMoveBoss = YES;

        }], nil] ;

        [bossSprite runAction:action];

        // 初始化Boss子弹数组

        bossBulletArray = [[CCArray alloc] init];

    }

}

startBossSprite:方法首先判断isStartBoss是否为“YES”(默认设置为“NO”,当玩家达到10000分时会将该值改为“YES”,则Boss启动),如果是,则先获取精灵表单,循环遍历敌机数组,从精灵表单中删除敌机,再从敌机数组中删除敌机(如果玩家是高手,希望玩到高难度的打飞机游戏,则可以不执行这段代码,游戏就会变成Boss和大量的小敌机轮番轰炸玩家)。接下来,创建一个Boss精灵,设置名称为“Boss”,生命值为600,为Boss创建一个血条,并计算血条比率。然后将Boss添加到敌机数组和精灵表单中。最后,执行一个moveBy动作,实际效果是Boss缓缓移动到屏幕上方,再将isMoveBoss设置为“YES”(Boss开始不规则动作)。记得初始化Boss子弹数组。

moveBossSprite:方法用于Boss启动后在屏幕上方做不规则运动。实现代码如下(程序清单同上)。

-(void) moveBossSprite:(ccTime)delta{

    if(isMoveBoss && !isShootingBoss){

        isShootingBoss = YES;

        // 不停地在屏幕上方左右移动

        id moveToLift = [CCMoveTo actionWithDuration:3

            position:ccp(screenWidth-bossSprite.contentSize.width/2,

            screenHeight-bossSprite.contentSize.height-20)];

        id moveRight = [CCMoveTo actionWithDuration:3

            position:ccp(0+bossSprite.contentSize.width/2,

            screenHeight-bossSprite.contentSize.height-20)];

        id delay = [CCDelayTime actionWithDuration:2];

        id sequence = [CCSequence actions:delay,moveToLift,moveRight, nil];

        // 注意:CCSequence中不能包含这个反复的动作。

        id repeat = [CCRepeatForever actionWithAction:sequence];

        [bossSprite runAction:repeat];

    }

}

moveBossSprite:方法首先判断isMoveBoss是否为“YES”,如果是,则说明Boss精灵已经启动,开始做不规则运动,并且设置isShootingBoss = YES,表示Boss可以发射子弹攻击玩家精灵。

updateBossShooting:方法用于Boss开始发射子弹。实现代码如下(程序清单同上)。

-(void) updateBossShooting:(ccTime)delta{

    if (isShootingBoss) {

        // Boss精灵坐标

        CGPoint pos = bossSprite.position;

        // Boss血条显示坐标位置

        bossSprite.enemyPlaneHP.position = ccp(pos.x, pos.y+55);

        if (!bossSprite.enemyPlaneHP.visible) {

            bossSprite.enemyPlaneHP.visible = YES;

        }

        // 获得精灵表单

        CCSpriteBatchNode *batchNode = (CCSpriteBatchNode*)[self getChildByTag:kTagBatchNode];

        if(count % 80 == 0)

        {

            // 创建代表子弹的精灵

            CCSprite* bossBulletSprite = [CCSprite spriteWithSpriteFrameName:@"bullet1.png"];

            // 设置子弹坐标

            CGPoint bulletPos = ccp(pos.x, pos.y - bossSprite.contentSize.height/2);

            bossBulletSprite.position = bulletPos;

            // 子弹精灵可见

            bossBulletSprite.visible = YES;

            // 子弹移动时间为0.5秒,移动距离为屏幕高度-子弹的y

            id moveBy=[CCMoveBy actionWithDuration:2.0f position:ccp(0,-screenHeight-bulletPos.y)];

            [bossBulletSprite runAction:moveBy];

            // 添加到Boss子弹数组中

            [bossBulletArray addObject:bossBulletSprite];

            // 将子弹精灵添加到精灵表单中

            [batchNode addChild:bossBulletSprite z:4];

        }

    }

}

updateBossShooting:首先判断isShootingBoss是否为“YES”,如果是,则设置Boss血条的坐标位置,并显示Boss血条。当count % 80 == 0时,发射Boss子弹,同时将Boss子弹添加到Boss子弹数组和精灵表单中。

修改collisionDetection:方法,重新判断玩家得分,并在爆炸效果之后添加代码,当玩家积分达到10000时,启动Boss。实现代码如下(程序清单同上)。

if ([enemyPlaneSprite.name isEqualToString:@"boss"]) {

    // 播放爆炸动画

    [self bombAnimate:@"bomb" :enemyPlaneSprite.position ];

    // 播放爆炸音效

    [[SimpleAudioEngine sharedEngine] playEffect:@"b1.mp3"];

    scoreValue += 5000;

    // 游戏胜利

    [self gameOver:@"游戏胜利!"];

}else{

    // 播放爆炸动画

    [self bombAnimate:@"blast" :enemyPlaneSprite.position ];

    // 播放爆炸音效

    [[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];

    if ([enemyPlaneSprite.name isEqualToString:@"e1"])

        scoreValue += 500;

    else

        scoreValue += 100;

    }

    // 10000分大Boss出动

    if (scoreValue >= 10000) {

        isStartBoss = YES;

        break;

    }

}

循环遍历完子弹数组之后,再添加遍历Boss子弹数组的代码,判断Boss子弹是否击中玩家飞机。实现代码如下(程序清单同上)。

// 判断Boss的子弹和玩家飞机的碰撞

    if (isShootingBoss) {

        CCSprite* bossBulletSprite;

        CCARRAY_FOREACH(bossBulletArray, bossBulletSprite){

            if(CGRectIntersectsRect(planeSprite.boundingBox,bossBulletSprite.boundingBox)){

                [planeSprite stopAllActions];

                // 删除玩家精灵

                [batchNode removeChild:planeSprite cleanup:YES];

                // 爆炸声音

                [[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];

                // 播放爆炸动画

                [self bombAnimate:@"blast" :planeSprite.position ];

                [self gameOver:@"游戏结束!"];

            }

        }

    }

修改updateEnemySprite:方法,判断是否更新敌机时增加!isStartBoss进行判断,意味着Boss出动后不再更新敌机。实现代码如下(程序清单同上)。

if (count % 30 == 0 && !isStartBoss)

if (count % 200 == 0 && !isStartBoss)

修改update方法,实现代码如下(程序清单同上)。

-(void) update:(ccTime)delta{

    count++;

    [self updateBackground:delta];

    [self updateEnemySprite:delta];

    [self removeEnemySprite:delta];

    [self updateShooting:delta];

    [self removeBulletSprite:delta];

    self collisionDetection:delta];

    [self updateHUD:delta];

    [self startBossSprite:delta];

    [self moveBossSprite:delta];

    [self updateBossShooting:delta];

}

再次编译并运行游戏,当玩家得分达到10000分时,Boss出动。模拟器显示效果如图13.66所示。

当玩家控制飞机攻击大Boss时,Boss的血条会随着生命值的减少而缩短。当Boss生命值为0时,播放爆炸效果,提示游戏胜利,模拟器显示效果如图13.67所示。

         

到此为止,这个打飞机游戏基本已经开发完成,包括背景滚动、飞机飞行动画、背景音乐、音效、大量敌机攻击、玩家射击、Boss大招、玩家积分统计和游戏设置等功能。记得有位软件大师曾经说过,游戏没有真正意义上的完结,因为开发者总是可以不断地完善它,赋予游戏更多的新元素和新玩法。比如,我们可以让敌机俯冲时发射炮弹、敌机做不规则运动、Boss出动时伴随大量小飞机、玩家飞机增加大炸弹功能、每过一关玩家飞机增加一架等。这个游戏我们暂时就介绍到这里,本节我们的目的是学习使用cocos2d制作一个简单的游戏。游戏虽然简单,但是包括的知识点很多,希望大家好好掌握,将来制作出更加有趣和完美的游戏。

加载中
0
devstore
devstore

开发者的福利到了,devstore将拿出十万,悬赏写评测报告的开发者,参与就有奖。                                               

返回顶部
顶部