Cocos2d 在其子级之一中执行 CCLayer 函数
我正在为一个研究项目构建一款 iPad 游戏,但我一直在尝试让我的一个对象(继承自 CCSprite)调用 CCLayer 上的函数。
情况: 我的 CCLayer 上有一个 wordObject 实例(继承自 CCSprite)。当对象被触摸时,它会记录一些内容,并且应该在其父对象 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];
}
我缺乏使用协议或接口的知识可能导致我在这个过程中遗漏了一些东西。虽然它没有给我任何错误或警告,但它也没有像我想要的那样执行该函数。 (我有一个正在使用它的演示应用程序,它工作得很好,但我只是找不到我丢失的代码片段)。
关于如何解决这个问题有什么建议吗?感谢您的阅读并希望能回答我的问题!
I'm building an iPad game for a study project and I'm stuck trying to have one of my objects (which inherits from CCSprite) to call a function on the CCLayer.
The situation:
I have an instance of wordObject (inherits from CCSprite) on my CCLayer. When the object gets touched it logs something and should execute a function on it's parent, the CCLayer, to create a new object.
What I have so far detects the touch and logs a message, but I can't find a way to execute the function on the CCLayer, hence my question.
When programming in another language I would just pass the CCLayer pointer as a parameter to the init function of my object. I tried doing that by extending the initWithSprite function this way:
//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;
}
The problem is after using this the object no longer responds to touch input (this is probably caused by me doing something wrong with the initialization of the object).
However, there is another way to do this and from what I understand this way is better in Objective C. I should be able to create a protocol for the function I need and then call that function in my object using delegation. The code I've written for this:
//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];
}
My lack of knowledge of working with protocols or interfaces probably caused me to omit something in the process. Although it doesn't give me any errors or warnings, it doesn't execute the function like I want it too. (I've got demo app that's using it and there it works perfectly but I just can't find the piece of code I'm missing).
Any suggestions on how I can fix this? Thanks for reading and hopefully answering my problem!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
拥有一个 CCSprite 子类是完全可以的。这应该不是问题(仅当您没有使用现有的字段名称时)。但是如果你的精灵有一个CCLayer作为父级,你可以简单地从精灵(甚至CCNode)访问它
PS:你不能改变一个对象的状态,只是将指针传递给它的某个地方,直到你通过这个指针调用一些方法。
It is totally ok to have a CCSprite subclass what you've done. It should not be a problem (only if you were not using the existing field name). But if your sprite has a CCLayer as a parent the you can simple access it from sprite (or even CCNode)
PS: You can't change the state of an object just passing pointer to it somewhere until you call some methods through this pointer.