1
\$\begingroup\$

I'm working on my player object for my game.

PhysicsBodyDef def;
def.fixedRotation = true;
def.density = 1.0f;
def.position = Vec2(200.0f, 200.0f); 
def.isDynamic = true;
def.size = Vec2(50.0f,200.0f);

m_player.init(def,&m_physicsEngine.getWorld());

This is how he moves:

b2Vec2 vel = getBody()->GetLinearVelocity();
float desiredVel = 0;

if (m_keys[ALLEGRO_KEY_A] || m_keys[ALLEGRO_KEY_LEFT])
{
    desiredVel = -5;
}
else if (m_keys[ALLEGRO_KEY_D] || m_keys[ALLEGRO_KEY_RIGHT])
{
    desiredVel = 5;
}
else
{
    desiredVel = 0;
}

float velChange = desiredVel - vel.x;
float impulse = getBody()->GetMass() * velChange; //disregard time factor
getBody()->ApplyLinearImpulse( b2Vec2(impulse,0), getBody()->GetWorldCenter(),true);

This creates a few problems. First, to move the player at a constant speed he must be given a high velocity. The problem with this is if he just comes in contact with a small box, he makes it move a lot.

Now, I can fix this by lowering his density, but then comes my main issue: I need other objects to be able to run into him, but when they do, he should be like a static wall and not move.

I'm not sure how to do that without high density. I cannot use collision groups since I still need him to be solid toward other dynamic things.

How can this be done? Essentially, how do I prevent other dynamic bodies from affecting the player's velocity?

\$\endgroup\$
2
\$\begingroup\$

First

If you don't want the "small box" to move a lot just increase it's density a lot. Why not do that?

Other than the obvious:

If I recall correctly, you can detect collisions in Box2d (i.e. set a callback) and there return false to not have the collision handled by the physics system. I think you could have it so when certain things collide with the player, the player does not move at all while when other things collide with her, the behavior is different.

\$\endgroup\$
  • 1
    \$\begingroup\$ Use the mask field to set which type of object is that. On a callback on the player, detect if that two type of fixtures should collide, if not, then handle it properly to make the character not move. \$\endgroup\$ – Gustavo Maciel Jun 4 '14 at 2:52
1
\$\begingroup\$

Short answer: you can't. Not as long as the player is represented by a dynamic physics body.

You should rather make the player a kinematic body and directly set the player's velocity every time before stepping the physics world - this is essentially the same what applying impulse does, but you have more control over the actual velocity if you do set velocity manually. For example you no longer need to factor in mass/density in the equation, which should make your body move on a "points per frame" basis and not require a high impulse force.

\$\endgroup\$
  • \$\begingroup\$ What about gravity? \$\endgroup\$ – jmasterx Jan 4 '14 at 14:22
  • \$\begingroup\$ just add gravity vector to velocity every frame \$\endgroup\$ – LearnCocos2D Jan 4 '14 at 15:57
  • 1
    \$\begingroup\$ but wouldn't that mean he'd have to handle player collisions with floors and walls differently? \$\endgroup\$ – wolfdawn Jun 3 '14 at 19:25
1
\$\begingroup\$

Have 2 bodies for your player, one that is dynamic and one that is kinematic, connected by a weld joint. Use collision groups so these two bodies do not collide with each other. Also use the collision groups so that the kinematic body only interacts with things that shouldn't influence the players movement, and use the dynamic body for ones that should.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.