Вопрос

I am trying to get multi touch working so that I can move two sprites at the same time. I followed this tutorial http://www.saturngod.net/detecting-touch-events-in-cocos2d-iphone-ganbaru-games and this is the code I have in 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);
    }
}

}

this is in 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;
    }
}

}

and this is in touchesEnded:

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

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

}

Every time I touch anywhere with one finger, I get this error:

"Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'",

When I touch with two fingers, the error does not come up but multi touch does not work correctly ( I cannot drag a sprite with a finger each. The second sprite touched jumps straight to the other finger location so that both sprites are under one finger.)

I made sure to add the code:

[glView setMultipleTouchEnabled:YES];

to my AppDelegate.m file and I have touch enabled in my init method.

How can I fix this issue so that multi-touch works properly and the error is removed?

Это было полезно?

Решение

UITouch *fingerOne = [touchArray objectAtIndex:0];
UITouch *fingerTwo = [touchArray objectAtIndex:1];

There's no guarantee that you'll always receive two touches in a touch event. First test how many touches there are in touchArray using

UITouch *fingerOne = [touchArray objectAtIndex:0];
UITouch *fingerTwo = nil;
if (touchArray.count > 1)
{
    fingerTwo = [touchArray objectAtIndex:1];
}

Even then this won't work logically because the second touch in the array may not always correspond to finger #2. I suggest to read up on tracking individual fingers here.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top