【问题标题】:multi touch error in cocos2d - index 1 beyond boundscocos2d中的多点触摸错误-索引1超出范围
【发布时间】:2014-01-17 19:36:10
【问题描述】:

我正在尝试让多点触控工作,以便我可以同时移动两个精灵。我遵循了本教程http://www.saturngod.net/detecting-touch-events-in-cocos2d-iphone-ganbaru-games,这是我在 ccTouchesBegan 中的代码:

-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

NSArray *touchArray = [touches allObjects];

// We're going to track the first two touches (i.e. first two fingers)
// Create "UITouch" objects representing each touch
UITouch *fingerOne = [touchArray objectAtIndex:0];
UITouch *fingerTwo = [touchArray objectAtIndex:1];

// Convert each UITouch object to a CGPoint, which has x/y coordinates we can actually       use
CGPoint pointOne = [fingerOne locationInView:[fingerOne view]];
CGPoint pointTwo = [fingerTwo locationInView:[fingerTwo view]];

// The touch points are always in "portrait" coordinates
// You will need to convert them if in landscape (which we are)
pointOne = [[CCDirector sharedDirector] convertToGL:pointOne];
pointTwo = [[CCDirector sharedDirector] convertToGL:pointTwo];

if (CGRectContainsPoint(ball.boundingBox, pointOne))
{
    //ball.position = ccp(location.x , location.y);
    areWeTouchingABall = YES;
    //printf("*** ccTouchesBegan (x:%f, y:%f)\n", location.x, location.y);
}

if(CGRectContainsPoint(sp.boundingBox, pointOne)){
    areWeTouchingASquare = YES;
    // printf("*** ccTouchesBegan (x:%f, y:%f)\n", location.x, location.y);
}


// Only run the following code if there is more than one touch
if ([touchArray count] > 1)
{
    if ( CGRectContainsPoint(ball.boundingBox, pointTwo))
    {
        //ball.position = ccp(location.x , location.y);
        areWeTouchingABall = YES;
        //printf("*** ccTouchesBegan (x:%f, y:%f)\n", location.x, location.y);
    }

    if(CGRectContainsPoint(sp.boundingBox, pointTwo)){
        areWeTouchingASquare = YES;
       // printf("*** ccTouchesBegan (x:%f, y:%f)\n", location.x, location.y);
    }
}

}

这是在touchesMoved中:

-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

NSArray *touchArray = [touches allObjects];

// We're going to track the first two touches (i.e. first two fingers)
// Create "UITouch" objects representing each touch
UITouch *fingerOne = [touchArray objectAtIndex:0];
UITouch *fingerTwo = [touchArray objectAtIndex:1];

// Convert each UITouch object to a CGPoint, which has x/y coordinates we can actually use
CGPoint pointOne = [fingerOne locationInView:[fingerOne view]];
CGPoint pointTwo = [fingerTwo locationInView:[fingerTwo view]];

// The touch points are always in "portrait" coordinates
// You will need to convert them if in landscape (which we are)
pointOne = [[CCDirector sharedDirector] convertToGL:pointOne];
pointTwo = [[CCDirector sharedDirector] convertToGL:pointTwo];

if (areWeTouchingABall == YES) //
{
    ball.position = ccp(pointOne.x , pointOne.y);
    ball.zOrder = 1;
    sp.zOrder = 0;
}

if (areWeTouchingASquare == YES) //
{
    sp.position = ccp(pointOne.x , pointOne.y);
    sp.zOrder = 1;
    ball.zOrder = 0;
}


// Only run the following code if there is more than one touch
if ([touchArray count] > 1)
{
    /*if (areWeTouchingABall == YES && CGRectContainsPoint(ball.boundingBox, pointOne)) //
    {
        ball.position = ccp(pointOne.x , pointOne.y);
        ball.zOrder = 1;
        sp.zOrder = 0;
    }*/

    if (areWeTouchingABall == YES && CGRectContainsPoint(ball.boundingBox, pointTwo)) //
    {
        ball.position = ccp(pointTwo.x , pointTwo.y);
        ball.zOrder = 1;
        sp.zOrder = 0;
    }

    /*if (areWeTouchingASquare == YES && CGRectContainsPoint(ball.boundingBox, pointOne)) //
    {
        sp.position = ccp(pointOne.x , pointOne.y);
        sp.zOrder = 1;
        ball.zOrder = 0;
    }*/

    if (areWeTouchingASquare == YES && CGRectContainsPoint(ball.boundingBox, pointTwo)) //
    {
        sp.position = ccp(pointTwo.x , pointTwo.y);
        sp.zOrder = 1;
        ball.zOrder = 0;
    }
}

}

这是touchesEnded:

-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

 areWeTouchingABall = NO;
 areWeTouchingASquare = NO;
 //printf("*** ccTouchesEnded (x:%f, y:%f)\n", location.x, location.y);

}

每次我用一根手指触摸任何地方时,都会出现此错误:

“由于未捕获的异常'NSRangeException'而终止应用程序,原因:'* -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'”,

当我用两根手指触摸时,不会出现错误,但多点触控不能正常工作(我不能用一根手指拖动一个精灵。第二个触摸的精灵直接跳到另一个手指位置,这样两个精灵都在一根手指下。)

我确保添加代码:

[glView setMultipleTouchEnabled:YES];

到我的 AppDelegate.m 文件,我在我的 init 方法中启用了触摸。

如何解决此问题,以便多点触控正常工作并消除错误?

【问题讨论】:

    标签: objective-c xcode cocos2d-iphone nsarray multi-touch


    【解决方案1】:
    UITouch *fingerOne = [touchArray objectAtIndex:0];
    UITouch *fingerTwo = [touchArray objectAtIndex:1];
    

    不能保证您总是会在一次触摸事件中收到两次触摸。首先使用

    测试touchArray中有多少次触摸
    UITouch *fingerOne = [touchArray objectAtIndex:0];
    UITouch *fingerTwo = nil;
    if (touchArray.count > 1)
    {
        fingerTwo = [touchArray objectAtIndex:1];
    }
    

    即使这样,这在逻辑上也不起作用,因为数组中的第二次触摸可能并不总是对应于 #2 手指。我建议阅读tracking individual fingers here

    【讨论】:

    • 感谢您的链接。我阅读了文档和其他一些文档,并且了解更多。我在这个链接上找到了示例代码:developer.apple.com/library/ios/samplecode/Touches/Introduction/… 这正是我想要用多点触控做的,它是移动对象(一个单独的或同时多个),但我不知道如何继续做使用 Cocos2d。你知道我下一步应该采取什么步骤吗?
    • 只是让你知道,我对 Objective-C 和 Cocos2d 还是很陌生,并且正在努力不只是简单地获取示例代码并重新使用它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    相关资源
    最近更新 更多