2013-11-06 3 views
0

У меня возникли проблемы с получением спрайта, чтобы сделать анимацию. В настоящее время он отображает только первый кадр анимации и «скользит» по экрану. Я пробовал несколько разных вещей, но без успеха, и мне нужна какая-то помощь, чтобы выяснить, в чем проблема.Cocos2D Sprite Animation - Sprite только раздвигается по экрану

Ниже приведен файл заголовка для класса спрайтов:

#import <Foundation/Foundation.h> 
#import "cocos2d.h" 
#import "mainGameLayer.h" 

@class MainGameLayer, Waypoint, Tower; 

@interface Unit : CCSprite { 
    CGPoint myPosition; 
    int maxHP; 
    int currentHP; 
    float walkingSpeed; 
    Waypoint *destinationWaypoint; 
    BOOL active; 
} 

@property (nonatomic, assign) MainGameLayer *theGame; 

@property (nonatomic, strong) CCSprite *mySprite; 
@property (nonatomic, strong) CCAction *walkAction; 

@property (nonatomic, assign) float centerToSides; 
@property (nonatomic, assign) float centerToBottom; 

+(id) nodeWithTheGame: (MainGameLayer *)_game; 
-(id) initWithTheGame: (MainGameLayer *)_game; 
-(void) doActivate; 
-(void) getRemoved; 

@end 

Sprite файл реализации класса:

#import "Unit.h" 
#import "Tower.h" 
#import "Waypoint.h" 

#define HEALTH_BAR_WIDTH 20 
#define HEALTH_BAR_ORIGIN -10 

@implementation Unit 

@synthesize theGame; 
@synthesize mySprite; 

+(id) nodeWithTheGame:(MainGameLayer *)_game 
{ 
    return [[self alloc] initWithTheGame:_game]; 
} 

// BELOW IS THE ORIGINAL INIT FUNCTION, UNMODIFIED, AND IN WORKING CONDITION 
-(id) initWithTheGame:(MainGameLayer *)_game 
{ 
    if ((self=[super init])) { 

     CCArray *walkFrames = [CCArray arrayWithCapacity:6]; 
     for (int i = 0; i < 6; i++) { 
      CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"hero_walk_%02d.png", i]]; 
      [walkFrames addObject:frame]; 
     } 
     CCAnimation *walkAnimation = [CCAnimation animationWithSpriteFrames:[walkFrames getNSArray] delay:1.0/12.0]; 

     theGame = _game; 
     maxHP = 40; 
     currentHP = maxHP; 

     active = FALSE; 

     walkingSpeed = 0.5; 

     Waypoint * waypoint = (Waypoint *)[theGame.waypoints objectAtIndex:([theGame.waypoints count]-1)]; 

     destinationWaypoint = waypoint.nextWaypoint; 

     CGPoint pos = waypoint.myPosition; 
     myPosition = pos; 

     self.mySprite = [CCSprite spriteWithSpriteFrameName:@"hero_walk_00.png"]; 
     self.mySprite.position = pos; 
     [self addChild:mySprite]; 

     mySprite.flipX = 180; 

     self.walkAction = [CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:walkAnimation]]; 

     [theGame addChild:self]; 

     [self scheduleUpdate]; 

    } 

    return self; 
} 

-(void) doActivate 
{ 
    active = TRUE; 
    [self stopAllActions]; 
    [self runAction: self.walkAction]; 
} 

-(void) update:(ccTime)dt 
{ 
    if(!active)return; 

    if([theGame circle:myPosition withRadius:1 collisionWithCircle:destinationWaypoint.myPosition 
collisionCircleRadius:1]) 
    { 
     if(destinationWaypoint.nextWaypoint) 
     { 
      destinationWaypoint = destinationWaypoint.nextWaypoint; 
     }else 
     { 
      //Reached the end of the road. Damage the player 
      [theGame getHpDamage]; 
      [self getRemoved]; 
     } 
    } 

    CGPoint targetPoint = destinationWaypoint.myPosition; 
    float movementSpeed = walkingSpeed; 

    CGPoint normalized = ccpNormalize(ccp(targetPoint.x-myPosition.x,targetPoint.y-myPosition.y)); 
    mySprite.rotation = CC_RADIANS_TO_DEGREES(atan2(normalized.y,-normalized.x)); 

    myPosition = ccp(myPosition.x+normalized.x * movementSpeed, 
        myPosition.y+normalized.y * movementSpeed); 

    [mySprite setPosition:myPosition]; 
} 

