Phys2D usage questions:

This is my farthest attempt into making a playable game. I have played around with some C++ engine like Orger3D, and have the basics of a game with a server, but I have no 3D talent, so I decided to try Java and 2D game. I have yet to finish and release a game so I am sorry if my questions are obvious or just common knowledge. I have spent at least 1 hour trying to solve the following questions. This is also my first time playing with a physics engine.

I am looking to make some top down 2d game, not sure what I want to make but I have some things I know will need to be done. I currently have the world gravity set to 0, so things just ‘float’ around.

  1. I have ‘space ship’ movement easy with setDamping(0f), ‘water’ simulation with setDamping(1f) (with my mass of 200) and then addForce(new Vector2f(0,-10000)) every loop. I would like to know the proper way to do person movement. I tried:

(delta = time since last loop)
float distance = (delta * 100) / 1000;
body.move(getX(), getY()+(-1f*distance));

this works fine except I will get a second lag (garbage collection?) and go right over my collision wall. Should I just make sure the movement isn’t over some amount (those with slower computers are slower in game)? I could do more stepping (does it work with move?) but that just adds more jerking in the end. I doubt “creating a line the length of my movement and checking it for collision, if no collision then move” would be a good idea…

  1. I was wondering how I could do per pixel collision. In the end I may have a destroyable terrain (think worms).
    I notice there is an addBitMap(), setBitMap() … options but not sure how to use them or if I can even use them like that.
    If I can’t use bitmask setting, I was thinking of making a collision object the same shape as my image my using lines, like in the gear demo (though gears demo used a formula). I was going to check the image and find the ‘outside’ points and feed the points into a collision object.
    Another way is just do circle/square collision, and if collision detected, do my own per pixel doing bitmask compare (examples on net). Problem is I do not think I can use the Phys2D ‘world’, and would have to manage the collision space myself, or is there a way to get around this?

  2. I might want to have tank(s) or car(s). Water isn’t bad because it does not have ridged turning but ‘slides’. I would like friction on the bottom, not just against other objects (or can I use a collision object to do this?). I could simulate sliding when the energy, other then the direction I am facing, gets to some point, I apply more energy or something… If I made a side scroller it woudl be cool because I could just attach tires to body and then turn the tire.

  3. Is world.getContacts(body); function thread safe? I was going to complicate things with threads and make things more interesting.

  4. If I make a space shooter I would like planets to have their ‘own’ gravity. I thought I read a comment on this and the solution was to attach springs to every object in range that got stronger the closer they were. I was thinking if there is no built in ‘world’ way to give object gravity, I would just have to check every body and if it is close to a gravity object, apply force based on distance.

Thats it for now and I hope I can still use Phys2D to do some of these. Granted I have no fixed idea what I will be making so I may make a game to fit the requirements than the other way around.

  1. You should be updating the world, not attempting to move bodies independently. if you’ve applied force then the world update will cause the movement (and make other things respond). There may be GC issues to discover, but more complicated sims have been written already without the issue showing.

  2. There’s no per pixel collision in phys2d, infact there’s no concept of a collision. The bit masks are used to define groups of bodies that can collide.

  3. Friction can be applied to any body - the “floor” would be a body - so the cars/tanks would slide against it.

  4. Phys2D is in no way thread safe. It’s all intended to be run in a single thread by calling world.update()

  5. There’s no way to add gravity production to bodies. Springs would also look very strange. Your approach sounds more appropriate.

Kev

Thank you for the quick replay.

  1. After posting I thought of something, I swear that submit button raises my IQ to like 200 for 1 second (happens all the time, sorry)
    setDamping(1f);
    addForce(new Vector2f(0,-10000));
    to
    body.setDamping(100f);
    body.addForce(new Vector2f(0,-1000000));

now it moves ‘like’ a person, I will lower those values till I find a good one.

  1. darn, so if I ever plan to make a worms type game I will make up my own collision library I guess. So what I call collision is: world.getContacts(this.body) , where one detects is body A has ‘touched’ body B.

  2. Since it is top down, the floor would be below my object, how can I have it apply the friction but not bounce off the ‘walls’ of the object. Say I have a “carboat” that drives 50x on land and has no sliding left/right, but 30x on water and slides all over. Also does Phys2D have a concept of front back back? if someone hits it on the side it should not slide much, as opposed to hitting the front and back.

  3. Thanks, I can easly thread sounds and GUI stuff…

  4. now I just need to make a “get list of objects within circle range” function.

