2013-06-28 3 views
1

Je veux faire un déclic afin que l'utilisateur puisse étirer la gâchette et donner la direction et ensuite déclencher le coup à la balle et la balle ira en conséquence.Comment faire un corps étirable (trigger) et appliquer la physique sur elle dans box2d dans iphone?

La vitesse et la direction de la balle dépendent du déclencheur.

Je suis nouveau dans box2d.

S'il vous plaît vérifier le lien que je veux.

http://dc694.4shared.com/img/Nw7YYLNL/s7/pool.png?async&0.2852371991612017

-(id) init 
{ 
if((self=[super init])) { 

CGSize winSize = [CCDirector sharedDirector].winSize; 
// Create a world 
b2Vec2 gravity = b2Vec2(0.0f, 0.0f); 
_world = new b2World(gravity); 






// Create sprite and add it to the layer 
CCSprite *Trigger = [CCSprite spriteWithFile:@"Trigger.png"]; 
Trigger.position = ccp(10, 50); 
Trigger.tag = 1; 
[self addChild:Trigger]; 

// Create Trigger body 
b2BodyDef TriggerBodyDef; 
TriggerBodyDef.type = b2_dynamicBody; 
TriggerBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO); 
TriggerBodyDef.userData = ball; 
TriggerBody = _world->CreateBody(&TriggerBodyDef);  // b2Body * ballBody 

// Create circle shape 
b2CircleShape circle; 
circle.m_radius = 26.0/PTM_RATIO; 

// Create shape definition and add to body 
b2FixtureDef TriggerShapeDef; 
TriggerShapeDef.shape = &circle; 
TriggerShapeDef.density = 15.0f; 
TriggerShapeDef.friction = 2.f; 
TriggerShapeDef.restitution = 0.0f; 
_TriggerFixture = TriggerBody->CreateFixture(&TriggerShapeDef); 




b2Vec2 force = b2Vec2(10, -12); 
TriggerBody->ApplyLinearImpulse(force, TriggerBodyDef.position); 










///////////////////////// Ball /////////////////////////////// 

// Create sprite and add it to the layer 
CCSprite *ball = [CCSprite spriteWithFile:@"ball.png"]; 
ball.position = ccp(100, 200); 
ball.tag = 1; 
[self addChild:ball]; 

// Create ball body 
b2BodyDef ballBodyDef; 
ballBodyDef.type = b2_dynamicBody; 
ballBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO); 
ballBodyDef.userData = ball; 
ballBody = _world->CreateBody(&ballBodyDef);  // b2Body * ballBody 

// Create circle shape 
b2CircleShape circle; 
circle.m_radius = 26.0/PTM_RATIO; 

// Create shape definition and add to body 
b2FixtureDef ballShapeDef; 
ballShapeDef.shape = &circle; 
ballShapeDef.density = 15.0f; 
ballShapeDef.friction = 2.f; 
ballShapeDef.restitution = 0.0f; 
_ballFixture = ballBody->CreateFixture(&ballShapeDef); 




b2Vec2 force = b2Vec2(73, -52); 
ballBody->ApplyLinearImpulse(force, ballBodyDef.position); 

    //ballBody->SetLinearVelocity(b2Vec2(10,0)); // try 
// ballBody->SetAngularVelocity(0);   // try 


    ///////////////////////// Ball /////////////////////////////// 







// Create paddle and add it to the layer 
CCSprite *paddle = [CCSprite spriteWithFile:@"paddle.png"]; 
paddle.position = ccp(winSize.width/2, 50); 
[self addChild:paddle]; 

// Create paddle body 
b2BodyDef paddleBodyDef; 
paddleBodyDef.type = b2_staticBody;   //b2_staticBody, b2_dynamicBody 
paddleBodyDef.position.Set(winSize.width/2/PTM_RATIO, 50/PTM_RATIO); 
paddleBodyDef.userData = paddle; 
paddleBodyDef.angle = 75; 
_paddleBody = _world->CreateBody(&paddleBodyDef); 

// Create paddle shape 
b2PolygonShape paddleShape; 
paddleShape.SetAsBox(paddle.contentSize.width/PTM_RATIO/2, paddle.contentSize.height/ PTM_RATIO/2); 

// Create shape definition and add to body 
b2FixtureDef paddleShapeDef; 
paddleShapeDef.shape = &paddleShape; 
paddleShapeDef.density = 25.0f; 
paddleShapeDef.friction = 1.1f; 
paddleShapeDef.restitution = 0.1f; 
_paddleFixture = _paddleBody->CreateFixture(&paddleShapeDef); 