-(void) getRemoved 
{ 
    [self.parent removeChild:self cleanup:YES]; 
    [theGame.units removeObject: self]; 

    // Notify the game that we killed an enemy so we can check if we can send another wave 
    [theGame enemyGotKilled]; 
} 

-(void) draw 
{ 
    ccDrawSolidRect(ccp(myPosition.x + HEALTH_BAR_ORIGIN, myPosition.y + 16), ccp(myPosition.x + HEALTH_BAR_ORIGIN + HEALTH_BAR_WIDTH, myPosition.y + 14), ccc4f(1.0, 0, 0, 1.0)); 

    ccDrawSolidRect(ccp(myPosition.x + HEALTH_BAR_ORIGIN, myPosition.y + 16), ccp(myPosition.x + HEALTH_BAR_ORIGIN + (float)(currentHP * HEALTH_BAR_WIDTH)/maxHP, myPosition.y + 14), ccc4f(0, 1.0, 0, 1.0)); 
} 



@end 

Вот основной файл заголовка игры:

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

@interface MainGameLayer : CCLayer { 
} 

+ (CCScene *) scene; 
- (BOOL) circle:(CGPoint)circlePoint withRadius:(float)radius collisionWithCircle:(CGPoint)circlePointTwo collisionCircleRadius:(float)radiusTwo; 
void ccFillPoly (CGPoint *poli, int points, BOOL closePolygon); 
- (void) enemyGotKilled; 
- (void) getHpDamage; 

@property (nonatomic, strong) NSMutableArray *towers; 
@property (nonatomic, strong) NSMutableArray *waypoints; 
@property (nonatomic, strong) NSMutableArray *units; 

@end 

И, наконец, основной файл реализации игры:

#import "MainGameLayer.h" 
#import "Tower.h" 
#import "Waypoint.h" 
#import "Unit.h" 


@implementation MainGameLayer 

@synthesize towers; 
@synthesize waypoints; 
@synthesize units; 

+ (CCScene *) scene 
{ 
    CCScene *scene = [CCScene node]; 

    MainGameLayer *layer = [MainGameLayer node]; 

    [scene addChild: layer]; 

    return scene; 
} 

- (id) init 
{ 
    if ((self = [super init])) { 
     // Initialize 
     self.isTouchEnabled = TRUE; 
     CGSize winSize = [CCDirector sharedDirector].winSize; 

     // Setting the background (Map) 
     CCSprite *background = [CCSprite spriteWithFile:@"layout.png"]; 
     [self addChild: background]; 
     [background setPosition: ccp(winSize.width/2, winSize.height/2)]; 

     [self addWaypoints]; 

     // In Game Buttons/Menu 
     CCMenuItem *sampleButton = [CCMenuItemImage itemWithNormalImage:@"sample.jpg" selectedImage:@"sample.jpg" target:self selector:@selector(samplePurchased:)]; 

     CCMenu *PurchaseUI = [CCMenu menuWithItems:sampleButton, nil]; 
     [PurchaseUI setScale:0.5]; 
     [PurchaseUI setPosition:ccp(63, 51)]; 
     [PurchaseUI alignItemsHorizontally]; 
     PurchaseUI.isTouchEnabled = TRUE; 
     [self addChild: PurchaseUI]; 

     // Set up the sprite sheets (Currently in testing) 
     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"pd_sprites.plist"]; 
     CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"pd_sprites.pvr.ccz"]; 
     [self addChild: spriteSheet]; 
    } 

    return self; 

} 

