Box2d SetLinearVelocity奇怪的问题

Box2d SetLinearVelocity weird issue

本文关键字:问题 SetLinearVelocity Box2d      更新时间:2023-10-16

我正试图让一个b2body对象以恒定的速度跟随触摸位置,但我在"y"轴上遇到了问题,在该轴上,物体会移动到"屏幕的另一半"上的位置就像镜像。。。"x"轴很好。(我使用的是cocos2d 1.0.0)

这是所有的代码:

HelloWorldLayer.h

#import "cocos2d.h"
#import "Box2D.h"
#define PTM_RATIO 32.0
@interface HelloWorldLayer : CCLayer {
    b2World *_world;
    b2Body *_body;
    CCSprite *_ball;
}
+ (id) scene;
@end

HelloWorldLayer.m

#import "HelloWorldLayer.h"
#import "CGPointExtension.h"
static CGPoint location;
@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;
        // Create sprite and add it to the layer
        _ball = [CCSprite spriteWithFile:@"ball.png" rect:CGRectMake(0, 0, 52, 52)];
        _ball.position = ccp(100, 300);
        [self addChild:_ball];
        // Create a world
        b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
        _world = new b2World(gravity);
        // Create edges around the entire screen
        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);
        // Create ball body and shape
        b2BodyDef ballBodyDef;
        ballBodyDef.type = b2_dynamicBody;
        ballBodyDef.position.Set(100/PTM_RATIO, 300/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);
        [self schedule:@selector(tick:)];
        [self setTouchEnabled:YES];
        [self setAccelerometerEnabled:YES];
    }
    return self;
}
- (void)tick:(ccTime) dt {
    int32 velocityIterations = 8;
    int32 positionIterations = 1;
    _world->Step(dt, velocityIterations, positionIterations);
    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)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [[event allTouches] anyObject];
     location = [touch locationInView:touch.view];
    NSLog(@"%@", NSStringFromCGPoint(location));

}
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [[event allTouches] anyObject];
    location = [touch locationInView:touch.view];
    [self schedule:@selector(asd:)];

}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
   // [self unschedule:@selector(asd:)];
   // _body->SetLinearVelocity(b2Vec2(0,0));
   // _body->SetAngularVelocity(0);
    //_body->SetActive(false);
}
-(void)asd:(ccTime) dt {
    NSLog(@"%@", NSStringFromCGPoint(location));
    //float ca = location.y;
        b2Vec2 convertedLocation = b2Vec2(location.x/PTM_RATIO - _body->GetPosition().x, location.y/PTM_RATIO - _body->GetPosition().y);
        //b2Vec2 toTouchPoint = convertedLocation - _body->GetPosition();
        convertedLocation.Normalize();
        b2Vec2 impulse = 5 * convertedLocation;
        _body->SetLinearVelocity(impulse);
     //  _body->ApplyLinearImpulse(_body->GetMass() * impulse, _body->GetWorldCenter());


}

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

提前感谢!

使用locationInView从触摸中获取位置时,原点位于左上角。其中,as in cocos2D原点位于左下角。可以翻转y值。或者您也可以使用CCDirector的ConvertToGL功能。我更喜欢后者,主要是因为它可以处理所有的人像和风景模式。

CGPoint loc = [touch locationInView:touch.view]
location = [[CCDirector sharedDirector] convertToGL:loc];