Используете вещи из других файлов в Cocos2d? - PullRequest
1 голос
/ 08 апреля 2011

Я делаю игру (очевидно), и я заметил, что мой файл HelloWorldLayer.m становится ЧРЕЗВЫЧАЙНО тесным. Я ЗНАЮ, что есть способ запускать методы из других .m файлов, я просто не знаю как. Например, я хочу иметь файл Character.h и Character.m. Могу ли я сделать это на уровне инициализации HelloWorldLayer, он просто использует все из файлов символов вместо того, чтобы объявлять все в HelloWorldLayer? Я надеюсь, что мой вопрос имеет смысл, и любая помощь приветствуется. Спасибо!

Вот Персонаж.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

1 Ответ

7 голосов
/ 08 апреля 2011

Здесь на помощь приходит объектно-ориентированное программирование.ООП рекомендует вам инкапсулировать переменные и функции, относящиеся к объекту, в сам объект.В вашем случае вы должны поместить методы, специфичные для 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 менее загроможден, вы можете легко понять, что делает ваш код, просто взглянув на разумно названные методы.

РЕДАКТИРОВАТЬ:

Комуответьте на свой вопрос, как в комментарии о том, как обозначить изображение спрайта в классе символов:

@implementation Character

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

@end

РЕДАКТИРОВАТЬ (после добавления кода к вопросу):

Сначала позвольте мне указать нанемного ошибок (извините за отсутствие более мягкого слова):

  1. Вам редко нужен ваш спрайт для вызова [self scheduleUpdate] или [self schedule:SEL].Обычно люди реализуют метод update (или tick) на уровне CCLayer или CCScene, где целью является проверка всех участников (спрайтов, меню, вложенных слоев и т. Д.) На предмет столкновения / взаимодействия и обновления их атрибутов.Если вы просто хотите анимировать перемещение спрайта в определенную позицию, просто вызовите метод runAction из CCLayer (в init, update, ccTouchBegan или где-то еще). Вы можете прочитать руководство по cocos2d-iphone по действиям, нажав здесь .Итак, переместите метод update и вызов scheduleUpdate в ваш HelloWorldLayer, и вам больше не нужно переопределять initWithTexture.

  2. Я вижу, как вы создаете экземпляр CCSprite вupdate метод.Выше я указал на неприемлемость метода 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...