JBox2D物理引擎

来源:互联网 发布:政府数据统计 编辑:程序博客网 时间:2024/05/03 08:27

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);}@Overrideprotected 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;@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onSensorChanged(SensorEvent event) {float[] values = event.values;JBoxUtils.world.setGravity(new Vec2(-values[2] * 10, -values[1] * 10));}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}}, s, SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onDestroy() {flag = false;super.onDestroy();}}







0 0
原创粉丝点击