Cocos2D:塔防游戏制作之旅(十四)

时间:2023-02-09 12:01:39

塔之战:炮塔的攻击

炮塔就位了?检查.敌人前进中?再次检查 - 它们看起来就是如此!看起来到了击溃这些家伙的时候了!这里我们将智能置入炮塔的代码中去.

每一个炮塔检查是否有敌人在其攻击范围.(炮塔一次只能攻击一个敌人.猫猪注)如果有,炮塔将开始向敌人开火直到两件事之一发生:敌人移出攻击范围或者敌人被摧毁.炮塔接着开始寻找其他欠扁的家伙 :]

将它们放到一起,新建新炮塔!你已经有一个防御基础了!

因为敌人和炮塔类相互依赖彼此,你不得不首先更新它们类的头文件,去避免你在修改实现代码时Xcode发生显示错误.

首先,打开Tower.h文件,然后完成以下修改:

// Add some instance variables
BOOL attacking;
Enemy *chosenEnemy;

// Add method definition
-(void)targetKilled;

打开Enemy.h文件修改如下:

// Add instance variable
NSMutableArray *attackedBy;

// Add method definitions
-(void)getAttacked:(Tower *)attacker;
-(void)gotLostSight:(Tower *)attacker;
-(void)getDamaged:(int)damage;

下一步,回到Tower.m中做如下修改:

// Import Enemy header at the top of the file:
#import "Enemy.h"

// Add the following methods
-(void)attackEnemy
{
    [self schedule:@selector(shootWeapon) interval:fireRate];
}

-(void)chosenEnemyForAttack:(Enemy *)enemy
{
    chosenEnemy = nil;
    chosenEnemy = enemy;
    [self attackEnemy];
    [enemy getAttacked:self];
}

-(void)shootWeapon
{
    CCSprite * bullet = [CCSprite spriteWithFile:@"bullet.png"];
    [theGame addChild:bullet];
    [bullet setPosition:mySprite.position];
    [bullet runAction:[CCSequence actions:
                       [CCMoveTo actionWithDuration:0.1 position:chosenEnemy.mySprite.position],
                       [CCCallFunc actionWithTarget:self selector:@selector(damageEnemy)],
                       [CCCallFuncN actionWithTarget:self selector:@selector(removeBullet:)], nil]];


}

-(void)removeBullet:(CCSprite *)bullet
{
    [bullet.parent removeChild:bullet cleanup:YES];
}

-(void)damageEnemy
{
    [chosenEnemy getDamaged:damage];
}

-(void)targetKilled
{
    if(chosenEnemy)
        chosenEnemy =nil;

    [self unschedule:@selector(shootWeapon)];
}

-(void)lostSightOfEnemy
{
    [chosenEnemy gotLostSight:self];
    if(chosenEnemy)
        chosenEnemy =nil; 

    [self unschedule:@selector(shootWeapon)];
}

最后,替换之前版本只能怪留下的空白update方法:

-(void)update:(ccTime)dt {
    if (chosenEnemy){

        //We make it turn to target the enemy chosen
        CGPoint normalized = ccpNormalize(ccp(chosenEnemy.mySprite.position.x-mySprite.position.x,
                                              chosenEnemy.mySprite.position.y-mySprite.position.y));
        mySprite.rotation = CC_RADIANS_TO_DEGREES(atan2(normalized.y,-normalized.x))+90;

        if(![theGame circle:mySprite.position withRadius:attackRange 
             collisionWithCircle:chosenEnemy.mySprite.position collisionCircleRadius:1])
        {
            [self lostSightOfEnemy];
        }
    } else {
        for(Enemy * enemy in theGame.enemies)
        {
            if([theGame circle:mySprite.position withRadius:attackRange 
                collisionWithCircle:enemy.mySprite.position collisionCircleRadius:1])
            {
                [self chosenEnemyForAttack:enemy];
                break;
            }
        }
    }
}