Cocos2d выполняет функцию CCLayer в одном из своих детей - PullRequest
0 голосов
/ 09 марта 2011

Я создаю игру для iPad для учебного проекта, и я пытаюсь заставить один из моих объектов (который наследуется от CCSprite) вызывать функцию на CCLayer.

Ситуация: У меня есть экземпляр wordObject (наследуется от CCSprite) на моем CCLayer. Когда к объекту прикасаются, он что-то регистрирует и должен выполнить функцию для своего родителя, CCLayer, чтобы создать новый объект.

То, что у меня есть, обнаруживает касание и регистрирует сообщение, но я не могу найти способ выполнить функцию на CCLayer, поэтому мой вопрос.

При программировании на другом языке я бы просто передавал указатель CCLayer в качестве параметра функции init моего объекта. Я попытался сделать это, расширив функцию initWithSprite следующим образом:

//touch function
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
        CGPoint location = [touch locationInView: [touch view]];
        if (CGRectContainsPoint([self boundingBox], location)) {
            CCLOG(@"Woah");
            [parentLayer foundWord:@"test" atLocation:ccp(100.0f, 100.0f) withZValue:(int)1000 andPoints:100];
            CCLOG(@"Delegate should have executed");

            return YES;
        }
        CCLOG(@"Touch detected, I'm located at %@ and the touch position is %@.", NSStringFromCGRect([self boundingBox]), NSStringFromCGPoint(location));
        return NO;
    }

// Extended init function, I have no normal init function anymore (but I don't think I need that, tried it and it gave crashes
-(id)initWithSpriteFrame:(CCSpriteFrame*)spriteFrame andParent:(CCLayer *)layer{
        [super initWithSpriteFrame:spriteFrame];
        self = [super init];
        if(self != nil){
            parentLayer = layer;
        }
        return self;
    }

Проблема в том, что после использования этого объекта больше не реагирует на сенсорный ввод (это, вероятно, вызвано тем, что я что-то не так сделал с инициализацией объекта).

Однако есть другой способ сделать это, и, насколько я понимаю, этот способ лучше в Objective C. Я должен иметь возможность создать протокол для нужной мне функции, а затем вызвать эту функцию в моем объекте с помощью делегирования. Код, который я написал для этого:

//CommonProtocols.h the file with the protocols. It is included in the CCLayer and in the object
@protocol GameplayScrollingLayerDelegate
-(void)foundWord:(NSString *)word atLocation:(CGPoint)location withZValue:(int)ZValue andPoints:(int)points;
@end

//Layer.h, subscribing the class to the protocol so it knows where it should delegate to
@interface Layer : CCLayer <GameplayScrollingLayerDelegate>  {
    //some stuff omitted due to not being relevant.
}

//Layer.m, nothing done here, I've just added the function which I described in the protocol file
-(void)foundWord:(NSString *)word atLocation:(CGPoint)location withZValue:(int)ZValue andPoints:(int)points{
    // Function gibberish doing what I want it to do
}

//Object.h create the delegate
@interface Object : GameObject <CCTargetedTouchDelegate> {
    id <GameplayScrollingLayerDelegate> delegate;
}

@property (nonatomic,assign) id <GameplayScrollingLayerDelegate> delegate;


//Object.m synthesize the delegate and try to execute the function
@synthesize delegate
//... code omitted ...
-(id)init{
    //default init stuff
    [delegate foundWord:@"test" atLocation:ccp(100.0f, 100.0f) withZValue:(int)1000 andPoints:100];
}

Мое отсутствие знаний о работе с протоколами или интерфейсами, вероятно, заставило меня что-то пропустить в процессе. Хотя он не дает мне ошибок или предупреждений, он не выполняет функцию так, как я хочу. (У меня есть демо-приложение, которое его использует, и оно отлично работает, но я просто не могу найти кусок кода, который мне не хватает).

Любые предложения о том, как я могу это исправить? Спасибо, что прочитали и, надеюсь, ответили на мою проблему!

1 Ответ

1 голос
/ 09 марта 2011

Совершенно нормально иметь подкласс CCSprite, что вы сделали.Это не должно быть проблемой (только если вы не используете существующее имя поля).Но если ваш спрайт имеет CCLayer в качестве родителя, вы можете просто получить к нему доступ из спрайта (или даже CCNode)

CCLayer *layer = (CCLayer*) self.parent;

PS: Нельзя изменить состояние объектапросто передавая указатель на него где-нибудь, пока вы не вызовете некоторые методы через этот указатель.

...