2013-11-21 43 views
0

我在業餘時間從Ray Wenderlich書中學習Cocos2D,但如果它沒有解釋如何做某件事,我可以看到自己需要未來。由於我的知識非常有限,我目前陷入困境。Cocos 2D - 從另一個班級更改遊戲角色狀態

我希望使用GamePlayLayer類隨意改變TBT類的字符狀態。

我已經檢查每一個國家,他們所有的工作(通過使它們產卵狀態檢查),所以這個問題是最有可能在我試圖使自己的方法gamePlayLayer.m文件。

我似乎能夠得到它的狀態改變爲kStateThrowing而是筆直向後(在第二!0.3),以kStateIdle它改變了動畫播放之前,並具有以下輸出...

2013-11-21 13:45:07.938 Spaceviking[981:12c03] CHANGING STATE TBT!!!!!!

2013-11-21 13:45:07.939 Spaceviking[981:12c03] TBT->Changing State to throwing

2013-11-21 13:45:07.967 Spaceviking[981:12c03] TBT Going to Idle

2013-11-21 13:45:07.970 Spaceviking[981:12c03] TBT->changing state to idle

任何幫助,這將不勝感激。

代碼如下...

// CommonProtocols.h 

#ifndef SpaceViking_CommonProtocols_h 
#define SpaceViking_CommonProtocols_h 

typedef enum { 
    kDirectionLeft, 
    kDirectionRight 
} 
PhaserDirection; 

typedef enum { 
    kStatespawning, 
    kStateIdle, 
    kStateWalking, 
    kStateIdleTilt, 
    kStatebackTilting, 
    kStateforwardTilting, 
    kStateAttacking, 
    kStateTakingDamage, 
    kStateThrowing, 
    kStateLosingALife, 
    kStateDead, 
    kStateTravelling, 
    kStateRotating, 
    kStatetest 

} 
CharacterStates; //1 

typedef enum { 
    kObjectTypeNone, 
    kPowerUpTypeHealth, 
    kPowerTypeMallet, 
    kEnemyType1BT, 
    kEnemyType2BT, 
    kEnemyType3BT, 
    kEnemyTypePhaser, 
    kVikingType, 

} GameObjectType; 


@protocol GamePlayLayerDelegate 

-(void)createObjectOfType:(GameObjectType)objectType 
withHealth:(int)initialHealth 
atLocation:(CGPoint)spawnLocation 
       withZValue:(int)ZValue; 

-(void)createPhaserWithDirection: (PhaserDirection)phaserDirection 
        andPosition:(CGPoint)spawnPosition; 


#endif 

// GamePlayLayer.h 

#import <Foundation/Foundation.h> 
#import "cocos2d.h" 
#import "CCLayer.h" 
#import "SneakyJoystick.h" 
#import "SneakyButton.h" 
#import "SneakyButtonSkinnedBase.h" 
#import "SneakyJoystickSkinnedBase.h" 
#import "Constants.h" 
#import "CommonProtocols.h" 
#import "TBT.h" 

@interface GamePlayLayer : CCLayer <GamePlayLayerDelegate> { 
    CCSprite *vikingSprite; 
    SneakyJoystick *leftJoystick; 
    SneakyButton *jumpButton; 
    SneakyButton *attackButton; 
    CCSpriteBatchNode *sceneSpriteBatchNode; 
} 
@end 

------------------------------------------------ 

// GamePlayLayer.m 
#import "GamePlayLayer.h" 

@implementation GamePlayLayer 
-(void) dealloc { 
    [leftJoystick release]; 
    [jumpButton release]; 
    [attackButton release]; 
    [super dealloc]; 
    } 

    --DELETED BELOW 2 METHODS AS NOT NEEDED FOR THIS QUESTION-- 
-(void)initJoystickAndButtons { 
    } 
-(void)applyJoystick:(SneakyJoystick *)aJoystick toNode: (CCNode *)tempNode forTimeDelta:(float)deltaTime 
{ 
    } 

-(void) update:(ccTime)deltaTime { 
    CCArray *listOfGameObjects = 
    [sceneSpriteBatchNode children];      
    for (GameCharacter *tempChar in listOfGameObjects) {   
     [tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:listOfGameObjects];       
    } 
} 
-(void) createObjectOfType: (GameObjectType)objectType 
       withHealth:(int)initialHealth atLocation:(CGPoint)spawnLocation withZValue:(int)ZValue { 
    if (objectType == kEnemyType1BT) { 
     CCLOG(@"creating 1BT"); 
     TBT *tBT = [[TBT alloc] initWithSpriteFrameName:@"BT_anim_1.png"]; 
     [tBT setCharacterHealth:initialHealth]; 
     [tBT setPosition:spawnLocation]; 
     [sceneSpriteBatchNode addChild:tBT 
            z:ZValue 
            tag:k1BTTagValue]; 
     [tBT release]; 
    } 
} 

--BELOW IS THE METHOD I HAVE CREATED TO CHANGE THE STATE-- 

