UIScrollView и Cocos2D - PullRequest
       21

UIScrollView и Cocos2D

5 голосов
/ 16 марта 2010

Я создал UIScrollView в приложении cocos2d. Я добавляю спрайты динамически, более 3 страниц. На первой странице касание отлично работает на спрайте, однако, если я использую представление прокрутки и перехожу на вторую страницу, касание работает не совсем правильно ... спрайт будет реагировать на касание, когда я касаюсь экрана, примерно сумму я прокрутил влево. Если я вернусь к первой странице, сенсорный режим отлично работает для спрайта. Есть идеи? Я использую следующий учебник: http://getsetgames.com/2009/08/21/cocos2d-and-uiscrollview/ :)


Я думаю, что некоторый код может быть полезен: -

Я использую точный код из вашей демонстрации ...

CocosOverlayScrollView и CocosOverlayViewController

Я создаю CocosOverlayViewController в моем слое: -

CocosOverlayViewController *scrollView = [CocosOverlayViewController alloc];
[[[Director sharedDirector] openGLView] addSubview:scrollView.view];

Я создаю слой в моей сцене: -

Scene *scene = [Scene node];
GridLayer *layer = [GridLayer node];
[scene addChild: layer z:-1];
[scene setTag:12];

Я создаю спрайты в своем слое: -

    myImage.position = ccp(53 * (coordinate.x  + 0.52), 57 * (coordinate.y + 1.45));
   [myImage runAction:[FadeIn actionWithDuration:0.3]];
    myImage.relativeAnchorPoint = YES;
   [self addChild:myImage z:-1];

Спрайт использует TouchesDispatcher, и касания разрешаются в классе.

Если я использую функцию cocos2d moveto на слое, я могу прикоснуться к спрайту, и он отвечает, так что я знаю, что это работает, все становится немного странным, когда я использую UIScrollView.

Надеюсь, вы понимаете мою проблему и можете помочь, всего наилучшего:)

Карл

1 Ответ

10 голосов
/ 26 апреля 2011

Наконец-то я приступил к реализации прокрутки CCLayer с помощью производного класса UIScrollView, следуя инструкциям, упомянутым в этом вопросе:

Оба они отлично читаются, и настоятельно рекомендуется получить более глубокое понимание того, как UIScrollViews (и UIViews в целом) могут быть созданы для обработки касаний в сотрудничестве с Cocos2D.

Однако, после реализации этих решений, я также столкнулся с ошибкой, описанной в вопросе: если вы не прокручиваете, касания распространяются от UIScrollView к CCLayer правильно. Если вы прокручиваете, слой прекрасно прокручивается, но не прокручиваемые касания UIScrollView распространяются на CCLayer со смещением, которое увеличивается с увеличением прокрутки, что делает CCLayer (и / или сопровождающее CCMenus) непригодным для использования.

Я обнаружил, что причиной этой проблемы является ошибка в том, как Cocos2D транслирует касания, отправленные в OpenGLView, в локальные системы координат CCNode или CCMenu. Эта ошибка присутствует в 1.0 rc и затрагивает только те касания, которые генерируются в подпредставлении OpenGLView (например, в нашем UIScrollView) и распространяются в основную область касания Cocos2D (а именно в OpenGLView), вызывая следующую строку внутри -touchesBegan метода UIScrollView:

 [[[CCDirector sharedDirector] openGLView] touchesBegan:touches withEvent:event];

(Обратите внимание, что вызова этой предыдущей строки достаточно для распространения касаний без прокрутки и без масштабирования из UIScrollView в Cocos2D, вам не нужно вызывать nextResponder: как это делают вышеупомянутые сообщения в блоге.)

Решение поставляется с небольшой модификацией двух источников Cocos2D:

CCNode.m

- (CGPoint)convertTouchToNodeSpace:(UITouch *)touch {
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView).
    // CGPoint point = [touch locationInView: [touch view]];
    CGPoint point = [touch locationInView: [[CCDirector sharedDirector] openGLView]];
    point = [[CCDirector sharedDirector] convertToGL: point];
    return [self convertToNodeSpace:point];
}

- (CGPoint)convertTouchToNodeSpaceAR:(UITouch *)touch {
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView).
    // CGPoint point = [touch locationInView: [touch view]];
    CGPoint point = [touch locationInView: [[CCDirector sharedDirector] openGLView]];
    point = [[CCDirector sharedDirector] convertToGL: point];
    return [self convertToNodeSpaceAR:point];
}

CCMenu.m

-(CCMenuItem *) itemForTouch: (UITouch *) touch {
    // cocos2d 1.0 rc bug when using with additional overlayed views (such as UIScrollView).
    // CGPoint touchLocation = [touch locationInView: [touch view]];
    CGPoint touchLocation = [touch locationInView: [[CCDirector sharedDirector] openGLView]];
    touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
    ...

Ключом здесь является UITouch locationInView: метод. Аргументом для этого метода должен быть UIView, в который вы хотите перевести координаты касаний. Большинство проектов Cocos2D имеют только один UIView: OpenGLView, поэтому касания генерируются в OpenGLView (= сенсорное представление) и переводятся в одно и то же представление. Однако, если вы добавляете накладывающиеся подпредставления для получения касаний, такие как UIScrollView, «представление касанием» будет иметь это значение, которое больше не соответствует требуемому OpenGLView.

...