1

我试图在我的 cocos2d 1.01rc iPhone 应用程序中处理视网膜显示触摸,并发现这样做我必须将触摸点乘以比例因子(参见下面的代码),即使我在我的 AppDelegate 中设置为视网膜显示(参见代码在页面的末尾)。我有点困惑,因为我预计locationInView功能会检索视网膜显示触摸而不是“标准”480x640 分辨率触摸。我的猜测是,这是由于locationInView来自 ios 库而不是来自 cocos2d,并且 cocos2d App 委托中的视网膜显示设置直到 ios 级别才会传播。奇怪的。为了清楚起见,我发布了下面的代码和输出,但如果您有类似的问题并且我是否应该考虑这个“错误”,我将不胜感激。作为 cocos2d 和 ios sdk 之间可能丢失的其他内容的警告。我可能只是愚蠢,没有找到合适的文档页面。

这是我在 ccTouchesEnded 事件上运行的代码:

-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
for(int i=0; i<[[touches allObjects] count]; i++){
    UITouch *touch = [[touches allObjects] objectAtIndex:i];
    CGPoint point = [touch locationInView: [touch view]];
    CCLOG(@"Before x:%f y:%f", point.x, point.y);
    point = [[CCDirector sharedDirector] convertToGL: point];   
    float factor = CC_CONTENT_SCALE_FACTOR();
    CCLOG(@"factor %f:", factor);
    CCLOG(@"After x:%f y:%f", point.x  , point.y  );
    CCLOG(@"After x:%f y:%f", point.x * factor, point.y * factor);
    ...
    } 

输出:

Before x:314.000000 y:3.000000
factor 2.000000:
After x:314.000000 y:477.000000
After x:628.000000 y:954.000000

该应用程序在第 4 代 iPod touch 上在视网膜显示屏下运行,以下是一些初始化数据:

cocos2d: cocos2d v1.0.1
 cocos2d: GL_VENDOR:   Imagination Technologies
 cocos2d: GL_RENDERER: PowerVR SGX 535
 cocos2d: GL_VERSION:  OpenGL ES-CM 1.1 IMGSGX535-63.14.2
  cocos2d: GL_MAX_TEXTURE_SIZE: 2048
 cocos2d: GL_MAX_MODELVIEW_STACK_DEPTH: 16
 cocos2d: GL_MAX_SAMPLES: 4
 cocos2d: GL supports PVRTC: YES
 cocos2d: GL supports BGRA8888 textures: YES
  cocos2d: GL supports NPOT textures: YES    
cocos2d: OS version: 5.0.1 (0x05000100)
cocos2d: surface size: 640x960

我在 google 和 stackoverflow 上进行了检查,在我看来,这是一年前的一个已知错误,我只是不能 100% 确定这是否已在 rc1.01 版本中修复,或者我是否在我的 AppDelegate 中做了一些愚蠢的事情:

- (void) applicationDidFinishLaunching:(UIApplication*)application
{
    //added
    CC_DIRECTOR_INIT();

    // Init the window
//  window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Try to use CADisplayLink director
    // if it fails (SDK < 3.1) use the default director
    if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
        [CCDirector setDirectorType:kCCDirectorTypeDefault];


    CCDirector *director = [CCDirector sharedDirector];

    [director setDeviceOrientation:kCCDeviceOrientationPortrait];

    // Init the View Controller
//  viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
//  viewController.wantsFullScreenLayout = YES;

    //
    // Create the EAGLView manually
    //  1. Create a RGB565 format. Alternative: RGBA8
    //  2. depth format of 0 bit. Use 16 or 24 bit for 3d effects, like CCPageTurnTransition
    //
    //
    EAGLView *glView =  [director openGLView];
    [glView setMultipleTouchEnabled:YES];

    // attach the openglView to the director
    [director setOpenGLView:glView];

//  // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
    if( ! [director enableRetinaDisplay:YES] )
        CCLOG(@"Retina Display Not supported");

有任何想法吗?这会影响我代码的其他方面吗?它似乎只涉及触摸检测,因此乘以比例因子的修复似乎没问题,当我访问精灵对象的相对位置时似乎没有问题。我会为此做更多的测试并记住这一点。

谢谢!

4

4 回答 4

3

这是设计使然。

您必须了解 iOS 设备以点为单位报告触摸位置。Retina 和非 Retina 设备的点分辨率均为 480x320 点。在 Retina 设备上,一个点由 4 个像素组成,而在所有其他设备上,一个点等于屏幕上的一个像素。

根据事件处理指南,Retina 设备上的触摸可以报告为 0.5 个位置(阅读第一个注释框),为您提供完整的 Retina 触摸分辨率。如果您不这样做,那么该分辨率可能会在转换过程中丢失(检查原始 UITouch 位置)。无论哪种方式,触摸的 Retina 分辨率都太准确了,无法使用,480x320 的触摸就足够了。

于 2012-05-02T20:35:24.670 回答
0

在 iOS(和 Cocos)中,触摸和很多东西(如视图位置/大小)不是以像素为单位处理的,而是以点为单位的。

在非视网膜屏幕中,一个点正好是一个像素,但在视网膜显示器中,一个点是两个像素宽和两个像素高。

这意味着您的所有触摸和其他坐标将始终在标准显示器的范围内(纵向 320 像素宽和 480 像素高)。这很棒,因为您不必担心屏幕的种类,而且您的代码更干净。

iOS 和 Cocos 几乎都在后台管理高分辨率,因此加载的图像将具有高分辨率,但您不必担心代码中有更多像素的屏幕。

(如果出于某种特定原因您想使用像素而不是点,那么您所做的是正确的,将点乘以内容大小。Apple 对点所做的背后的想法是您不必为此烦恼, 尽管)

于 2012-04-29T13:37:51.783 回答
0

尝试

CGPoint point = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:point];
CGPoint locationInSelf = [self convertToNodeSpace:convertedLocation];

我认为 cocos 在 convertToNodeSpace 中应用了适当的比例因子。依赖 API 将使您的代码在任何潜在的未来变化中(无论是在 cocos 中还是在苹果的东西中)。

至于对视网膜的担忧,我的总工作时间几乎为零(只需要处理我有创意并偏离上述“生存”声明的情况,在非高清版本中)。

于 2012-04-29T13:49:30.407 回答
0
CCLOG(@"After x:%f y:%f", point.x * factor, point.y * factor);

这里不需要使用因子相乘。因为在视网膜显示器中 640 * 960 是像素大小,并且对于触摸处理它们返回点,所以删除因子乘法。可能是它帮助你。

于 2012-04-29T16:01:01.670 回答