To me it seems Phys2d is more geared toward a side scroller than a overhead game, but not impossible. Perhaps a clone of http://xmoto.tuxfamily.org/ in Java, multi player, and car(s) might be fun…

Thats dead right. A top down game implies 3 dimensions really, given the floor is in at a different z to the players/units. Phys2D is strictly a 2D engine. For interest, the original source of Phys2D has been released as a C++ engine (Box2D) which is in the process of being ported by another group. It may be more able to deal with your use cases - though I haven’t seen any info on the project as yet.

Kev

Good point on the top down being really 3d, never really thought of it in that way.

Well now that I know what Phys2d was meant to do, I can use it for a future side scrolling shooter, but use a 3d library or roll my own (so many examples on net) for a Zelda/FF/Diablo/NWN type game.

I thought that Phys2D was an implementation of Box2D and not the other way around. I saw http://www.box2d.org/forum/viewtopic.php?f=5&t=36 earlier, but just thought it was someone with time on their hands reinventing Phys2D in a different way. I will go look at what Box2D has over Phys2D

I wanted to thank you for making a great physics engine. I find it easy to use as long as I don’t try to use it for something it was not made to do. Right now I am still playing around with lwjgl, logl, and java2d rendering. If I decided on a game that can use Phys2D I will look forward to using it.

Thats what I meant btw, the original source of Phys2D - rather than the original src. To be clear, Phys2D is based on the original Box2D demo by Erin.

Kev

Hi there - I’m one of the people working on the new Java port of (the new) Box2D. quixote_arg is working on it, too, and for now it’s just the two of us.

Just to clarify, Phys2d is a port/reworking of the older Box2d engine, which is now being referred to as Box2D Lite. The Lite engine was basically a proof of concept/educational project (it was missing a lot of features), so Erin Catto finally decided to throw together a real full featured and actively maintained engine in C++. My only introduction to the old Box2d was Phys2d, and I was very impressed, so I figured that it was worth some time to getting the new one working in Java.

I’m not exactly sure of the feature differences between the two - I know the new one has polygons and circles, as well as all types of joints, and does friction, world gravity, and that type of stuff. I’m not sure how much of this was in the old one before the reworking into Phys2d, I’ve heard people say that the Lite version had no polygons. One of the things I’m really looking forward to is that Erin has promised to add continuous collision detection to the engine - this means no more tunneling, assuming it works. But I’m pretty sure this one doesn’t have anything that would make doing an overhead driving thing work any easier, though, and I don’t think there are inter-body gravity forces. These are certainly things you could code up yourself, though, but you could probably do it just as easy with Phys2d, which is a lot more stable, especially right now.

As far as speed, the new Box2d has been highly optimized in the C++ version, and should run a good deal faster than the Lite one; however, we’re still completely unsure how these gains will translate to Java, since a lot of the C++ optimizations have to do with memory handling. Once we’re all set, it might be worth comparing it to Phys2d to see if the algorithms are actually faster or if most of the improvement gets lost in the porting.

In any case, our port is now about 95% working, but we’ve still got to iron out some bugs, update it to sync up with the newest C++ code (Erin works FAST), and optimize it a bit for Java. I’m guessing we’ll do a first “release” once we’ve updated it, but before the optimizations. The project lives at http://sourceforge.net/projects/jbox2d and the source is all there now, but beware, it’s changing quickly. I’ll send a message over here when it’s done so you guys can check it out.

Great stuff, really looking forward to the java version of the new Box2D! Continuous collision - really!? Awesome stuff! :slight_smile:

Can’t wait!

Kev

Yes, I want to see it too! Hurry up you guys! :stuck_out_tongue:

im trying to use phys2D on a 3D rendered game… hope it works

