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. 使用python做简单的接口性能测试

    思路:利用ruquest发送请求,利用多线程模拟并发 下面直接上代码: #!/user/bin/env python #coding=utf-8 import requests import date ...

  2. python自学——文件处理(强制刷新)

    # 文件的刷新flash# 为什么要刷新文件呢?# 首先我们就要知道电脑是怎么储存信息的,# 写的代码保存在缓存中当缓存满了之后就会将内容储存到硬盘中. # 那这个跟刷新有什么关系呢?# 系统也会自动 ...

  3. 什么是套接字(Socket)

    应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要 通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连 ...

  4. Web Services 根据wsdl生成代理类

    生成代理类步骤: 一:找到Visual Studio 的工具文件夹 二:用管理员方式打开本机工具命令提示 三:输入要执行的脚本 wsdl /language:C# /n:xxxx.HermesMobi ...

  5. rsync 数据备份+cron+mailx案例

    大家都知道数据非常重要的,需要经常备份,如果备份了,但无法恢复还原,那就证明你备份的很失败,所有当我们备份了数据需要检查是否备份完整,是否可用可恢复.以下为一个企业案例: 某公司里有一台Web服务器, ...

  6. [BZOJ 1568][JSOI2008]Blue Mary开公司

    [BZOJ 1568][JSOI2008]Blue Mary开公司 题意 \(n\) 次操作, 维护一个一次函数集合 \(S\). 有两种操作: 给定 \(b\) 和 \(k\), 向 \(S\) 中 ...

  7. Windows2008 Server r2 64位显示桌面图标的方法

    点击桌面左下方的开始菜单,在搜索框中输入“icon”,如下图所示: 点击:显示或隐藏桌面上的通用图标,然后弹出如下图: 应用并确定即可!

  8. 在HTML中使用object和embed标签插入视频

    object标签和embed标签都能给页面添加多媒体内容: 一.object 对于object,w3c上定义object为一个嵌入的对象.可以使用此元素向您的 XHTML 页面添加多媒体.此元素允许您 ...

  9. Oracle修改表空间为自动扩展

    https://gqsunrise.iteye.com/blog/2015692 1.数据文件自动扩展的好处1)不会出现因为没有剩余空间可以利用到数据无法写入2)尽量减少人为的维护3)可以用于重要级别 ...

  10. BZOJ 1076 奖励关 状态压缩DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1076 题目大意: 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里, ...