javaprocessingbox2djbox2d

How to have the screen/camera follow a box2d body as it moves


I am trying to learn how to use box2d (a lot of this code is unashamedly stolen from the legend Dan Shiffman) so I have created a small "game" where a ball rolls in Perlin noise terrain. The obvious problem with my code is that quite quickly the ball just rolls off the screen. I know I will have to change my terrain generation as it won't keep generating as the screen moves but for now I would like to know how to get the screen to move in the first place. I want to keep the the circles x value in the center of the screen.

I have found several similar questions where the answer was to move the world but that seems like a bad idea with box2d. I also found someone mentioning a camera? class but I am a beginner and have no idea what that is or how to use it.

Some of the main code:


void setup() {
  size(1000,800);
  smooth();
  frameRate(30);
  sw = new StopWatchTimer();
  sw.start();

  box2d = new Box2DProcessing(this);
  box2d.createWorld();

  p = new player(10,10,10);

  surface = new Surface();

  grav = -50;
  box2d.setGravity(0, grav);

}

void draw() {

  background(200);

  //text(sw.second(),100,100);

  box2d.step();
  surface.display();
  time();
  keyTyped();

  box2d.setGravity(0, grav);

  p.display();
  prePos = p.getPos();
}

Some code from the player class:

player(float x, float y, float r_) {
    r = r_;

    makeBody(x, y, r);
    body.setUserData(this);
    col = color(175);
  }


  public void makeBody(float x, float y, float r) {

    BodyDef bd = new BodyDef();

    bd.position = box2d.coordPixelsToWorld(x, y);
    bd.type = BodyType.DYNAMIC;
    body = box2d.createBody(bd);


    cs = new CircleShape();
    cs.m_radius = box2d.scalarPixelsToWorld(r);

    fd = new FixtureDef();
    fd.shape = cs;

    fd.density = 5;
    fd.friction = 1;
    fd.restitution = .3;


    body.createFixture(fd);

}

I am well aware this question is really poorly asked but I was unsure which code would be needed and i'm not a very articulate person so if any clarification or more code is needed to make this understandable don't hesitate to yell at me for it.


Solution

  • You could use the translate() command. You would put in draw with the coordinates of the player as parameters. I assume that p.getPos() returns a PVector. If this is the case, then draw would look like this:

    void draw() {
      pushMatrix()
      translate(p.getPos().x+width/2,p.getPos().y+height/2); // <--Added Line
      background(200);
    
      //text(sw.second(),100,100);
    
      box2d.step();
      surface.display();
      popMatrix()
      time();
      keyTyped();
    
      box2d.setGravity(0, grav);
    
      p.display();
      prePos = p.getPos();
    }