edit: seems to work fine, but since im rendering the 3D images, i can’t see the physics circles and boxes. makes it abit hard to sync the 3D stuffs and the “2D bounding box/circle”

When i debug my Phys2D stuff with LWJGL, i draw the 3D. Then i desable the depth buffer and i draw the physic object from the world data (showWorld) :

  protected void showBody(Body body)
  {
    if (body.getShape() instanceof Box)
    {
//			drawBoxBody(g,body,(Box) body.getShape());
    }
    if (body.getShape() instanceof Circle)
    {
	drawCircleBody(body,(Circle) body.getShape());
    }
    if (body.getShape() instanceof Line)
    {
      drawLineBody(body,(Line) body.getShape());
    }
    if (body.getShape() instanceof Polygon)
    {
//	drawPolygonBody(g,body,(Polygon) body.getShape());
    }
  }
  
  protected void drawCircleBody(Body body, Circle circle)
  {
    GL11.glColor3f(1.0f,1.0f,1.0f);

    float x = body.getPosition().getX();
    float y = body.getPosition().getY();
    float r = circle.getRadius();
    float rot = body.getRotation();
    float xo = (float) (Math.cos(rot) * r);
    float yo = (float) (Math.sin(rot) * r);
		
    //g.drawOval((int) (x-r),(int) (y-r),(int) (r*2),(int) (r*2));
    //g.drawLine((int) x,(int) y,(int) (x+xo),(int) (y+yo));
    
    GL11.glBegin(GL11.GL_LINES);
          GL11.glVertex3f(x+r,y,0.0f);
          for(int i=1;i<8;i++)
          {
            GL11.glVertex3f(x+r*(float)Math.cos(i*Math.PI/4),y+r*(float)Math.sin(i*Math.PI/4),0.0f);
            GL11.glVertex3f(x+r*(float)Math.cos(i*Math.PI/4),y+r*(float)Math.sin(i*Math.PI/4),0.0f);
          }
          GL11.glVertex3f(x+r,y,0.0f);
    
          GL11.glVertex3f(x,y,0.0f);
          GL11.glVertex3f(x+xo,y+yo,0.0f);
    GL11.glEnd();
    
    GL11.glColor3f(1.0f,1.0f,0.0f);
    
   /* float fx = body.getVelocity().getX()/10.0f;
    float fy = body.getVelocity().getY()/10.0f;
    
    System.out.println(fx+"-"+fy);
    
    GL11.glBegin(GL11.GL_LINES);
          GL11.glVertex3f(x,y,0.0f);
          GL11.glVertex3f(x+fx,y+fy,0.0f);
    GL11.glEnd();*/
  }
  
  protected void drawLineBody(Body body, Line line)
  {
    GL11.glColor3f(1.0f,1.0f,1.0f);

    Vector2f[] verts = line.getVertices(body.getPosition(), body.getRotation());
    
    GL11.glBegin(GL11.GL_LINES);
          GL11.glVertex3f(verts[0].getX(),verts[0].getY(),0.0f);
          GL11.glVertex3f(verts[1].getX(),verts[1].getY(),0.0f);
    GL11.glEnd();
  }
  
  protected void showJoint(Joint j)
  {
    if (j instanceof FixedJoint)
    {
	FixedJoint joint = (FixedJoint) j;
			
        GL11.glColor3f(1.0f,0.0f,0.0f);
	float x1 = joint.getBody1().getPosition().getX();
	float x2 = joint.getBody2().getPosition().getX();
	float y1 = joint.getBody1().getPosition().getY();
	float y2 = joint.getBody2().getPosition().getY();
		
        GL11.glBegin(GL11.GL_LINES);
          GL11.glVertex3f(x1,y1,0.0f);
          GL11.glVertex3f(x2,y2,0.0f);
        GL11.glEnd();
     }
/*		if (j instanceof BasicJoint) {
			BasicJoint joint = (BasicJoint) j;
			
			Body b1 = joint.getBody1();
			Body b2 = joint.getBody2();
	
			Matrix2f R1 = new Matrix2f(b1.getRotation());
			Matrix2f R2 = new Matrix2f(b2.getRotation());
	
			ROVector2f x1 = b1.getPosition();
			Vector2f p1 = MathUtil.mul(R1,joint.getLocalAnchor1());
			p1.add(x1);
	
			ROVector2f x2 = b2.getPosition();
			Vector2f p2 = MathUtil.mul(R2,joint.getLocalAnchor2());
			p2.add(x2);
	
			g.setColor(Color.red);
			g.drawLine((int) x1.getX(), (int) x1.getY(), (int) p1.x, (int) p1.y);
			g.drawLine((int) p1.x, (int) p1.y, (int) x2.getX(), (int) x2.getY());
			g.drawLine((int) x2.getX(), (int) x2.getY(), (int) p2.x, (int) p2.y);
			g.drawLine((int) p2.x, (int) p2.y, (int) x1.getX(), (int) x1.getY());
		}
		if (j instanceof SpringJoint) {
			SpringJoint joint = (SpringJoint) j;
			
			Body b1 = joint.getBody1();
			Body b2 = joint.getBody2();
	
			Matrix2f R1 = new Matrix2f(b1.getRotation());
			Matrix2f R2 = new Matrix2f(b2.getRotation());
	
			ROVector2f x1 = b1.getPosition();
			Vector2f p1 = MathUtil.mul(R1,joint.getLocalAnchor1());
			p1.add(x1);
	
			ROVector2f x2 = b2.getPosition();
			Vector2f p2 = MathUtil.mul(R2,joint.getLocalAnchor2());
			p2.add(x2);
			
			g.setColor(Color.red);
			g.drawLine((int) x1.getX(), (int) x1.getY(), (int) p1.x, (int) p1.y);
			g.drawLine((int) p1.x, (int) p1.y, (int) p2.getX(), (int) p2.getY());
			g.drawLine((int) p2.getX(), (int) p2.getY(), (int) x2.getX(), (int) x2.getY());
		}*/
  }
  
  protected void drawContact(Contact contact)
  {
    int x = (int) contact.getPosition().getX();
    int y = (int) contact.getPosition().getY();
    
    GL11.glColor3f(0.0f,0.4f,1.0f);
    GL11.glBegin(GL11.GL_QUADS);
      GL11.glVertex3f(x+0.5f,y+0.5f,0.0f);
      GL11.glVertex3f(x-0.5f,y+0.5f,0.0f);
      GL11.glVertex3f(x-0.5f,y-0.5f,0.0f);
      GL11.glVertex3f(x+0.5f,y-0.5f,0.0f);
    GL11.glEnd();
    
    //g.setColor(Color.blue);
    //g.fillOval(x-3,y-3,6,6);
    
     int dx = (int) (contact.getNormal().getX() * 10);
     int dy = (int) (contact.getNormal().getY() * 10);
    // g.setColor(Color.darkGray);
    // g.drawLine(x,y,x+dx,y+dy);
  }
          
  protected void showWorld()
  {
    GL11.glDisable(GL11.GL_BLEND);
    GL11.glDisable(GL11.GL_TEXTURE_2D);
      
    BodyList bodies = world.getBodies();
		
    for (int i=0;i<bodies.size();i++)
    {
      Body body = bodies.get(i);
      showBody(body);
    }
		
    JointList joints = world.getJoints();
    for (int i=0;i<joints.size();i++)
    {
	Joint joint = joints.get(i);
	showJoint(joint);
    }
		
    ArbiterList arbs = world.getArbiters();
    for (int i=0;i<arbs.size();i++)
    {
      Arbiter arb = arbs.get(i);
 
      Contact[] contacts = arb.getContacts();
      int numContacts = arb.getNumContacts();
			
      for (int j=0;j<numContacts;j++)
      {
	drawContact(contacts[j]);
      }
    }
  }

Well don’t take it like that but you get the idea.

hi guys can anyone help me with something?

how do i reset the physics? for example, an object in mid-fall will start to fall from rest once more.

coz i wan to make a reset button, but the thing is the physics calculation does not get reset! it’s funny but not working as intended. i didn’t see anything of use in the documentation so any help here would be greatly appreciated

edit: hmm i created a new instances of body and re-added them to the world… seems to work as intended now~