0
votes

I have a little issue with my game. In my main game scene I create a Player object from a class, like this:

player = [Player spriteWithFile:@"[email protected]"];        
player.position = ccp(100.0f, 180.0f);
[player createBox2dObject:world];

Below is the main chunk of my small Player class that creates the body and the fixture so I can use it in a box2d world.

b2BodyDef playerBodyDef;
playerBodyDef.type = b2_dynamicBody;
playerBodyDef.position.Set(self.position.x/PTM_RATIO, self.position.y/PTM_RATIO);
playerBodyDef.userData = self;
playerBodyDef.fixedRotation = true;
playerBodyDef.linearDamping = 4.0;

body = world->CreateBody(&playerBodyDef);

b2CircleShape circleShape;
circleShape.m_radius = 0.7;
b2FixtureDef fixtureDef;
fixtureDef.shape = &circleShape;
fixtureDef.density = 1.0f;
fixtureDef.friction = 1.0f;
fixtureDef.restitution =  1.0f;

body->CreateFixture(&fixtureDef);

The result of this code is a Box2d object with [email protected] over it. When I move a joystick, a Box2D impulse is applied and the player moves. Simple enough, right? In non-retina displays, this works fine. However, when I switch to Retina in the simulator, [email protected] is created a little higher and farther to the right, not over the Box2D circle. Then, gravity is applied and they both fall down to the platform. [email protected] falls twice as fast. When I move the joystick, the Box2D circle moves, but [email protected] moves twice as fast and the camera follows it, soon leaving the circle off the screen. I doubt this issue has really anything to do with the code I have here, I feel like its a scaling issue hidden somewhere in my game. Does anyone have suggestions?

Edit: I move the sprite with:

[player moveRight];

This is moveRight in the player class:

-(void) moveRight {
    b2Vec2 impulse = b2Vec2(2.0f, 0.0f);
    body->ApplyLinearImpulse(impulse, body->GetWorldCenter());
}

Shouldn't be any issue here, right?

Edit (again):

Here's my update: method-

- (void) update:(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 *myActor = (CCSprite*)b->GetUserData();
            myActor.position = CGPointMake( b->GetPosition().x *PTM_RATIO, 
                                       b->GetPosition().y * PTM_RATIO);
            myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
        }   
    }
    b2Vec2 pos = [player body]->GetPosition();
    CGPoint newPos = ccp(-1 * pos.x * PTM_RATIO + 50, self.position.y * PTM_RATIO); 
    [self setPosition:newPos];
}

I have a feeling that the issue is somewhere in here. I've tried changing PTM_RATIO around, but it doesn't affect the speed. Any ideas?

Edit: see comment below, almost have this figured out

1
Not at all... I was looking for your frame method where you update the sprite position based on where the box2d body's position.Jer In Chicago
Not sure if this changes what you are trying to accomplish, but also maybe try body->SetLinearVelocity(impulse);Jer In Chicago
I tried replacing my ApplyLinearImpulse line with that, but nothing changes (except the speed is much slower). What do you mean by updating my sprites position by the body? Are you saying that every frame I have to set the sprite's position to the body? Thanks for the help so far, by the way.nick
No problem. Basically you should have some code in a frame, tick, or update method that updates a sprite's position to follow the box2d body... I'm editing my question below with an example of the code I'm looking forJer In Chicago
Actually I think I may have this figured out. Basically, in retina mode, I need to change PTM_RATIO to 16, but on older screens it needs to stay at 32. I could probably perform a check to see which number it should use, but that would happen every frame and it would be messy. Do you know of a way to make a superglobal variable that I could set in my applicationDidStart: that I could use exactly like PTM_RATIO (which is #define'd)?nick

1 Answers

1
votes

You problem probably stems from the fact you are using a @2x image... Read, http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:how_to_develop_retinadisplay_games_in_cocos2d

There it states:

WARNING: It is NOT recommend to use the ”@2x” suffix. Apple treats those images in a special way which might cause bugs in your cocos2d application.

So to solve your problem read through the information on using png files with the -hd suffix.

For the comment:

Do you have some code that looks something like...

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

See how the code loops through all the box2d bodies in the word and sets the position of the sprite that is associated with the box2d body?