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. mysql index hint 在index不存在时的处理

    关于index_hint 在mysql查询语句中可以通过指定index_hint来告诉优化器如何使用索引,详细可以参考这里 index_hint: USE {INDEX|KEY} [FOR {JOIN ...

  2. IE中操作粘贴板复制和粘贴

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. sysbench使用

      1 部署 1.1 官方主页 https://github.com/Percona-Lab/sysbench-tpcc https://github.com/akopytov/sysbench 1. ...

  4. SqlServer中sqlmaint 实用工具和xp_sqlmaint扩展过程

    sqlmaint 实用工具可以对一个或多个数据库执行一组指定的维护操作.使用 sqlmaint,可以运行 DBCC 检查.备份数据库及其事务日志.更新统计以及重建索引.所有数据库维护活动都会生成报表, ...

  5. python容错

    #try: except: else: #为什么叫容错呢,先说说错误,这里说的错误并不是因为马虎或者什么原因在脚本中留下的bug,这个不能容掉,所谓容掉就是略过这个错误,要在测试时候发现并修正,需要容 ...

  6. C#-老生常谈的 值类型与引用类型

    特殊的String 说起值类型和引用类型,大家都知道这么个事,很多时候我们会拿String做值类型来做比较,但实际上String虽然是值类型,却表现的有点特别 String示例 看下面的一个例子: 话 ...

  7. JRebel for Hybris ,Idea and Windows

    参考: Jrebel官网参考地址:https://manuals.zeroturnaround.com/jrebel/standalone/hybris.html Wiki Hybris参考地址:ht ...

  8. MySQL案列之主从复制出错问题以及pt-slave-restart工具的使用

    今天主从复制遇到一个问题,主库上插入了几百行万数据,后来又删除了这些数据,原因就是主库删除的表从库中不存在,导致从库在遇到删除不存在表的错误无法继续同步. MySQL [(none)]> sho ...

  9. [技术] OIer的C++标准库 : STL入门

    注: 本文主要摘取STL在OI中的常用技巧应用, 所以可能会重点说明容器部分和算法部分, 且不会讨论所有支持的函数/操作并主要讨论 C++11 前支持的特性. 如果需要详细完整的介绍请自行查阅标准文档 ...

  10. python基础之单例设计模式

    class Player(): instance = None init_flag = False def __init__(self): if self.init_flag is False: pr ...