android 2d物理引擎-Box2d
16lz
2021-12-31
转载http://rayleung.iteye.com/blog/439056
Box2d是一个很出名的2d物理引擎,大家可以google之。Box2d有C++,flash和Java等版本。android可以直接使用java版本的Jbox2d,但因为Jbox2d的图形渲染是使用processing库来实现的,所以,在android中使用Jbox2d的时候,图形渲染的工作就只能自己来写了。因为网上关于box2d的资料真的非常的少,特别是关于图形绘制方面,所以,虽然程序写得不是很好,还是贴上来了,先看截图:
程序很简单:蓝色的是地面,从上面掉下两个绿球和一个红色的方块,它们之间的碰撞都由box2d引擎自己来完成。
(这程序运行起来有点卡,我 也正在解决这个问题,有朋友知道答案的也请分享一下啦!)
代码如下:
Java代码- packagecom.ray.test;
- importorg.jbox2d.collision.AABB;
- importorg.jbox2d.collision.CircleDef;
- importorg.jbox2d.collision.PolygonDef;
- importorg.jbox2d.common.Vec2;
- importorg.jbox2d.dynamics.Body;
- importorg.jbox2d.dynamics.BodyDef;
- importorg.jbox2d.dynamics.World;
- importandroid.app.Activity;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.view.WindowManager;
- publicclassMyBox2dextendsActivity{
- privatefinalstaticintRATE=10;//屏幕到现实世界的比例10px:1m;
- privateAABBworldAABB;//创建一个管理碰撞的世界
- privateWorldworld;
- privatefloattimeStep=1/60;//模拟的的频率
- privateintiterations=10;//迭代越大,模拟约精确,但性能越低
- privateBodybody,body2,body3;
- privateMyViewmyView;
- privateHandlermHandler;
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- worldAABB=newAABB();
- //上下界,以屏幕的左上方为原点,如果创建的刚体到达屏幕的边缘的话,会停止模拟
- worldAABB.lowerBound.set(-100.0f,-100.0f);
- worldAABB.upperBound.set(100.0f,100.0f);//注意这里使用的是现实世界的单位
- Vec2gravity=newVec2(0.0f,10.0f);
- booleandoSleep=true;
- world=newWorld(worldAABB,gravity,doSleep);//创建世界
- createBox(160,470,160,10,true);
- createBox1(160,150,160,10,false);
- createCircle(160,100,10);
- createCircle1(150,60,10);
- timeStep=1.0f/60.0f;
- iterations=10;
- myView=newMyView(this);
- setContentView(myView);
- mHandler=newHandler();
- mHandler.post(update);
- }
- privateRunnableupdate=newRunnable(){
- publicvoidrun(){
- world.step(timeStep,iterations);//开始模拟
- Vec2position=body.getPosition();
- Vec2position1=body2.getPosition();
- Vec2position2=body3.getPosition();
- myView.x=position.x*RATE;
- myView.y=position.y*RATE;
- myView.x1=position1.x*RATE;
- myView.y1=position1.y*RATE;
- myView.x2=position2.x*RATE;
- myView.y2=position2.y*RATE;
- myView.update();
- mHandler.postDelayed(update,(long)timeStep*1000);
- }
- };
- publicvoidcreateBox(floatx,floaty,floathalf_width,floathalf_height,
- booleanisStatic){
- PolygonDefshape=newPolygonDef();
- if(isStatic){shape.density=0;}
- else{shape.density=2.0f;}
- shape.friction=0.8f;
- shape.restitution=0.3f;
- shape.setAsBox(half_width/RATE,half_height/RATE);
- BodyDefbodyDef=newBodyDef();
- bodyDef.position.set(x/RATE,y/RATE);
- Bodybody1=world.createBody(bodyDef);
- body1.createShape(shape);
- body1.setMassFromShapes();
- }
- publicvoidcreateCircle(floatx,floaty,floatradius){
- CircleDefshape=newCircleDef();
- shape.density=7;
- shape.friction=0.2f;
- shape.radius=radius/RATE;
- BodyDefbodyDef=newBodyDef();
- bodyDef.position.set(x/RATE,y/RATE);
- body2=world.createBody(bodyDef);
- body2.createShape(shape);
- body2.setMassFromShapes();
- }
- publicvoidcreateCircle1(floatx,floaty,floatradius){
- CircleDefshape=newCircleDef();
- shape.density=7;
- shape.friction=0.2f;
- shape.radius=radius/RATE;
- BodyDefbodyDef=newBodyDef();
- bodyDef.position.set(x/RATE,y/RATE);
- body3=world.createBody(bodyDef);
- body3.createShape(shape);
- body3.setMassFromShapes();
- }
- publicvoidcreateBox1(floatx,floaty,floathalf_width,floathalf_height,
- booleanisStatic){
- PolygonDefshape=newPolygonDef();
- if(isStatic){shape.density=0;}
- else{shape.density=2.0f;}
- shape.friction=0.3f;
- shape.setAsBox(half_width/RATE,half_height/RATE);
- BodyDefbodyDef=newBodyDef();
- bodyDef.position.set(x/RATE,y/RATE);
- body=world.createBody(bodyDef);
- body.createShape(shape);
- body.setMassFromShapes();
- }
- classMyViewextendsView{
- Canvascanvas;
- publicfloatx=160,y=150;
- publicfloatx1=160,y1=100;
- publicfloatx2=150,y2=60;
- publicMyView(Contextcontext){
- super(context);
- }
- publicvoiddrawBox(floatx,floaty){
- PaintmPaint=newPaint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(Color.RED);
- canvas.drawRect(x-160,y-10,x+160,y+10,mPaint);
- }
- publicvoiddrawGround(){
- PaintmPaint=newPaint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(Color.BLUE);
- canvas.drawRect(0,460,320,480,mPaint);
- }
- publicvoiddrawCircle(floatx1,floaty1){
- PaintmPaint=newPaint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(Color.GREEN);
- canvas.drawCircle(x1,y1,10,mPaint);
- }
- publicvoidupdate(){
- postInvalidate();
- }
- protectedvoidonDraw(Canvascanvas){
- super.onDraw(canvas);
- this.canvas=canvas;
- drawGround();
- drawBox(x,y);
- drawCircle(x1,y1);
- drawCircle(x2,y2);
- }
- }
- }
程序运行的时候需要加载Jbox2d的库,可到以下地址下载(使用的是不带渲染部分的库jbox2d-2.0.1-library-only.jar):
http://sourceforge.net/projects/jbox2d/ 附件也有
更多相关文章
- 总结的一些android公共库
- 编译移植android 2.3到tiny210
- 学习Android(安卓)应注意的十个问题
- Android的Message Queue
- 实践中探索Android智能手机系统------ROM分区
- edittext的imeOptions属性和android软键盘的使用
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用