Box2d中,物体可以接受力(Force)、冲量(Impulse)和扭矩(Torque)。这些物理元素都能改变物体的运动形式,并且默认都会唤醒物体,当然只是针对动态物体。

力是一个持久的效果,通过Box2d内置的积分器实现运动变化。

冲量是一个瞬时效果,能立马改变其效果。

主要函数:

body.applyLinearImpulse( Vector2 impulse, Vector2 position, boolean wakeup )

第一个参数表示冲量,包含x和y方向的大小。

第二个参数表示施加冲量的位置。

第三个参数表示是否唤醒物体。

物体碰撞时,可以检测到碰撞的过程,开始和结束,并能够通过其Contact类获取碰撞的2个物体形状,进而获取物体。

物体可以设置UserData,然后可以在render函数中获取对应的UserData,并设置对应的角度和位置就能够显示图片等元素。

关节(Joint)是物体之间连接的方式,添加关节后物体的自由度会减少,运动轨迹会受到一定约束。

Box2d中有距离、旋转、滑轮、鼠标等一系列关节,这些都很方便的帮我们模拟现实。

具体示例:

 package com.fxb.newtest;

 import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Joint;
import com.badlogic.gdx.physics.box2d.JointDef;
import com.badlogic.gdx.physics.box2d.JointDef.JointType;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.joints.DistanceJointDef;
import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;
import com.badlogic.gdx.utils.Array; public class Lib021_Box2d1 extends ApplicationAdapter{ World world;
OrthographicCamera camera;
//DebugRenderer debugRenderer;
Box2DDebugRenderer debugRenderer;
Body bodyBox, bodyCircle;
TextureRegion region;
Sprite sprite;
SpriteBatch batch;
final Array<Body> arrBody = new Array<Body>(); @Override
public void create() {
// TODO Auto-generated method stub
super.create(); camera = new OrthographicCamera();
camera.setToOrtho( false, Gdx.graphics.getWidth()/10, Gdx.graphics.getHeight()/10 );
debugRenderer = new Box2DDebugRenderer();
world = new World( new Vector2(0, -10), true ); batch = new SpriteBatch();
region = new TextureRegion( new Texture( Gdx.files.internal( "data/badlogicsmall.jpg" ) ) );
sprite = new Sprite( region );
sprite.setSize( 4, 4 ); BodyDef bodyGroundDef = new BodyDef();
bodyGroundDef.type = BodyType.StaticBody;
bodyGroundDef.position.set( 0, 2 );
Body bodyGround = world.createBody( bodyGroundDef ); PolygonShape shapeGround = new PolygonShape();
shapeGround.setAsBox( camera.viewportWidth, 1 );
bodyGround.createFixture( shapeGround, 1 );
shapeGround.dispose(); BodyDef bodyBoxDef = new BodyDef();
bodyBoxDef.type = BodyType.DynamicBody;
bodyBoxDef.position.set( 5, 60 );
bodyBox = world.createBody( bodyBoxDef );
PolygonShape shapeBox = new PolygonShape();
shapeBox.setAsBox( 2, 2 );
FixtureDef fixtureDefBox = new FixtureDef();
fixtureDefBox.friction = 0.1f;
fixtureDefBox.shape = shapeBox;
fixtureDefBox.restitution = 0.3f;
//bodyBox.createFixture( shapeBox, 1 );
bodyBox.createFixture( fixtureDefBox );
shapeBox.dispose();
//bodyBox.setUserData( sprite ); BodyDef bodyCircleDef = new BodyDef();
bodyCircleDef.type = BodyType.DynamicBody;
bodyCircleDef.position.set( 20, 30 );
bodyCircle = world.createBody( bodyCircleDef );
CircleShape shapeCircle = new CircleShape();
shapeCircle.setRadius(2);
FixtureDef fixtureDefCir = new FixtureDef();
fixtureDefCir.friction = 0.1f;
fixtureDefCir.shape = shapeCircle;
fixtureDefCir.restitution = 0.3f;
bodyCircle.createFixture( fixtureDefCir );
shapeCircle.dispose(); InputAdapter processor = new InputAdapter(){
@Override
public boolean keyDown(int keycode) {
if( keycode == Input.Keys.A ){
//bodyBox.applyForce( 2f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
//bodyBox.applyForceToCenter( 2f, 2f, true );
bodyBox.applyLinearImpulse( 12f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
System.out.println( "a" );
}
return super.keyDown(keycode);
}
};
Gdx.input.setInputProcessor( processor ); world.setContactListener( new ContactListener(){
@Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
System.out.println( "begin" );
Body body1 = contact.getFixtureA().getBody();
Body body2 = contact.getFixtureB().getBody();
System.out.println( body1.getPosition().x + "," + body1.getPosition().y );
System.out.println( body2.getPosition().x + "," + body2.getPosition().y ); if( body1.getType() == BodyType.DynamicBody ){
body1.setUserData( sprite );
}
if( body2.getType() == BodyType.DynamicBody ){
body2.setUserData( sprite );
}
} @Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
System.out.println( "end" ); Body body1 = contact.getFixtureA().getBody();
Body body2 = contact.getFixtureB().getBody();
if( body1.getType() == BodyType.DynamicBody ){
body1.setUserData( null );
}
if( body2.getType() == BodyType.DynamicBody ){
body2.setUserData( null );
}
} @Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
} }); DistanceJointDef jointDefDis = new DistanceJointDef();
jointDefDis.bodyA = bodyBox;
jointDefDis.bodyB = bodyCircle;
jointDefDis.type = JointType.DistanceJoint;
jointDefDis.length = 10;
Joint jointDis = world.createJoint( jointDefDis ); /* RevoluteJointDef jointDefRevo = new RevoluteJointDef();
//jointDefRevo.bodyA = bodyBox;
//jointDefRevo.bodyB = bodyCircle;
jointDefRevo.initialize( bodyBox, bodyCircle, bodyCircle.getWorldCenter() );
jointDefRevo.type = JointType.RevoluteJoint;
Joint jointRevo = world.createJoint( jointDefRevo );*/
} @Override
public void render() {
// TODO Auto-generated method stub
super.render();
Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT ); if( Gdx.input.isKeyPressed( Input.Keys.D ) ){
bodyBox.applyForce( 12f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
} world.step( Gdx.graphics.getDeltaTime(), 6, 2 );
camera.update(); batch.setProjectionMatrix( camera.combined );
batch.begin(); world.getBodies( arrBody );
for( int i=0; i<arrBody.size; ++i ){
Body body = arrBody.get(i);
Sprite sprite0 = (Sprite)body.getUserData();
if( sprite0 != null ){
sprite0.setPosition( body.getPosition().x-2, body.getPosition().y-2 );
sprite0.setRotation( MathUtils.radiansToDegrees*body.getAngle() );
sprite0.draw( batch );
}
}
batch.end(); debugRenderer.render( world, camera.combined ); } @Override
public void dispose() {
// TODO Auto-generated method stub
super.dispose();
} }

