This is entirely possible in Box2d, but requires some work to get it going.
A game I am working on, called Space Spiders Must Die!, required "space spiders" to be able to walk on Astroids, jumping between them.
The first thing you will need are waypoints. These are the points, either on the body you want to move around, or in your case, right next to your walls, that you want your character to move along. Having the points be "static" (not on a moving body) cuts down the work tremendously.
Suppose you want to move between two points, p0 and p1, over time T. Your time step is dT (fixed). It is tempting to use SetTransform(...) on the body, doing something like:
// Initialize for new points
int steps = T/dT;
Vec2 toTarget = p1-p0;
toTarget.Normalize();
int stepsTaken = 0;
float32 bodyAngle = atan2f(toTarget.y,toTarget.x)
// Each time step
stepsTaken++;
Vec2 pos = p0 + stepsTaken*dT*toTarget;
body.SetTransform(pos,bodyAngle);
if(stepsTaken >= steps)
{
// Set up next set of points.
}
HOWEVER, if you do this, I believe you will find that the physics engine no longer interacts with your body for collisions. I believe this is because SetTransform(...) causes the engine to "miss a beat" with regard to collision detection.
So, the solution that I found was to create a b2PrismaticJoint at p0, attached to the body, and pointing in the direction of p1. The maximum length of the joint was set to the distance between the points.
This is the code from the project I did this in:
void CreateNextMovingJoint(float32 motorStrength = 1.0f)
{
b2PrismaticJointDef jointDef;
// We need to figure out some geometry here.
_pathIter = _pathDataList.begin();
PATH_DATA_T& pd = *_pathIter;
_pathIter++;
// Anchor
Vec2 pAnchor = pd.point;
// End point of the anchor, used for the axis.
Vec2 pEnd = pd.point + pd.distToNext[_direction]*pd.normalAlongPath[_direction];
jointDef.bodyA = _bodyMovingOn;
jointDef.bodyB = _bodyMoving;
jointDef.localAnchorA = pAnchor;
jointDef.localAnchorB = Vec2(0.0,0.0);
jointDef.localAxisA = pEnd-pAnchor;
jointDef.referenceAngle = 0;
jointDef.enableMotor = true;
jointDef.enableLimit = true;
jointDef.motorSpeed = _maxSpeed;
jointDef.maxMotorForce = motorStrength*(_maxSpeed/4)*_bodyMoving->GetMass();
jointDef.lowerTranslation = -0.1*pd.distToNext[_direction];
jointDef.upperTranslation = 1.1*pd.distToNext[_direction];
jointDef.collideConnected = true;
_bodyMoving->GetWorld()->CreateJoint(&jointDef);
}
After each update of the physics engine, you need to check how close the moving body is to the next point. When it gets close enough, destroy the existing prismatic joint and create a new one to the next point.
This is part of a larger code base, but the idea should be well represented here. In my case, I stored all the data for each point-point segment in something called PATH_DATA_T structures. There was a list of them which I iterated over. When the spider gets close to the next point, the iterator moves to the next element and works off that. This worked VERY well (see video here).
Was this helpful?