JBox2D物理引擎

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();
	}

}







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值