// Restrict paddle along the x axis 
b2PrismaticJointDef jointDef; 
b2Vec2 worldAxis(0.0f, 0.0f); 
jointDef.collideConnected = true; 
jointDef.Initialize(_paddleBody, _groundBody, _paddleBody->GetWorldCenter(), worldAxis); 
_world->CreateJoint(&jointDef); 


[self schedule:@selector(tick:)]; 
self.touchEnabled = YES; 
} 



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

if (_mouseJoint != NULL) return; 

UITouch *myTouch = [touches anyObject]; 
CGPoint location = [myTouch locationInView:[myTouch view]]; 
location = [[CCDirector sharedDirector] convertToGL:location]; 
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO); 

if (_paddleFixture->TestPoint(locationWorld)) { 

b2MouseJointDef md; 

md.bodyA = _groundBody; 
md.bodyB = _paddleBody; 
md.target = locationWorld; 
md.collideConnected = true; 
md.maxForce = 1000.0f * _paddleBody->GetMass(); 

_mouseJoint = (b2MouseJoint *)_world->CreateJoint(&md); 
_paddleBody->SetAwake(true); 
} 

// [self kick]; 
} 

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

if (_mouseJoint == NULL) return; 

UITouch *myTouch = [touches anyObject]; 
CGPoint location = [myTouch locationInView:[myTouch view]]; 
location = [[CCDirector sharedDirector] convertToGL:location]; 
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO); 

_mouseJoint->SetTarget(locationWorld); 





} 

Je ne suis pas en mesure de faire déclencheur et non en mesure d'appliquer la physique sur l'image de déclenchement. Comment appliquer la physique sur le corps de la gâchette? Et comment le ballon va se déplacer selon la détente?

Répondre

0

J'ai mis cela comme suit:

HelloWorldLayer.h

#import "cocos2d.h" 
#import "Box2D.h" 
#define PTM_RATIO 32.0 

@interface HelloWorldLayer : CCLayer { 
    b2World *_world; 
    b2Body *_body; 
    CCSprite *_ball; 
    CGPoint firstlocation; 
    CGPoint lastlocation; 
    b2Vec2 pre_velocity; 

} 

+ (id) scene; 
- (void)kick; 
@end 

HelloWorldLayer.m

#import "HelloWorldLayer.h" 

@implementation HelloWorldLayer 

+ (id)scene { 

    CCScene *scene = [CCScene node]; 
    HelloWorldLayer *layer = [HelloWorldLayer node]; 
    [scene addChild:layer]; 
    return scene; 

} 

- (id)init { 

    if ((self=[super init])) { 
     CGSize winSize = [CCDirector sharedDirector].winSize; 
     _ball = [CCSprite spriteWithFile:@"ball.png" rect:CGRectMake(0, 0, 52, 52)]; 
     _ball.position = ccp(100, 100); 
     [self addChild:_ball]; 

     //create world 
     b2Vec2 gravity = b2Vec2(0.0f, -8.0f); 
     _world = new b2World(gravity); 

     // Create ball body and shape 
     b2BodyDef ballBodyDef; 
     ballBodyDef.type = b2_dynamicBody; 
     ballBodyDef.position.Set(26/PTM_RATIO, 26/PTM_RATIO); 
     ballBodyDef.userData = _ball; 
     _body = _world->CreateBody(&ballBodyDef); 

     b2CircleShape circle; 
     circle.m_radius = 26.0/PTM_RATIO; 

     b2FixtureDef ballShapeDef; 
     ballShapeDef.shape = &circle; 
     ballShapeDef.density = 1.0f; 
     ballShapeDef.friction = 0.2f; 
     ballShapeDef.restitution = 0.8f; 
     _body->CreateFixture(&ballShapeDef); 

     //ground edge 
     b2BodyDef groundBodyDef; 
     groundBodyDef.position.Set(0,0); 

     b2Body *groundBody = _world->CreateBody(&groundBodyDef); 
     b2EdgeShape groundEdge; 
     b2FixtureDef boxShapeDef; 
     boxShapeDef.shape = &groundEdge; 

     //wall definitions 
     groundEdge.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0)); 
     groundBody->CreateFixture(&boxShapeDef); 
     groundEdge.Set(b2Vec2(0,0), b2Vec2(0,winSize.height/PTM_RATIO)); 
     groundBody->CreateFixture(&boxShapeDef); 

     groundEdge.Set(b2Vec2(0, winSize.height/PTM_RATIO), 
         b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO)); 
     groundBody->CreateFixture(&boxShapeDef); 

     groundEdge.Set(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), 
         b2Vec2(winSize.width/PTM_RATIO, 0)); 
     groundBody->CreateFixture(&boxShapeDef); 

     [self schedule:@selector(tick:)]; 
     // [self schedule:@selector(kick) interval:3.0]; 
     self.isTouchEnabled = YES; 
     self.isAccelerometerEnabled = YES; 
    } 
    return self; 
} 
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{ 
    b2Vec2 gravity(acceleration.y * 30, -acceleration.x * 30); 
    _world->SetGravity(gravity); 
} 
- (void)tick:(ccTime) dt { 

    _world->Step(dt, 10, 1); 
    for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {  
     if (b->GetUserData() != NULL) { 
      CCSprite *ballData = (CCSprite *)b->GetUserData(); 
      ballData.position = ccp(b->GetPosition().x * PTM_RATIO, 
            b->GetPosition().y * PTM_RATIO); 

      ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()); 


     }   
    } 

} 
- (void)kick { 
    b2Vec2 force = b2Vec2(-30, 30); 
    _body->ApplyLinearImpulse(force,_body->GetPosition()); 
} 