-(BOOL) canBuyTower 
{ 
    return YES; 
} 

-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    for (UITouch *touch in touches) { 
     CGPoint location = [touch locationInView: [touch view]]; 

     location = [[CCDirector sharedDirector] convertToGL: location]; 
     CCLOG(@"X: %f Y: %f", location.x, location.y); 

     if ([self canBuyTower]) { 
      // Spend the gold later 
      Tower *tower = [Tower nodeWithTheGame:self location: location]; 
      [towers addObject: tower]; 
     } 
    } 
} 

-(void) addWaypoints 
{ 
    waypoints = [[NSMutableArray alloc] init]; 

    Waypoint * waypoint1 = [Waypoint nodeWithTheGame:self location:ccp(-25,360)]; 
    [waypoints addObject:waypoint1]; 

    Waypoint * waypoint2 = [Waypoint nodeWithTheGame:self location:ccp(73,360)]; 
    [waypoints addObject:waypoint2]; 
    waypoint2.nextWaypoint =waypoint1; 

    Waypoint * waypoint3 = [Waypoint nodeWithTheGame:self location:ccp(467,360)]; 
    [waypoints addObject:waypoint3]; 
    waypoint3.nextWaypoint =waypoint2; 

    Waypoint * waypoint4 = [Waypoint nodeWithTheGame:self location:ccp(905,360)]; 
    [waypoints addObject:waypoint4]; 
    waypoint4.nextWaypoint =waypoint3; 

    Waypoint * waypoint5 = [Waypoint nodeWithTheGame:self location:ccp(1050,360)]; 
    [waypoints addObject:waypoint5]; 
    waypoint5.nextWaypoint =waypoint4; 
} 

-(BOOL) circle:(CGPoint)circlePoint withRadius:(float)radius collisionWithCircle:(CGPoint)circlePointTwo collisionCircleRadius:(float)radiusTwo 
{ 
    float xdif = circlePoint.x - circlePointTwo.x; 
    float ydif = circlePoint.y - circlePointTwo.y; 

    float distance = sqrt(xdif*xdif + ydif*ydif); 

    if (distance <= radius + radiusTwo) { 
     return TRUE; 
    } 

    return FALSE; 
} 

-(void) samplePurchased: (id)sender 
{ 
    Unit *unit = [Unit nodeWithTheGame: self]; 
    [units addObject: unit]; 
    [unit schedule:@selector(doActivate)]; 
} 

@end 
+0

[mySprite runAction: walkAction]? – YvesLeBorg

ответ

0

В конце концов, этот селектор работает каждый кадр:

-(void) doActivate 
{ 
    active = TRUE; 
    [self stopAllActions]; 
    [self runAction: self.walkAction]; 
} 

Таким образом, каждый кадр он останавливает все действия, и запускает новое действие ходьбы. Следующее действие шага кадра останавливается, а затем перезапускается. Промыть и повторить.

Поскольку анимация walk начинается с каждого кадра, у нее никогда не будет шансов перейти на следующий кадр.

+0

Извините, если это звучит как начинающий вопрос, но почему «doActivate» запускает каждый кадр? Я мог ошибаться, но я считаю, что я закодировал его, чтобы называть «doActivate» один раз для каждого устройства, как только игрок нажимает кнопку, чтобы купить устройство. Я изменил его так, чтобы удалить строку «stopallactions» и вместо этого поставить флаг, говорящий, если он еще не выполняет действие запуска, а затем запустите его; это привело к тому же результату, когда мой спрайт скользит. – user1843954

+0

[блок графика: @selector (doActivate)]; <== назначает селектор для каждого кадра – LearnCocos2D

+0

А, ок. Спасибо, что поняли это. Я не понимал, что это планирование для вызова каждого кадра. Я всегда думал, что нужно просто назвать эту конкретную функцию один раз. Я заменил его так, что теперь я вызываю функцию только один раз, но, похоже, у меня все еще такая же проблема. Любые идеи относительно того, что еще может вызвать это? Еще раз спасибо за помощь! – user1843954