### applyforce inconsistent behavior

Posted:

**Sun Mar 19, 2017 9:23 pm**I am using box2d to simulate projectile motion from a cannon. I am calculating the angle and distance between the cannon barrel and the crosshair. The greater the distance between the crosshair and the barrel the larger the force. I am running this program on Xcode 8.2.1 and cocos2d. When I run my program on the iPad air I see inconsistent behavior. For example, as I increase the distance I expect the force to increase, and as a result I expect the distance the projectile travels to be longer, but I am not seeing this behavior. I decrease the distance between the barrel and the crosshair and the projectile flies farther. Below is the code I am using. I know that box2d is not deterministic and I have tried applyForce, applyLinerarImpulse, and setLinearVelocity, but I cannot get the behavior correct. I want the force to be less when the distance is less, and the force to be greater when the distance is greater. Below is my code. Any help is appreciated.

Code: Select all

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

{

if( self.boulderFired || gamePaused)

{

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

return;

}

NSLog(@"began");

UITouch *myTouch = [touches anyObject];

CGPoint location = [myTouch locationInView:[myTouch view]];

location = [[CCDirector sharedDirector] convertToGL:location];

float angleDegree, angleRadian;

int direction =1;

if(self.hud.isSoundOn)

[self.musicInterface playAudioStartTouch];

float distanceX = ( (location.x/PTM_RATIO) - (barrel.position.x/PTM_RATIO) );

float distanceY = ( (location.y/PTM_RATIO) - (barrel.position.y/PTM_RATIO) );

if (fabsf(distanceX)>18*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth) ||

fabsf(distanceY)>18*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth))

{

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

return;

}

if(barrel.position.x<location.x)

{

angleRadian = atanf(distanceY/distanceX);

angleDegree = CC_RADIANS_TO_DEGREES(angleRadian);

}

else

{

angleRadian = atanf(distanceY/distanceX);

angleDegree =180 + CC_RADIANS_TO_DEGREES(angleRadian);

direction=-1;

}

slingPosition = ccp(barrel.position.x, (barrel.position.y+15/scaleFactorSpriteResolution));

barrel.rotation = (angleDegree*-1);

if (distanceX*distanceX+distanceY*distanceY>(17*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth)))

{

CGFloat angleTemp = atan2f(distanceY,distanceX);

CGPoint tempStandPos = [self scalePoint:ccp(35,135)];

CGPoint tempBarrelPos = [self scalePoint:ccp(65,165)];

location.x=tempBarrelPos.x+tempStandPos.y*cosf(angleTemp);

location.y=tempBarrelPos.y+tempStandPos.y*sinf(angleTemp);

}

crossHair.position = ccp(location.x, location.y);

distanceX = ( (crossHair.position.x/PTM_RATIO) - (slingPosition.x/PTM_RATIO) );

distanceY = ( (crossHair.position.y/PTM_RATIO) - (slingPosition.y/PTM_RATIO) );

float distance = sqrtf(distanceX*distanceX+distanceY*distanceY)*direction;

bulletStartingPosition = b2Vec2(slingPosition.x, slingPosition.y);

//bulletStartingVelocity = b2Vec2(cosf(angleRadian)*(distance/scaleFactorSpriteResolution),sinf(angleRadian)*(distance/scaleFactorSpriteResolution));

bulletStartingVelocity = b2Vec2(cosf(angleRadian)*(distance*10),sinf(angleRadian)*(distance*10));

if(sniperOn)

[self drawProjectilePath:b2Vec2(barrel.position.x, barrel.position.y) withVelocity:b2Vec2(cosf(angleRadian)*(distance*23.895),sinf(angleRadian)*(distance*23.895))];

// [self drawProjectilePath:bulletStartingPosition :b2Vec2(cosf(angleRadian)*distance*56.595,sinf(angleRadian)*distance*56.595)];

//[self drawProjectilePath:bulletStartingPosition :bulletStartingVelocity];

}

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

{

NSLog(@"move start");

if( self.boulderFired || gamePaused)

{

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

return;

}

UITouch *myTouch = [[touches allObjects] objectAtIndex:0];

CGPoint location = [myTouch locationInView:[myTouch view]];

location = [[CCDirector sharedDirector] convertToGL:location];

float angleDegree, angleRadian;

int direction=1;

float distanceX = ( (location.x/PTM_RATIO) - (barrel.position.x/PTM_RATIO) );

float distanceY = ( (location.y/PTM_RATIO) - (barrel.position.y/PTM_RATIO) );

if (fabsf(distanceX)>18*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth) ||

fabsf(distanceY)>18*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth))

{

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

return;

}

if(barrel.position.x<location.x)

{

angleRadian = atanf(distanceY/distanceX);

angleDegree = CC_RADIANS_TO_DEGREES(angleRadian);

}

else

{

angleRadian = atanf(distanceY/distanceX);

angleDegree =180 + CC_RADIANS_TO_DEGREES(angleRadian);

direction=-1;

}

barrel.rotation = (angleDegree*-1);

if (distanceX*distanceX+distanceY*distanceY>(17*(screenSize.height/designSizeHeight)*(screenSize.width/designSizeWidth)))

{

CGFloat angleTemp = atan2f(distanceY,distanceX);

CGPoint tempStandPos = [self scalePoint:ccp(35,135)];

CGPoint tempBarrelPos = [self scalePoint:ccp(65,165)];

location.x=tempBarrelPos.x+tempStandPos.y*cosf(angleTemp);

location.y=tempBarrelPos.y+tempStandPos.y*sinf(angleTemp);

}

crossHair.position = ccp(location.x, location.y);

distanceX = ( (crossHair.position.x/PTM_RATIO) - (slingPosition.x/PTM_RATIO) );

distanceY = ( (crossHair.position.y/PTM_RATIO) - (slingPosition.y/PTM_RATIO) );

float distance = sqrtf(distanceX*distanceX+distanceY*distanceY)*direction;

bulletStartingPosition = b2Vec2(slingPosition.x, slingPosition.y);

//bulletStartingVelocity = b2Vec2(cosf(angleRadian)*(distance/scaleFactorSpriteResolution),sinf(angleRadian)*(distance/scaleFactorSpriteResolution));

bulletStartingVelocity = b2Vec2(cosf(angleRadian)*(distance*10),sinf(angleRadian)*(distance*10));

if(sniperOn)

[self drawProjectilePath:b2Vec2(barrel.position.x, barrel.position.y) withVelocity:b2Vec2(cosf(angleRadian)*(distance*23.895),sinf(angleRadian)*(distance*23.895))];

// [self drawProjectilePath:bulletStartingPosition :b2Vec2(cosf(angleRadian)*distance*56.595,sinf(angleRadian)*distance*56.595)];

//[self drawProjectilePath:bulletStartingPosition :bulletStartingVelocity];

}

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

{

if(gamePaused )

{

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

return;

}

NSLog(@"ended");

if(!self.boulderFired)

{

[self createBullets:slingPosition];

bullet->SetActive(true);

NSLog(@"ending starting position %f and %f", bulletStartingPosition.x, bulletStartingPosition.y);

NSLog(@"ending began starting velocity %f and %f", bulletStartingVelocity.x, bulletStartingVelocity.y);

//bullet->ApplyForce(bulletStartingVelocity, bulletStartingPosition);

bullet->SetLinearVelocity(bulletStartingVelocity);

self.boulderFired = true;

[self enableGestureSwipes:true];

bulletStartingVelocity = b2Vec2(0,0);

bulletStartingPosition = b2Vec2(0,0);

}

}