UIScrollView和Cocos2D

Car*_*arl 5 iphone uiscrollview uiviewcontroller cocos2d-iphone

我在cocos2d应用程序中创建了一个UIScrollView.我正在动态添加精灵,超过3页.在第一页上,触摸在精灵上完美运行,但是如果我使用滚动视图并导航到第二页,则触摸不能正常工作...当我触摸屏幕时,精灵会响应触摸,大约是金额我向左滚动.如果我滚动回到第一页,触摸可以完美地用于精灵.有任何想法吗?我使用以下教程:http://getsetgames.com/2009/08/21/cocos2d-and-uiscrollview/ :)


我认为一些代码可能有用: -

我正在使用您的演示中的确切代码...

CocosOverlayScrollViewCocosOverlayViewController

我在我的图层中创建CocosOverlayViewController: -

CocosOverlayViewController *scrollView = [CocosOverlayViewController alloc];
[[[Director sharedDirector] openGLView] addSubview:scrollView.view];
Run Code Online (Sandbox Code Playgroud)

我正在我的场景中创建图层: -

Scene *scene = [Scene node];
GridLayer *layer = [GridLayer node];
[scene addChild: layer z:-1];
[scene setTag:12];
Run Code Online (Sandbox Code Playgroud)

我在我的图层中创建了精灵: -

    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];
Run Code Online (Sandbox Code Playgroud)

精灵正在使用TouchesDispatcher,并且在类中解析了触摸.

如果我在图层上使用cocos2d moveto函数,我可以触摸一个精灵,它会响应,所以我知道它有效,当我使用UIScrollView时,事情变得有些奇怪.

我希望你理解我的问题,可以提供帮助,一切顺利:)

卡尔

Ric*_*aez 10

我终于通过使用UIScrollView派生类实现了CCLayer的滚动,遵循这个问题中提到的教程:

它们都是非常好的阅读,强烈建议您更深入地了解UIScrollViews(以及一般的UIViews)如何与Cocos2D合作处理触摸.

但是,在实现这些解决方案时,我也遇到了问题中描述的错误:如果不滚动,则触摸会从UIScrollView正确传播到CCLayer.如果滚动,图层会滚动得很漂亮,但UIScrollView上的非滚动触摸会传播到CCLayer,偏移越大,滚动越多,这使得CCLayer(和/或伴随CCMenus)无法使用.

我发现这个问题的原因是Cocos2D如何将发送到OpenGLView的触摸转换为本地CCNode或CCMenu坐标系的错误.此错误出现在1.0 rc中,并且只影响在OpenGLView的子视图(如我们的UIScrollView)上生成的触摸,并通过调用UIScrollView的-touchesBegan:方法中的以下行传播到Cocos2D主触摸区域(即OpenGLView).

 [[[CCDirector sharedDirector] openGLView] touchesBegan:touches withEvent:event];
Run Code Online (Sandbox Code Playgroud)

(请注意,调用此前一行足以传播从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];
}
Run Code Online (Sandbox Code Playgroud)

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];
    ...
Run Code Online (Sandbox Code Playgroud)

这里的关键是UITouch的locationInView:方法.此方法的参数应该是要将触摸坐标转换为的UIView.大多数Cocos2D项目只有一个UIView:OpenGLView,因此触摸在OpenGLView(=触摸视图)中生成并转换为相同的视图.但是,如果添加重叠子视图以接收触摸(例如UIScrollView),则"触摸视图"将具有此值,该值不再对应于所需的OpenGLView.