使用Cocos2d中其他文件的东西?

时间:2011-04-08 02:24:53

标签: objective-c cocos2d-iphone

我正在制作一个游戏(显然),我注意到我的HelloWorldLayer.m文件变得非常拥挤。我知道有一种方法可以从其他.m文件中运行方法,我只是不知道如何。例如,我想要一个Character.h和Character.m文件。我可以在HelloWorldLayer初始化层中实现它,它只使用Character文件中的所有内容而不必在HelloWorldLayer中声明所有内容吗?我希望我的问题有道理,任何帮助都表示赞赏。谢谢!

这是Character.m:

@implementation Character

@synthesize health,velocity;

-(void)dealloc {
    [super dealloc];
}

-(id)initWithTexture:(CCTexture2D *)texture rect:(CGRect)rect
{
    if((self = [super initWithTexture:texture rect:rect]))
    {
        [self scheduleUpdate];
    }
    return self;
}

-(void)update:(ccTime)dt {
    [self setPosition:ccp(self.position.x,self.position.y)];

    self = [CCSprite spriteWithFile:@"nukeboyGreen.gif"];
}

@end

这是HelloWorldLayer.m(我吝啬了它并取出了不必要的零件):

self = [super init];
    if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {

        CGSize winSize = [[CCDirector sharedDirector] winSize];

        character = [Character spriteWithFile:@"nukeboyGreeen.gif"];
        character.position = ccp(winSize.width/2,winSize.height/2);
        character.scale = 0.15;
        [self addChild:character];

请注意,我在HelloWorldLayer.h中声明了一个Character

1 个答案:

答案 0 :(得分:7)

这是面向对象编程拯救的地方。 OOP鼓励您封装与该对象本身中的对象相关的变量和函数。在您的情况下,您应该在Character类中放置特定于Character的方法,并且只让HelloWorld触发这些方法。

示例:

@interface Character : CCSprite {
   ...
}

- (void)didCollideWith:(Object *)object;

- (void)moveTo:(CGPoint)nextPoint;

- (void)shootArrow:(ckDirection)direction;

- (BOOL)isAlive;

- (int)numberOfLivesRemaining;

...

@end

然后在HelloWorldLayer中:

[character moveTo:ccp(100, 200)];
[character shootArrow:kDirectionUp];

if (![character isAlive]) {
   [self showGameOver];
}

不仅您的HelloWorldLayer不那么杂乱,您只需查看合理命名的方法,就可以轻松了解代码的作用。

编辑:

如在关于如何在Character类中指定精灵图像的评论中回答您的问题:

@implementation Character

- (id)init {
   self = [super initWithFile:@"sprite_character.png"];
   if (self) {
       // further customization
   }
   return self;
}

@end

编辑(代码添加到问题后):

首先让我指出一些错误(抱歉缺少更柔和的词):

  1. 您很少需要您的精灵来呼叫[self scheduleUpdate][self schedule:SEL]。通常人们在CCLayer或CCScene级别实现update(或tick)方法,其目的是检查所有角色(精灵,菜单,嵌套层等)以进行冲突/交互并更新它们属性。如果您只想将精灵的移动设置为特定位置,只需从CCLayer(runActioninitupdate或某处)调用ccTouchBegan方法即可。 You can read cocos2d-iphone tutorial on Actions by clicking here。因此,将update方法和scheduleUpdate调用移动到HelloWorldLayer中,然后您不再需要覆盖initWithTexture。

  2. 我看到你在update方法中实例化了一个CCSprite。我的上述观点指出了update方法在CCSprite中的不恰当性,当你实现一个方法时,你需要了解一些更重要的事情:那就是你需要决定你的方法的使用方式和频率/调用。由于update方法将每帧调用一次(即每秒60次),因此在该方法中无条件地实例化对象是完全错误的。你正在让iPhone分配(和解除分配)对象没有明显的原因,浪费了设备的处理器时间/功率。您可能想询问在哪里实例化CCSprite。答案在init方法中,因为该方法仅针对每个对象实例调用一次。同样,您需要知道的是一个方法是一次还是多次调用,并决定一段代码是在那里还是在其他地方。

  3. 在您的HelloWorldLayer代码中,您是否意识到您正在调用super init*方法两次。您无需致电[super init],因为[super initWithColor:ccc4( ... )]将在内部调用特定的init方法。虽然这样做并不完全错误,但你打算打破每个实例调用一次init的“假设”,这样你最终可能会无意中打破一些对象的完整性(相信我会这样做)以后难以调试)

  4. 最后,请注意告诉我行[self setPosition:ccp(self.position.x,self.position.y)];的真正目的是什么。你基本上将self对象的位置设置为当前位置,这就像是说“嘿,把你的位置移到当前位置”,他会像“嗯?” :P