- (void)ccTouchesBegan:(NSSet *)touch withEvent:(UIEvent *)event { 
    /* b2Vec2 force = b2Vec2(-30, -30); 
    _body->ApplyLinearImpulse(force, _body->GetPosition());*/ 
    UITouch *touchpoint = [touch anyObject]; 
    firstlocation = [touchpoint locationInView:[touchpoint view]]; 
    firstlocation = [[CCDirector sharedDirector] convertToGL:firstlocation]; 

} 
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 
    UITouch *touchpoint = [touches anyObject]; 
    lastlocation = [touchpoint locationInView:[touchpoint view]]; 
    lastlocation = [[CCDirector sharedDirector] convertToGL:lastlocation]; 
    //NSLog(@"start location %2f %2f",firstlocation.x,firstlocation.y); 
    //NSLog(@"last location %2f %2f",lastlocation.x,lastlocation.y); 
    GLfloat y = firstlocation.y - lastlocation.y; 
    GLfloat x = firstlocation.x - lastlocation.x; 

    GLfloat lengthOfFlick = sqrt(x*x + y*y); 
    NSLog(@"%2f",lengthOfFlick); 
/* GLfloat basAngle = atan2(-x, -y); 
    GLfloat radians = (basAngle + (180/3.14)); 
    //GLfloat angle = 180 + radians;*/ 

    //GLfloat theta = atan2(y,x)* 180/3.14; 

    //NSLog(@"theta: %2f",theta); 
    float ratio = lengthOfFlick/90; 
    NSLog(@"%f",ratio); 
    if(ratio > 1){ 
     ratio = 1; 
    } 
    NSLog(@"%f",ratio); 
    if(firstlocation.x > lastlocation.x){ 
     if(firstlocation.y > lastlocation.y){ 
      b2Vec2 force = b2Vec2((int)(45 * ratio),(int)(45 * ratio)); 

      _body->ApplyLinearImpulse(force, _body->GetPosition()); 
     }else{ 
      b2Vec2 force = b2Vec2((int)(-1 * 45 * ratio), (int)(45 * ratio)); 
      _body->ApplyLinearImpulse(force, _body->GetPosition()); 
     } 
    }else{ 
     if(firstlocation.y > lastlocation.y){ 

      b2Vec2 force = b2Vec2((int)(-1 * 45 * ratio),(int)(45 * ratio)); 
      _body->ApplyLinearImpulse(force, _body->GetPosition()); 
     }else{ 

      b2Vec2 force = b2Vec2((int)(-1* 45 * ratio),(int)(-1 * 45 * ratio)); 

      _body->ApplyLinearImpulse(force, _body->GetPosition()); 
     } 
    } 

} 
-(void)dealloc{ 
    delete _world; 
    _body = NULL; 
    _world = NULL; 
    [super dealloc]; 
} 


@end 

Ou vous pouvez télécharger ce code de: 4shared.com /zip/PRv8c1Pz/BOX2D.html

Questions connexes