实现分析 - Enemy part2

来源:互联网 发布:excel中国数据地图 编辑:程序博客网 时间:2024/06/06 09:59
-(void)changeState:(CharacterStates)newState {if (characterState == kStateDead)return; // No need to change state further once I am dead[self stopAllActions];id action = nil;characterState = newState;switch (newState) {     case kStateSpawning:          [self runAction:[CCFadeOut actionWithDuration:0.0f]];  // Fades out the sprite if it was visible before          [self setDisplayFrame:  [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"teleport.png"]];          action =  [CCSpawn actions:                     [CCRotateBy actionWithDuration:1.5f angle:360],                     [CCFadeIn actionWithDuration:1.5f], nil];          break;     case kStateIdle:          CCLOG(@"EnemyRobot->Changing State to Idle");          [self setDisplayFrame: [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"an1_anim1.png"]];           break;     case kStateWalking:           CCLOG(@"EnemyRobot->Changing State to Walking");           if (isVikingWithinBoundingBox)           break; // AI will change to Attacking on next frame                float xPositionOffSet = 150.0f;     if (isVikingWithinSight) {     if ([vikingCharacter position].x < [self position].x) xPositionOffSet = xPositionOffSet * -1;     // Invert to -150     } else {          if (CCRANDOM_0_1() > 0.5f) xPositionOffSet = xPositionOffSet * -1;          if (xPositionOffSet > 0.0f) {               [self setFlipX:YES];           } else {               [self setFlipX:NO];           }     }      action = [CCSpawn actions:                  [CCAnimate actionWithAnimation:robotWalkingAnim restoreOriginalFrame:NO],                 [CCMoveTo actionWithDuration:2.4f position:ccp([self position].x + xPositionOffSet,[self position].y)], nil];           break;      case kStateAttacking:           CCLOG(@"EnemyRobot->Changing State to Attacking");           action = [CCSequence actions:                     [CCAnimate actionWithAnimation:raisePhaserAnim restoreOriginalFrame:NO],                     [CCDelayTime actionWithDuration:1.0f],                     [CCAnimate actionWithAnimation:shootPhaserAnim restoreOriginalFrame:NO],                     [CCCallFunc actionWithTarget:self selector:@selector(shootPhaser)],                     [CCAnimate actionWithAnimation:lowerPhaserAnim restoreOriginalFrame:NO],                     [CCDelayTime actionWithDuration:2.0f], nil];            break;            case kStateTakingDamage:            CCLOG(@"EnemyRobot->Changing State to TakingDamage");            if ([vikingCharacter getWeaponDamage] > kVikingFistDamage){                 // If the viking has the mallet, then                 action = [CCAnimate actionWithAnimation:headHitAnim restoreOriginalFrame:YES];            } else {                  // Viking does not have weapon, body blow                action = [CCAnimate actionWithAnimation:torsoHitAnim restoreOriginalFrame:YES];            }            break;      case kStateDead:                              CCLOG(@"EnemyRobot -> Going to Dead State");            action = [CCSequence actions: [CCAnimate actionWithAnimation:robotDeathAnim restoreOriginalFrame:NO],                      [CCDelayTime actionWithDuration:2.0f],                      [CCFadeOut actionWithDuration:2.0f],             nil];             break;             default: CCLOG(@"Enemy Robot -> Unknown CharState %d",characterState);             break;    }if (action != nil)        [self runAction:action];} 


死亡:


(AI)gameUpdate 会在“适当的时候“来调用changeState,所以gameUpdate的责任是思考----” 如果是什么什么情况,就怎么样“。。。 如此这般。

然后决定了要”怎么样“,由改变状态 changeState来处理。 (just like your boss & you)

每次状态的改变应该带来行为的改变,例如本来在巡逻”walking“的敌人,在发现玩家后会改为”攻击“状态。所以stopAllAction在开始便要执行。


----  下面是AI部分

-(void)updateStateWithDeltaTime:(ccTime)deltaTime andListOfGameObjects:(CCArray*)listOfGameObjects {    [self checkAndClampSpritePosition];    if ((characterState != kStateDead) && (characterHealth <= 0)) {        [self changeState:kStateDead];        return;    }    vikingCharacter = (GameCharacter*)[[self parent] getChildByTag:kVikingSpriteTagValue];    CGRect vikingBoundingBox = [vikingCharacter adjustedBoundingBox];    CGRect robotBoundingBox = [self adjustedBoundingBox];    CGRect robotSightBoundingBox = [self eyesightBoundingBox];    isVikingWithinBoundingBox = CGRectIntersectsRect(vikingBoundingBox, robotBoundingBox) ? YES : NO;    isVikingWithinSight = CGRectIntersectsRect(vikingBoundingBox, robotSightBoundingBox)? YES : NO;    if ((isVikingWithinBoundingBox) && ([vikingCharacter characterState] == kStateAttacking)) {     // Viking is attacking this robot    if ((characterState != kStateTakingDamage) && (characterState != kStateDead)) {        [self setCharacterHealth: [self characterHealth] – [vikingCharacter getWeaponDamage]];       if (characterHealth > 0) {            [self changeState:kStateTakingDamage];        } else {            [self changeState:kStateDead];        }              return; // Nothing to update further, stop and show damage    }    } if ([self numberOfRunningActions] == 0) {   // -- 1    if (characterState == kStateDead) {        // Robot is dead, remove        [self setVisible:NO];        [self removeFromParentAndCleanup:YES];     } else if ([vikingCharacter characterState] == kStateDead) {         // Viking is dead, walk around the scene         [self changeState:kStateWalking];     } else if (isVikingWithinSight) {         [self changeState:kStateAttacking];     } else {          // Viking alive and out of sight, resume walking          [self changeState:kStateWalking];     }  } }

1-- 关键的一句

例如创建时状态是spawning,此时 updateStateWithDeltaTime 判断为:执行一个1.5s 的动画action。

如果没有1,enemy的状态会在下一个运算循环中被改为其它状态。

numberOfRunningActions 让enemy在做完前一阶段的动作后,再回到AI判断,下一阶段应该是什么。



原创粉丝点击