您的位置:首页 > 其它

JBox2D物理引擎

2014-06-20 20:42 204 查看
JBox2D是一个免费的物理引擎,官方建议捐助,通过该引擎可以搭建一个现实的物理世界(2D),可以设置环境重力,并建立各种刚体(Body),并为这些刚体设置属性。根据刚体的受力情况,会自动计算出移动的轨迹,获得坐标的值,通过自定义View,来绘制这些内容。

JBox2D的经典版本是2.0.1,最新版本是2.2.1,新版本更简单,老版本网上的资料更多。

需要导入jar包:jbox2d-library-2.2.1.1.jar

1、创建vo

public class Ball {

private Body body;

private float r;

public Ball(Body body) {
this.body = body;
r = Globals.PIECE_WIDTH / 4;
}

public void draw(Canvas canvas, Paint paint) {
canvas.drawBitmap(ImageUtils.getBallImg(), body.getPosition().x
* Globals.RATE - r, body.getPosition().y * Globals.RATE - r,
paint);
}
}
2、创建util工具类
(1)

public class Globals {

public static int SCREEN_WIDTH;
public static int SCREEN_HEIGHT;
public static int RATE;

public static float PIECE_WIDTH;
public static float PIECE_HEIGHT;

public static void init(Activity a) {
SCREEN_WIDTH = a.getWindowManager().getDefaultDisplay().getWidth();
SCREEN_HEIGHT = a.getWindowManager().getDefaultDisplay().getHeight();

RATE = 10;

PIECE_WIDTH = SCREEN_WIDTH / 6f;
PIECE_HEIGHT = SCREEN_HEIGHT / 10f;

}

}


(2)
public class ImageUtils {

private static Bitmap ballImg;

public static void init(Activity a) {
ballImg = changeSize(
BitmapFactory.decodeResource(a.getResources(), R.drawable.ball),
Globals.PIECE_WIDTH / 2, Globals.PIECE_HEIGHT / 2);
}

private static Bitmap changeSize(Bitmap source, float overWidth,
float overHeight) {
Matrix m = new Matrix();
m.postScale(overWidth / source.getWidth(),
overHeight / source.getHeight());

return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), m, false);
}

public static Bitmap getBallImg() {
return ballImg;
}
}
(3)
public class JBoxUtils {

public static World world;

public static int IRON_TYPE = 1;
public static int WOOD_TYPE = 2;
public static int WALL_TYPE = 3;

public static void init() {
world = new World(new Vec2(0, 0));
// 设置世界不会自动休眠
world.setAllowSleep(false);
}

public static Body createCircle(float r, float x, float y, int type,
boolean isStatic) {
CircleShape shape = new CircleShape();
shape.m_radius = r / Globals.RATE;

return createBody(shape, type, x, y, isStatic);
}

public static Body createBox(float width, float height, float x, float y,
int type, boolean isStatic) {
PolygonShape shape = new PolygonShape();
shape.setAsBox(width / 2 / Globals.RATE, height / 2 / Globals.RATE);

return createBody(shape, type, x, y, isStatic);
}

private static Body createBody(Shape shape, int type, float x, float y,
boolean isStatic) {
FixtureDef def = new FixtureDef();
def.shape = shape;

switch (type) {
case 1:
def.density = 7.9f;
def.restitution = 0.2f;
def.friction = 0.1f;
break;
case 2:
def.density = 0.8f;
def.restitution = 0.4f;
def.friction = 0.2f;
break;
case 3:
def.density = 0f;
def.restitution = 0.5f;
def.friction = 0.5f;
break;

}

BodyDef bd = new BodyDef();
bd.position = new Vec2(x / Globals.RATE, y / Globals.RATE);

Body b = world.createBody(bd);
b.createFixture(def);
if (isStatic) {
b.setType(BodyType.STATIC);
} else {
b.setType(BodyType.DYNAMIC);
}

return b;
}

}
3、创建View类
public class MainView extends View {

private Ball ball;

public MainView(Context context, AttributeSet attrs) {
super(context, attrs);

setBackgroundResource(R.drawable.gamebg);

ball = new Ball(JBoxUtils.createCircle(Globals.PIECE_WIDTH / 4,
Globals.PIECE_WIDTH / 4, Globals.PIECE_HEIGHT / 4,
JBoxUtils.IRON_TYPE, false));

// 建立四面墙
JBoxUtils.createBox(Globals.SCREEN_WIDTH, 2, Globals.SCREEN_WIDTH / 2,
-1, JBoxUtils.WALL_TYPE, true);
JBoxUtils.createBox(Globals.SCREEN_WIDTH, 2, Globals.SCREEN_WIDTH / 2,
Globals.SCREEN_HEIGHT + 1, JBoxUtils.WALL_TYPE, true);

JBoxUtils.createBox(2, Globals.SCREEN_HEIGHT, -1,
Globals.SCREEN_HEIGHT / 2, JBoxUtils.WALL_TYPE, true);
JBoxUtils.createBox(2, Globals.SCREEN_HEIGHT, Globals.SCREEN_WIDTH + 1,
Globals.SCREEN_HEIGHT / 2, JBoxUtils.WALL_TYPE, true);

}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
if (ball != null) {
ball.draw(canvas, paint);
}

}

}
4、Activity类
public class MainActivity extends Activity {

private MainView mainView;

private boolean flag = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Globals.init(this);
ImageUtils.init(this);
JBoxUtils.init();

setContentView(R.layout.activity_main);

mainView = (MainView) findViewById(R.id.main_view);

Thread t = new Thread() {
@Override
public void run() {
while (flag) {
try {

mainView.postInvalidate();

JBoxUtils.world.step(1.0f / 30, 3, 8);

Thread.sleep(33);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
t.start();

SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor s = manager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
manager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;

JBoxUtils.world.setGravity(new Vec2(-values[2] * 10, -values[1] * 10));
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}
}, s, SensorManager.SENSOR_DELAY_GAME);

}

@Override
protected void onDestroy() {
flag = false;
super.onDestroy();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息