Подтвердить что ты не робот

Cocos2d обращается с несколькими слоями

Я был занят в течение нескольких дней, пытаясь понять, как обращаться с прикосновением в моем проекте Cocos2d. Ситуация немного другая, как обычно. У меня есть несколько разных игровых уровней, на которых есть элементы, которые мне нужно контролировать с прикосновением:

  • ControlLayer: содержит элементы управления игрой (движение, кнопка действия). Этот слой находится сверху.
  • GameplayLayer: удерживает игровые объекты (CCSprites). Этот уровень находится непосредственно под ControlLayer.

Теперь мои прикосновения отлично работают в ControlLayer, я могу перемещать свой игровой персонаж и заставить его прыгать и делать другие глупые вещи. Однако я не могу понять, как реализовать привязки к некоторым моим CCSprites.

Информация, которую я собрал до сих пор, заставляет меня думать, что мне нужно получить весь мой сенсорный ввод с уровня управления. Затем мне как-то нужно "каскадировать" сенсорную информацию на GameplayLayer, чтобы я мог обрабатывать входные данные там. Другим вариантом было бы получить информацию CGRect от моих спрайтов, создав массив с указателями на объекты, которые должны быть осязаемыми. Я должен иметь возможность использовать эту информацию в ControlLayer для проверки каждого элемента в этом списке, если элемент был затронут.

Каков наилучший вариант для этого и как это реализовать? Я новичок в программировании с помощью cocoa и Objective C, поэтому я не уверен, что лучший вариант для этого языка и как получить доступ к информации справки CGRect ([mySpriteName boundingBox]) в другом классе, затем слой он отображается.

В настоящий момент единственный способ, которым я уверен, заставить его работать, - создать дубликаты CGR для каждой позиции CCSprite, и поэтому я могу проверить их, но я знаю, что это неправильный способ сделать это.

Что я до сих пор (чтобы проверить): ControlLayer.m

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];

CGRect rect = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f);

//Tried some stuff here to get see if I could get a sprite by tagname so I could use it bounding box but that didn't work

// Check for touch with specific location
if (CGRectContainsPoint([tree boundingBox], location)) {
    CCLOG(@"CGRect contains the location, touched!");
}

CCLOG(@"Layer touched at %@", NSStringFromCGPoint(location));

}

Заранее благодарим за помощь!

4b9b3361

Ответ 1

Самый простой и простой способ решить вашу проблему - ИМО, используя ccTouchBegan/Moved/Ended вместо ccTouchesBegan/Moved/Ended. Смысл, вы решаете одно касание в определенный момент, чтобы избежать путаницы над несколькими касаниями, а также самой важной особенностью ccTouchBegan является то, что CCLayer может "поглощать" прикосновение и не допускать его распространения на следующие уровни. Больше объяснений после примеров кода ниже.

Вот шаги для этого. Внедрите эти методы во всех подклассах CCLayer, которые должны обрабатывать события касания:

Сначала зарегистрируйтесь в CCTouchDispatcher:

- (void)registerWithTouchDispatcher {
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}

Далее, реализуем ccTouchBegan, пример ниже из игры, которую я создал (часть пропущена, конечно):

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    if (scene.state != lvlPlaying) {
        // don't accept touch if not playing
        return NO;
    }
    CGPoint location = [self convertTouchToNodeSpace:touch];
    if (scene.mode == modePlaying && !firstTouch) {
        if (CGRectContainsPoint(snb_putt.sprite.boundingBox, location)) {
            touchOnPutt = touch.timestamp;

            // do stuff

            // return YES to consume the touch
            return YES;
         }
    }
    // default to not consume touch
    return NO;
}

И, наконец, реализуем ccTouchMoved и ccTouchEnded, как и ccTouches *, но они обрабатывают одно касание, а не касаются друг друга. Прикосновение, которое передается этим методам, ограничено тем, которое потребляется в ccTouchBegan, поэтому нет необходимости делать валидацию в этих двух методах.

В основном так оно и работает. Событие касания передается CCScene каждому из своих CCLayers один за другим на основе z-упорядочения (то есть начинается с верхнего слоя на нижний уровень), пока ни один из слоев не поглотит прикосновение. Поэтому, если слой наверху (например, уровень управления) потребляет сенсорное касание, касание не будет передаваться на следующий уровень (например, слой объекта). Таким образом, каждый слой должен только беспокоиться о себе, чтобы решить, потреблять ли это прикосновение или нет. Если он решит, что сенсор не может быть использован, тогда он просто не должен потреблять прикосновение (возврат NO из ccTouchBegan), и прикосновение будет автоматически распространяться по слоям.

Надеюсь, что это поможет.