-(void)changeState:(CharacterStates)newState { 
    [self stopAllActions]; 

    int x = (arc4random() % 3); 

    TBT *tBT = [[TBT alloc] 
        initWithSpriteFrame:[[CCSpriteFrameCache 
             sharedSpriteFrameCache] 
             spriteFrameByName:@"BT_anim_1.png"]]; 
    if (x>0) { 
     CCLOG(@"CHANGING STATE TBT!!!!!!"); 

     [tBT changeState:kStateThrowing]; 

     [tBT setDelegate:self]; 
     [tBT release];  
    } 
} 

-(id)init { 
    self = [super init]; 

    if (self !=nil) { 
     CGSize screenSize = [CCDirector sharedDirector]. winSize; 
     self.TouchEnabled = YES; 
     srandom(time(NULL)); 

     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
      [[CCSpriteFrameCache sharedSpriteFrameCache] 
      addSpriteFramesWithFile:@"scene1atlas.plist"];   // 1 
      sceneSpriteBatchNode = 
      [CCSpriteBatchNode batchNodeWithFile:@"scene1atlas.png"]; // 2 
     } else { 
      [[CCSpriteFrameCache sharedSpriteFrameCache] 
      addSpriteFramesWithFile:@"scene1atlasiPhone.plist"];   // 1 
      sceneSpriteBatchNode = 
      [CCSpriteBatchNode batchNodeWithFile:@"scene1atlasiPhone.png"]; 
     } 
     [self addChild:sceneSpriteBatchNode z:0];     
     [self initJoystickAndButtons];       
     BC *viking = [[BC alloc] 
          initWithSpriteFrame:[[CCSpriteFrameCache 
               sharedSpriteFrameCache] 
               spriteFrameByName:@"BCmoving_anim_1.png"]];    
     [viking setJumpButton:jumpButton]; 
     [viking setAttackButton:attackButton]; 
     [viking setPosition:ccp(screenSize.width * 0.19f, 
           screenSize.height * 0.19f)]; 
     [viking setCharacterHealth:3]; 

     [sceneSpriteBatchNode 
     addChild:viking 
     z:kVikingSpriteZValue 
     tag:kVikingSpriteTagValue];   



     [self createObjectOfType:kEnemyType1BT withHealth:3 atLocation:ccp(screenSize.width * 0.0439f, screenSize.height * 0.822f) withZValue:10]; 

     ---THE BELOW SELECTOR IS WHAT I HAVE USED TO DO A TIMED STATE CHANGE (METHOD ABOVE)-- 

     [self schedule:@selector(changeState:) interval:1.0f]; 

     [self scheduleUpdate]; 
    } 
    return self; 
} 
@end 

// TBT.h 

#import <Foundation/Foundation.h> 
#import "GameCharacter.h" 

@interface TBT : GameCharacter { 
    //This is for the required animations 
    CCAnimation *tiltingAnim; 
    CCAnimation *transmittingAnim; 
    CCAnimation *loseLifeAnim; 
    CCAnimation *throwingAnim; 
    CCAnimation *afterThrowingAnim;  
    CCAnimation *shootPhaserAnim;  

    GameCharacter *vikingCharacter; 
    id <GamePlayLayerDelegate> delegate; 

} 
@property (nonatomic,assign) id <GamePlayLayerDelegate> delegate; 
@property (nonatomic, retain) CCAnimation *tiltingAnim; 
@property (nonatomic, retain) CCAnimation *transmittingAnim; 
@property (nonatomic, retain) CCAnimation *loseLifeAnim; 
@property (nonatomic, retain) CCAnimation *throwingAnim; 
@property (nonatomic,retain) CCAnimation *afterThrowingAnim; 
@property (nonatomic,retain) CCAnimation *shootPhaserAnim; 

-(void)initAnimations; 
-(void)changeState:(CharacterStates)newState; 
@end 


// TBT.m 
#import "TBT.h" 

@implementation TBT 

@synthesize delegate; 
@synthesize tiltingAnim; 
@synthesize transmittingAnim; 
@synthesize loseLifeAnim; 
@synthesize throwingAnim; 
@synthesize afterThrowingAnim; 
@synthesize shootPhaserAnim; 

-(void) dealloc { 
    delegate = nil; 

    [tiltingAnim release]; 
    [transmittingAnim release]; 
    [loseLifeAnim release]; 
    [throwingAnim release]; 
    [afterThrowingAnim release]; 
    [shootPhaserAnim release]; 

    [super dealloc]; 
} 
--BELOW METHOD NOT NEEDED FOR THIS QUESTION 
-(void)shootPhaser {} 

-(CGRect)TBTboundingBox { 
    CGRect tbtBoundingBox = [self boundingBox]; 
    float xOffset; 
    float xCropAmount = tbtBoundingBox.size.width * 0.5482f; 
    float yCropAmount = tbtBoundingBox.size.height * 0.1f; 

    tbtBoundingBox = 
    CGRectMake(tbtBoundingBox.origin.x + xOffset, 
       tbtBoundingBox.origin.y, 
       tbtBoundingBox.size.width - xCropAmount, 
       tbtBoundingBox.size.height - yCropAmount); 

    return tbtBoundingBox; 

} 

