Hi guys,
First off, my sincerest apologies if this should've been placed elsewhere, this seemed the best place to post this. What I'm trying to do is make it so that a user can grab a sprite with one finger and use that finger as an anchor and then use a swipe with a second finger to rotate that sprite in a given direction. Then when they let go I spawn the sprite as a box2D object in a given environment with the proper rotation etc.
Well, the spawning is working fine, what's not working is my implementation of multitouch rotation. In the simulator it appears to work fine, and it will rotate based on the angle difference between the lines created by the touches in the current and previous views. However, when exported to an actual iPhone device, the object will jump from one finger to another, rather than respecting the anchoring that I'm trying to regulate.
If anyone has any ideas that I could use to have more reliability in my moving touch-anchored rotation I'd very much appreciate it.
My code's below.
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if(spawnObject && !objectSpawned){
CCSprite *sprite;
NSString spriteName = [NSString stringWithFormat:@"object%i.png", objectNum];
sprite = [CCSprite spriteWithSpriteFrameName:spriteName];
objectSpawned = sprite;
[self addChild:objectSpawned];
NSArray *allTouch = [touches allObjects];
UITouch *touch = [allTouch objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
if(location.y > screenSize.height/2){
NSInteger offset = location.y - (screenSize.height/2);
location.y = (screenSize.height/2) - offset;
}
else {
NSInteger offset = (screenSize.height/2) - location.y;
location.y = (screenSize.height/2) + offset;
}
objectSpawned.position = ccp(location.x, location.y);
}
else {
NSArray *allTouch = [touches allObjects];
UITouch *touch = [allTouch objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 touchPosition = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
b2Vec2 bodyPosition;
// Vars
b2Body* closestBody = NULL;
float minDistance = 25.0f/PTM_RATIO;
float closestBodyDistance = 999.0f;
// Check all bodies for proximity, exclude groundbody
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
bodyPosition = b2Vec2(b->GetPosition().x, b->GetPosition().y);
float distance = b2Distance(bodyPosition, touchPosition);
if(distance > minDistance) continue; // To far away
// This is the new closest
if(distance < closestBodyDistance)
{
closestBodyDistance = distance;
closestBody = b;
}
}
// No match
if(closestBody == NULL) return;
// Do something with the cloest body
// ...
objectSpawned = (CCSprite*)closestBody->GetUserData();
spawnObject = TRUE;
remakeObject = TRUE;
remadeObject = objectSpawned;
[self removeChild:(CCSprite*)closestBody->GetUserData() cleanup:true];
world->DestroyBody(closestBody);
return;
}
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if(spawnObject && objectSpawned){
NSArray *allTouch = [touches allObjects];
UITouch *anchorTouch = NULL;
UITouch *secondaryTouch;
CGPoint objectLocation;
for(UITouch* touch in allTouch){
CGPoint location = [touch previousLocationInView: [touch view]];
if(CGRectContainsPoint([objectSpawned textureRect], location) && !anchorTouch){
anchorTouch = touch;
}
else {
secondaryTouch = touch;
}
}
if(!anchorTouch){
anchorTouch = [allTouch objectAtIndex:0];
}
objectLocation = [anchorTouch locationInView:[anchorTouch view]];
objectLocation = [[CCDirector sharedDirector] convertToGL:objectLocation];
/*UITouch *touch = [allTouch objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];*/
if([allTouch count] > 1){
CGFloat currentAngle = angleBetweenLinesInRadians([anchorTouch previousLocationInView:[anchorTouch view]], [secondaryTouch previousLocationInView:[secondaryTouch view]], [anchorTouch locationInView:[anchorTouch view]], [secondaryTouch locationInView:[secondaryTouch view]]);
objectSpawned.rotation = objectSpawned.rotation + CC_RADIANS_TO_DEGREES(currentAngle);
}
//CCLOG(@"Move sprite sprite %0.2f x %02.f",location.x,location.y);*/
objectSpawned.position = ccp(objectLocation.x, objectLocation.y);
}
}
-(void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
objectRotation = objectSpawned.rotation;
[self removeChild:objectSpawned cleanup:true];
objectSpawned = NULL;
//Add a new body/atlas sprite at the touched location
if (spawnObject) {
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
[self addNewSpriteWithCoords: location ofType:objectNum];
break;
}
spawnObject = false;
}
world->SetGravity(b2Vec2(0.0f,-10.0f));
}