1

I want to make trigger so that user can stretch the trigger and give the direction and then trigger hit to the ball and the ball will go accordingly.

The Ball speed and direction will depend on the trigger.

I am new in box2d.

Please check the link what I want.

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);





}

I am not able to make trigger and not able to apply physics on trigger image. How to apply physics on trigger body? And how the ballbody will move according to trigger?

4

1 回答 1

0

我已经实现了如下:

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

或者您可以从以下网址下载此代码:4shared.com/zip/PRv8c1Pz/BOX2D.html

于 2013-06-28T13:26:06.477 回答