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, следуя инструкциям, упомянутым в этом вопросе:
- http://getsetgames.com/2009/08/21/cocos2d-and-uiscrollview/
- http://www.cocos2d-iphone.org/forum/topic/9417
Оба они отлично читаются и настоятельно рекомендуются, чтобы получить более глубокое понимание того, как 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.