Iphone UIScrollView和Cocos2D

Iphone UIScrollView和Cocos2D,iphone,uiviewcontroller,uiscrollview,cocos2d-iphone,Iphone,Uiviewcontroller,Uiscrollview,Cocos2d Iphone,我已经在cocos2d应用程序中创建了UIScrollView。我正在动态添加精灵,超过3页。在第一页上,触摸在精灵上工作得非常好,但是如果我使用滚动视图并导航到第二页,触摸就不能正常工作。。。当我触摸屏幕时,精灵将响应触摸,大约是我向左滚动的量。如果我滚动回到第一页,触摸屏对于精灵来说是完美的。有什么想法吗?我正在使用以下教程:) 我认为一些代码可能有用:- 我使用的正是你演示中的代码 cocoOverlayScrollView和cococoOverlayViewController 我正在

我已经在cocos2d应用程序中创建了UIScrollView。我正在动态添加精灵,超过3页。在第一页上,触摸在精灵上工作得非常好,但是如果我使用滚动视图并导航到第二页,触摸就不能正常工作。。。当我触摸屏幕时,精灵将响应触摸,大约是我向左滚动的量。如果我滚动回到第一页,触摸屏对于精灵来说是完美的。有什么想法吗?我正在使用以下教程:)


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

我使用的正是你演示中的代码

cocoOverlayScrollViewcococoOverlayViewController

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

CocosOverlayViewController *scrollView = [CocosOverlayViewController alloc];
[[[Director sharedDirector] openGLView] addSubview:scrollView.view];
    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];
我正在场景中创建层:-

Scene *scene = [Scene node];
GridLayer *layer = [GridLayer node];
[scene addChild: layer z:-1];
[scene setTag:12];
我正在我的图层中创建精灵:-

CocosOverlayViewController *scrollView = [CocosOverlayViewController alloc];
[[[Director sharedDirector] openGLView] addSubview:scrollView.view];
    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时,事情会变得有点奇怪

我希望你能理解我的问题,并能帮助我,祝你一切顺利:)


Carl

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

这两本书都是很好的读物,强烈建议您深入了解UIScrollView(以及一般的UIView)如何与Cocos2D合作处理触摸

然而,在实现这些解决方案时,我也遇到了问题中描述的错误:如果不滚动,触摸会从UIScrollView正确地传播到CCLayer。如果滚动,该层滚动得很漂亮,但UIScrollView上的非滚动接触会传播到CCLayer,并且偏移量会随着滚动次数的增加而增加,这使得CCLayer(和/或附带的CCMenus)无法使用

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

 [[[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];
}
-(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];
    ...
ccmen.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];
}
-(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。

嘿,Carl,你在和写这篇文章的人说话!很高兴你找到了它,希望它能让你很好地开始工作。至于您的问题,听起来您使用的是分页scrollview实例,对吗?我在写这篇文章时并没有考虑到这种情况,但我相信我们可以找出一些问题。我使用的是页面滚动视图,但我的应用程序不依赖它,所以我可以删除它。我不认为我之前解释得很好,触摸事件在第一个“页面”上工作得很好,但是当我滚动(即使是最轻微的)精灵移动时,触摸事件仍然对精灵先前的位置做出响应。有什么想法吗?我使用Cocos2d和UIScrollView创建了一个示例项目,并在Cocos2d论坛上发布了一个链接:这个问题与我的兴趣相关。卡尔,罗布:你找到解决办法了吗?如果是这样的话,你能给出答案吗?我一直在阅读教程,我准备尝试并实现它,但我有一些疑问:它是否适用于Cocos2D iPhone 1.0rc?如何在Cocos2D项目中使用CocosOverlayViewController?是否应该替换默认的RootViewController?只是想指出,要编辑的第二个文件是CCMenu.m,而不是CCLayer.m;-)我想我只是独立地做了这个修复,因为我还使用了UIScrollView和EagleView。