UIScrollView и Cocos2D

Я создал 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 ответ

Решение

Наконец-то я приступил к реализации прокрутки 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];
    ...

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

Другие вопросы по тегам