运行效果:

落地后与地面发生碰撞,物体中间的图片都正常显示。

按下‘A’键后,方块物体向右移动,与圆环发生碰撞,内部UserData都设为null,没有图片显示。

添加了距离关节,两者连在了一起。

同时Box2d与stage也能够很好的结合起来一起显示,很方便。

libgdx学习记录21——Box2d物理引擎之碰撞Contact、冲量Impulse、关节Joint的更多相关文章

  1. libgdx学习记录18——Box2d物理引擎

    libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创 ...

  2. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  3. 实例介绍Cocos2d-x中Box2D物理引擎:使用关节

    下面我们将使用Box2D物理引擎技术进行重构.使得关节能够掌握如何在Box2D使用关节约束.HelloWorldScene.cpp中与使用关节的相关代码如下: void HelloWorld::add ...

  4. 【极客学院出品】Cocos2d-X系列课程之九-BOX2D物理引擎

    Cocos2d-x 是时下最热门的手游引擎,在国内和国外手机游戏开发使用的份额各自是70%和25%,在App Store的top10中,有7个是用它开发的. 本节课程为Cocos2d-x系列课程之九, ...

  5. 瘸腿蛤蟆笔记29-cocos2d-x-3.2 Box2d物理引擎dynamics模块介绍

    转载标明出处:http://blog.csdn.net/notbaron/article/details/38611335 上篇回想 本篇名言:奋斗.寻觅.发现,而不屈服.[诗人丁尼生] 上篇中,我们 ...

  6. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  7. 实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D

    我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用.这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触 ...

  8. cocos2d-x中的Box2D物理引擎

    在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...

  9. python下的Box2d物理引擎的配置

    /******************************* I come back! 由于已经大四了,正在找工作 导致了至今以来第二长的时间内没有更新博客.向大家表示道歉 *********** ...

随机推荐

  1. Sql Server Tempdb原理-日志机制解析实践

    笔者曾经在面试DBA时的一句”tempdb为什么比其他数据库快?”使得95%以上的应试者都一脸茫然.Tempdb作为Sqlserver的重要特征,一直以来大家对它可能即熟悉又陌生.熟悉是我们时时刻刻都 ...

  2. ORACLE-SQL微妙之处

    本文总结一下平时经常使用的SQL语句以及一些ORACLE函数的微妙之处.欢迎大家多多补充平时最常用的SQL语句,供大家学习参考. SQL> select * from temp2; NAME S ...

  3. w3school 基础学习

    http://www.w3school.com.cn/ http://www.w3school.com.cn/sql/sql_quickref.asp

  4. ASA 用TFTP 备份配置方法

    一种方法是用ASDM,在菜单样哪项里有一个backup,保存为一个压缩文件rar,恢复也是用ASDM.另一种是用TFTP SERVER 来做,电脑用网线接上ASA,还要把cisco TFTP SERV ...

  5. 【转】Spring学习---Spring IoC容器的核心原理

    [原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...

  6. MySQL基础之 逻辑运算符

    mysql的逻辑运算符有四个:与.或.非.异或 我们平时在谈论的时候不考虑带有NULL的情况,今天我们就来考虑一下带有NULL值,他们的结果是怎么样的 AND(&&)运算符 mysql ...

  7. Hadoop HBase概念学习系列之HRegion服务器(三)

    所有的数据库数据一般是保存在Hadoop分布式系统上面的,用户通过一系列HRegion服务器获取这些数据.一台机器上一般只运行一个HRegion服务器,而且每一分区段的HRegion也只会被一个HRe ...

  8. 5.Dubbo2.5.3泛化引用和泛化实现

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.泛化引用 泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Ma ...

  9. C语言编程积累2

    版权声明:本文为CSDN博主(天才2012)原创文章,未经博主同意不得转载. https://blog.csdn.net/gzzaigcn/article/details/27113957 寥寥数笔, ...

  10. Scala学习之路 (八)Scala的隐式转换和隐式参数

    一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...