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. 【转】Linux---centos安装配置并挂载NFS

    转自:http://blog.csdn.net/loyachen/article/details/51010688 [系统环境] CentOS release 6.7 (Final) 服务端配置 1. ...

  2. 重学C语言---05运算符、表达式和语句

    一.循环简介 实例程序 /*shoes1.c--把一双鞋的尺码变为英寸*/#include <stdio.h>#define ADJUST 7.64#define SCALE 0.325 ...

  3. 重学C语言---02C语言概述

    1.第一个C语言实例 #include<stdio.h> int main(void) /*一个简单的C程序*/ { int num; /*定义一个num的变量*/ num = ; /*为 ...

  4. “由于这台计算机没有终端服务器客户端访问许可证”解决方案

    由于windows2003默认仅支持2个终端用户的登陆.当"终端连接超出了最大连接"的情况出现导致不能登录. 1.在另外一台Windows2003的机器上运行"tsmmc ...

  5. Linux 进程管理之四大名捕

    本文来自网络,著作权归原创作者所有,不做任何商业用途. 一.四大名捕 四大名捕,最初出现于温瑞安创作的武侠小说,是朝廷中正义力量诸葛小花的四大徒弟,四人各怀绝技,分别是轻功暗器高手“无情”.内功卓越的 ...

  6. Linux parted命令详解

    parted常见命令参数 Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...] Apply COMMANDs with PAR ...

  7. Django有关的所有命令

    1. Django的安装 pip install django ==1.11.11 pip install -i yuan django==1.11.11 2. 创建项目 django-admin s ...

  8. 【Alpha 冲刺】 5/12

    今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 建立数据库 未完成 设计表结构的时候,有些逻辑没有设计好,重新review一番设想的功能才初步确定表结构 孙浩楷 根据UI设计, ...

  9. Android 7.0以上版本 系统解决拍照的问题 exposed beyond app through ClipData.Item.getUri()

    解决方案1: android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg e ...

  10. Linux防火墙工具Firestarter

    Firestarter是一个非常好用的防火墙图形化配置工具,作者和开发者是芬兰人. 首先肯定的说Firestarter防火墙是一款非常优秀的基于GUI图形用户界面下的,完全免费的自由软件,它为中小型L ...