2012-09-10
从今天开始学习Box2D,在java中是JBox2D(Download),包的导入就不用说了吧!
文章后面给出了我写的helloworld,仅供参考
笔记:Ⅰ)Box2D由世界,物体等组成,Box2D能自动计算物体的位置,然后我们还需要在Android中绘制出来;
Ⅱ)Box2D世界中的单位都是标准单位,秒、米、千克 etc. 需要按照比例缩放,不然速度很慢(代码中有转换);
Ⅲ)Box2D每帧的位移是2m/frame,不能超过这个速度,所以要进行缩放,即可放大速度;
Ⅳ)注意坐标系的零点是在左上角,同时角度是以弧度制的;
坐标系 效果图
代码:
public class Hello_Box2d extends Activity {
private World mWorld;
private Handler mHandler;
private View mView;
private int screenH, screenW;
private final float WORLD2PHONE_RATE = 5;
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
mWorld.step(0.1f, 3, 3);//
mView.invalidate();
mHandler.postDelayed(this, 100);
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);// full screen
//get the window width and height
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
screenH = metric.heightPixels;
screenW = metric.widthPixels;
//create view
mView = new helloBox2dView(this);
mView.setBackgroundColor(Color.WHITE);
setContentView(mView);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mRunnable);
}
class helloBox2dView extends View {
private Canvas mCanvas;
private Body mBody;
public helloBox2dView(Context context) {
super(context);
/** Creating a World */
{
Vec2 gravity = new Vec2(0f, 9.8f);// vector, the gravity direction, left and right, up and down
mWorld = new World(gravity, false);
}
/** Creating a Ground Box */
{
// Bodies are built using the following steps:
// Step 1. Define a body with position, damping, etc.
BodyDef groundBodyDef = new BodyDef();
groundBodyDef.position.set(0f, (screenH-screenW*3/4)/WORLD2PHONE_RATE);
groundBodyDef.angle = (float) Math.asin(0.6);
// Step 2. Use the world object to create the body.
Body groundBody = mWorld.createBody(groundBodyDef);
// Step 3. Define fixtures with a shape, friction, density, etc.
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox(screenW*5/4/WORLD2PHONE_RATE, 1f/WORLD2PHONE_RATE);
// Step 4. Create fixtures on the body.
groundBody.createFixture(groundBox, 0.0f);
//border
BodyDef groundBodyDef2 = new BodyDef();
groundBodyDef2.position.set(screenW/WORLD2PHONE_RATE, 0f);
groundBodyDef2.angle = (float) (0.5f*Math.PI);
Body groundBody2 = mWorld.createBody(groundBodyDef2);
PolygonShape groundBox2 = new PolygonShape();
groundBox2.setAsBox(screenH/WORLD2PHONE_RATE, 1f/WORLD2PHONE_RATE);
groundBody2.createFixture(groundBox2, 0.0f);
}
/** Creating a Dynamic Body */
{
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DYNAMIC;
bodyDef.position.set(100f/WORLD2PHONE_RATE, 0f);
mBody = mWorld.createBody(bodyDef);
CircleShape dynamicBox = new CircleShape();
dynamicBox.m_radius = 10/WORLD2PHONE_RATE;
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicBox;
fixtureDef.density = 500f;
fixtureDef.friction = 0.5f;
fixtureDef.restitution = 0.8f;
mBody.createFixture(fixtureDef);
}
mHandler = new Handler();
mHandler.post(mRunnable);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCanvas = canvas;
//draw ground
drawGround();
//draw box
Vec2 position = mBody.getPosition();
float angle = mBody.getAngle();
drawBox(position.x*WORLD2PHONE_RATE, position.y*WORLD2PHONE_RATE, angle);
}
public void drawBox(float x, float y, float angle){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
mCanvas.drawCircle(x, y, 10, paint);
mCanvas.drawLine(x, y, (float)(x+10*Math.cos(angle)), (float)(y+10*Math.sin(angle)), new Paint());
}
public void drawGround(){
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
mCanvas.drawLine(0, screenH-screenW*3/4, screenW, screenH, paint);
mCanvas.drawLine(screenW, 0, screenW, screenH, paint);
}
}
}