Правильно ли реализовать касания на нескольких CCSprites в Cocos2d ?? - PullRequest
1 голос
/ 29 июля 2011

Я разрабатываю свою первую игру с cocos2d, и я столкнулся с проблемой, которую, похоже, не могу найти правильного решения. я добавляю и анимирую CCSprite каждую секунду от верхней части экрана до нижней части и должен скрывать эти спрайты, когда игрок касается любого из них. Поэтому я подумал о том, чтобы дать теги каждому спрайту, который я добавляю, и позже получить доступ к этому спрайту с этим конкретным тегом. Нужно ли мне помещать номер тега в некоторый массив, поскольку они увеличиваются каждую секунду даже до того, как я получу к ним доступ с помощью сенсорного метода ??

- (void)addStraightBugs 
{
currentAntTag++;

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"smallAunt.plist"];        

spriteSheetmedAnt = [CCSpriteBatchNode batchNodeWithFile:@"smallAunt.png"];
[self addChild:spriteSheetmedAnt z:0 tag:kSpriteManager];

CCSprite *ant= [CCSprite spriteWithSpriteFrameName:@"small-aunt1.png"];
[spriteSheetmedAnt addChild:ant z:1 tag:currentAntTag];

NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 2; ++i) {
    [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"small-ant%d.png", i]]];
}

CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.15f];
CCAction *action=[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];


ant.position = ccp(100,500);
[ant runAction:action];

CGPoint realDest = ccp(60,140);

int minDuration = 2.0;
int maxDuration = 5.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;

[ant runAction:[CCSequence actions:
                       [CCMoveTo actionWithDuration:actualDuration position:realDest],
                       [CCCallFuncN actionWithTarget:self selector:@selector(moveFinished:)],
                       nil]];

}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event  
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];

CCSpriteBatchNode *spriteManager;
spriteManager = (CCSpriteBatchNode*)[self getChildByTag:kSpriteManager];
CCSprite *ant = (CCSprite*)[spriteManager getChildByTag:currentAntTag];

CGRect abc= CGRectInset([ant boundingBox],30, 85);

if(CGRectContainsPoint(abc,touchLocation))  
{

    ant.visible=NO;
}
}

также у меня есть 3 метода, которые вызываются каждые несколько секунд, в течение которых я создаю эти объекты CCSpriteFrameCache и CCSpriteBatchNode, чтобы заставить моего персонажа работать, пока он анимируется. это будет слишком тяжело - кэшировать каждую секунду, как это, или я должен создать их в методе init и просто запустить действие на CCSprite здесь ??

1 Ответ

2 голосов
/ 18 августа 2011

Подкласс CCSprite. Тогда в его инициации:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];

Реализация методов ccTouch:

- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

Теперь у вас есть два варианта. Вы можете иметь переменную делегата для обратного вызова или использовать NSNotifications. Пойдите с обратным вызовом здесь, это быстрее.

// in your @interface
id touchDelegate; // between the {}'s

@property (nonatomic, assign) id touchDelegate;

Внутри вашего игрового класса, когда вы создаете своих плохих парней:

NewCCSprite = newSprite = [NewCCSprite init];
newSprite.touchDelegate = self;

А когда вы касаетесь одного:

- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    if (self.touchDelegate == nil) return;
    [self.touchDelegate performSelector:@selector(touched:) withDelay:0.0f];
}

Наконец, ваше прикосновение: метод:

- (void) touch:(id)sender {
    NewCCSprite* sprite = (NewCCSprite*)sender;
    // hide/kill off/etc
}
...