-(void)changeState:(CharacterStates)newState { 
    [self stopAllActions]; 
    id action = nil; 

    [self setCharacterState:newState]; 

    switch (newState) { 
     case kStatespawning: 
      CCLOG(@"TBT->Changing State to Spwaning"); 
      [self setDisplayFrame: 
      [[CCSpriteFrameCache sharedSpriteFrameCache] 
       spriteFrameByName:@"BT_anim_1.png"]]; 
      break; 


     case kStateIdle: 
      CCLOG(@"TBT->schaning state to idle"); 
      [self setDisplayFrame: 
      [[CCSpriteFrameCache sharedSpriteFrameCache] 
       spriteFrameByName:@"BT_anim_1.png"]]; 

      break; 

     case kStateThrowing: 
      CCLOG(@"TBT->Changing State to throwing"); 
      action = [CCSequence actions: 
         [CCAnimate actionWithAnimation:throwingAnim 
           restoreOriginalFrame:NO], 
         [CCDelayTime actionWithDuration:1.0f], 
         //[CCAnimate actionWithAnimation:shootPhaserAnim 
         //   restoreOriginalFrame:NO], 
         [CCCallFunc actionWithTarget:self 
              selector:@selector(shootPhaser)], 
         [CCAnimate actionWithAnimation:afterThrowingAnim 
           restoreOriginalFrame:NO], 
         [CCDelayTime actionWithDuration:0.1f], 
         nil]; 

      break; 

     case kStateLosingALife: 
      CCLOG(@"TBT->Losing a life"); 

      break; 

      case kStateDead: 
      CCLOG(@"TBT->changing state to dead"); 
      action = [CCAnimate actionWithAnimation:loseLifeAnim]; 

      break; 

     default: 
      CCLOG(@"unhandled state %d in TBT", newState); 
      break; 
    } 
    if (action !=nil) { 
     [self runAction:action]; 
     } 
} 

-(void)updateStateWithDeltaTime: (ccTime)deltaTime andListOfGameObjects:(CCArray*)listOfGameObjects { 
    if (characterState == kStateDead) 
     return; 
    vikingCharacter = 
    (GameCharacter*)[[self parent] 
        getChildByTag:kVikingSpriteTagValue]; 
    CGRect vikingBoudingBox = 
    [vikingCharacter adjustedBoundingBox]; 
    CharacterStates vikingState = [vikingCharacter characterState]; 
    if ((vikingState == kStateAttacking) && (CGRectIntersectsRect ([self adjustedBoundingBox], vikingBoudingBox))) { 
     if (characterState != kStateTakingDamage) { 
      [self changeState:kStateTakingDamage]; 
      return; 
     } 
    } 
    if ((([self numberOfRunningActions] == 0) && (characterState != kStateDead))) { 
     CCLOG(@"TBT Going to Idle"); 
     [self changeState:kStateIdle]; 
     return; 
    } 

} 


-(void)initAnimations { 
    [self setTransmittingAnim:[self loadPlistForAnimationWithName:@"transmittingAnim" andClassName:NSStringFromClass([self class])]]; 

    [self setThrowingAnim:[self loadPlistForAnimationWithName:@"throwingAnim" andClassName:NSStringFromClass([self class])]]; 

    [self setAfterThrowingAnim:[self loadPlistForAnimationWithName:@"afterThrowingAnim" andClassName:NSStringFromClass([self class])]]; 
} 

-(id) initWithSpriteFrameName:(NSString*)frameName{ 
    if ((self=[super init])) { 
     if ((self = [super initWithSpriteFrameName:frameName])) { 

      CCLOG(@"### TBT initialized"); 
      [self initAnimations];         
      characterHealth = 3.0f;        
      gameObjectType = kEnemyType1BT;      
      [self changeState:kStatespawning];      
      } 
    } 
    return self; 
} 
@end 

回答

0

我的猜測是你不加入TBT對象作爲一個孩子任何東西(即CCScene/CCNode/CCSprite)。嘗試將其添加到「sceneSpriteBatchNode」,就像在createObjectOfType:方法中一樣。

[sceneSpriteBatchNode addChild:tBT 
         z:ZValue 
         tag:k1BTTagValue]; 
+0

嗨Skullz,非常感謝您給予回覆。我以爲我已經在createObjectOf類型中將TBT添加爲圖層中的一個子元素。我添加了TBT * tBT =(TBT *) [sceneSpriteBatchNode getChildByTag:kEnemyType1BT];進入changeState:(CharacterStates)newState方法,但是它什麼都不做,並且當它被添加時,它將不再將狀態改變爲拋出,並且它僅停留在空閒狀態。如果你能給我任何其他的想法,那就太好了,再次感謝 –

相關問題