libgdx学习记录21——Box2d物理引擎之碰撞Contact、冲量Impulse、关节Joint

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

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

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

主要函数:

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

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

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

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

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

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

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

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

具体示例:


  1 package com.fxb.newtest;
2
3 import com.badlogic.gdx.ApplicationAdapter;
4 import com.badlogic.gdx.Gdx;
5 import com.badlogic.gdx.Input;
6 import com.badlogic.gdx.InputAdapter;
7 import com.badlogic.gdx.graphics.GL10;
8 import com.badlogic.gdx.graphics.OrthographicCamera;
9 import com.badlogic.gdx.graphics.Texture;
10 import com.badlogic.gdx.graphics.g2d.Sprite;
11 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
12 import com.badlogic.gdx.graphics.g2d.TextureRegion;
13 import com.badlogic.gdx.math.MathUtils;
14 import com.badlogic.gdx.math.Vector2;
15 import com.badlogic.gdx.physics.box2d.Body;
16 import com.badlogic.gdx.physics.box2d.BodyDef;
17 import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
18 import com.badlogic.gdx.physics.box2d.CircleShape;
19 import com.badlogic.gdx.physics.box2d.Contact;
20 import com.badlogic.gdx.physics.box2d.ContactImpulse;
21 import com.badlogic.gdx.physics.box2d.ContactListener;
22 import com.badlogic.gdx.physics.box2d.FixtureDef;
23 import com.badlogic.gdx.physics.box2d.Joint;
24 import com.badlogic.gdx.physics.box2d.JointDef;
25 import com.badlogic.gdx.physics.box2d.JointDef.JointType;
26 import com.badlogic.gdx.physics.box2d.Manifold;
27 import com.badlogic.gdx.physics.box2d.PolygonShape;
28 import com.badlogic.gdx.physics.box2d.World;
29 import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
30 import com.badlogic.gdx.physics.box2d.joints.DistanceJointDef;
31 import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;
32 import com.badlogic.gdx.utils.Array;
33
34 public class Lib021_Box2d1 extends ApplicationAdapter{
35
36 World world;
37 OrthographicCamera camera;
38 //DebugRenderer debugRenderer;
39 Box2DDebugRenderer debugRenderer;
40 Body bodyBox, bodyCircle;
41 TextureRegion region;
42 Sprite sprite;
43 SpriteBatch batch;
44 final Array<Body> arrBody = new Array<Body>();
45
46 @Override
47 public void create() {
48 // TODO Auto-generated method stub
49 super.create();
50
51 camera = new OrthographicCamera();
52 camera.setToOrtho( false, Gdx.graphics.getWidth()/10, Gdx.graphics.getHeight()/10 );
53 debugRenderer = new Box2DDebugRenderer();
54 world = new World( new Vector2(0, -10), true );
55
56 batch = new SpriteBatch();
57 region = new TextureRegion( new Texture( Gdx.files.internal( "data/badlogicsmall.jpg" ) ) );
58 sprite = new Sprite( region );
59 sprite.setSize( 4, 4 );
60
61
62 BodyDef bodyGroundDef = new BodyDef();
63 bodyGroundDef.type = BodyType.StaticBody;
64 bodyGroundDef.position.set( 0, 2 );
65 Body bodyGround = world.createBody( bodyGroundDef );
66
67 PolygonShape shapeGround = new PolygonShape();
68 shapeGround.setAsBox( camera.viewportWidth, 1 );
69 bodyGround.createFixture( shapeGround, 1 );
70 shapeGround.dispose();
71
72
73 BodyDef bodyBoxDef = new BodyDef();
74 bodyBoxDef.type = BodyType.DynamicBody;
75 bodyBoxDef.position.set( 5, 60 );
76 bodyBox = world.createBody( bodyBoxDef );
77 PolygonShape shapeBox = new PolygonShape();
78 shapeBox.setAsBox( 2, 2 );
79 FixtureDef fixtureDefBox = new FixtureDef();
80 fixtureDefBox.friction = 0.1f;
81 fixtureDefBox.shape = shapeBox;
82 fixtureDefBox.restitution = 0.3f;
83 //bodyBox.createFixture( shapeBox, 1 );
84 bodyBox.createFixture( fixtureDefBox );
85 shapeBox.dispose();
86 //bodyBox.setUserData( sprite );
87
88 BodyDef bodyCircleDef = new BodyDef();
89 bodyCircleDef.type = BodyType.DynamicBody;
90 bodyCircleDef.position.set( 20, 30 );
91 bodyCircle = world.createBody( bodyCircleDef );
92 CircleShape shapeCircle = new CircleShape();
93 shapeCircle.setRadius(2);
94 FixtureDef fixtureDefCir = new FixtureDef();
95 fixtureDefCir.friction = 0.1f;
96 fixtureDefCir.shape = shapeCircle;
97 fixtureDefCir.restitution = 0.3f;
98 bodyCircle.createFixture( fixtureDefCir );
99 shapeCircle.dispose();
100
101 InputAdapter processor = new InputAdapter(){
102 @Override
103 public boolean keyDown(int keycode) {
104 if( keycode == Input.Keys.A ){
105 //bodyBox.applyForce( 2f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
106 //bodyBox.applyForceToCenter( 2f, 2f, true );
107 bodyBox.applyLinearImpulse( 12f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
108 System.out.println( "a" );
109 }
110 return super.keyDown(keycode);
111 }
112 };
113 Gdx.input.setInputProcessor( processor );
114
115
116 world.setContactListener( new ContactListener(){
117 @Override
118 public void beginContact(Contact contact) {
119 // TODO Auto-generated method stub
120 System.out.println( "begin" );
121 Body body1 = contact.getFixtureA().getBody();
122 Body body2 = contact.getFixtureB().getBody();
123 System.out.println( body1.getPosition().x + "," + body1.getPosition().y );
124 System.out.println( body2.getPosition().x + "," + body2.getPosition().y );
125
126 if( body1.getType() == BodyType.DynamicBody ){
127 body1.setUserData( sprite );
128 }
129 if( body2.getType() == BodyType.DynamicBody ){
130 body2.setUserData( sprite );
131 }
132 }
133
134 @Override
135 public void endContact(Contact contact) {
136 // TODO Auto-generated method stub
137 System.out.println( "end" );
138
139 Body body1 = contact.getFixtureA().getBody();
140 Body body2 = contact.getFixtureB().getBody();
141 if( body1.getType() == BodyType.DynamicBody ){
142 body1.setUserData( null );
143 }
144 if( body2.getType() == BodyType.DynamicBody ){
145 body2.setUserData( null );
146 }
147 }
148
149 @Override
150 public void preSolve(Contact contact, Manifold oldManifold) {
151 // TODO Auto-generated method stub
152 }
153 @Override
154 public void postSolve(Contact contact, ContactImpulse impulse) {
155 // TODO Auto-generated method stub
156 }
157
158 });
159
160
161 DistanceJointDef jointDefDis = new DistanceJointDef();
162 jointDefDis.bodyA = bodyBox;
163 jointDefDis.bodyB = bodyCircle;
164 jointDefDis.type = JointType.DistanceJoint;
165 jointDefDis.length = 10;
166 Joint jointDis = world.createJoint( jointDefDis );
167
168
169 /* RevoluteJointDef jointDefRevo = new RevoluteJointDef();
170 //jointDefRevo.bodyA = bodyBox;
171 //jointDefRevo.bodyB = bodyCircle;
172 jointDefRevo.initialize( bodyBox, bodyCircle, bodyCircle.getWorldCenter() );
173 jointDefRevo.type = JointType.RevoluteJoint;
174 Joint jointRevo = world.createJoint( jointDefRevo );*/
175 }
176
177 @Override
178 public void render() {
179 // TODO Auto-generated method stub
180 super.render();
181 Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT );
182
183
184 if( Gdx.input.isKeyPressed( Input.Keys.D ) ){
185 bodyBox.applyForce( 12f, 0, bodyBox.getPosition().x, bodyBox.getPosition().y, true );
186 }
187
188 world.step( Gdx.graphics.getDeltaTime(), 6, 2 );
189 camera.update();
190
191 batch.setProjectionMatrix( camera.combined );
192 batch.begin();
193
194 world.getBodies( arrBody );
195 for( int i=0; i<arrBody.size; ++i ){
196 Body body = arrBody.get(i);
197 Sprite sprite0 = (Sprite)body.getUserData();
198 if( sprite0 != null ){
199 sprite0.setPosition( body.getPosition().x-2, body.getPosition().y-2 );
200 sprite0.setRotation( MathUtils.radiansToDegrees*body.getAngle() );
201 sprite0.draw( batch );
202 }
203 }
204 batch.end();
205
206 debugRenderer.render( world, camera.combined );
207
208 }
209
210 @Override
211 public void dispose() {
212 // TODO Auto-generated method stub
213 super.dispose();
214 }
215
216 }

运行效果:

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

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

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

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

时间: 2024-10-24 23:56:27

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

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

libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创建正交相机,并设置其宽高.Box2d中使用物理世界中米作为单位,而不是图像中的像素,通常设一个比值,这里为了方便,直接设置为10. 3. 创建世界中的动态物体(一般是方块.圆环或其他形状物体)和静态物体(主要指地面.墙壁等). 4. 在渲染函数中添加world时间布,并利用DebugRenderer

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

在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact(b2Contact* contact).两个物体開始接触时会响应,但仅仅调用一次. virtual void EndContact(b2Contact* contact).分离时响应. 但仅仅调用一次. virtual void PreSolve(b2Contact* contact, const

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

下面我们将使用Box2D物理引擎技术进行重构.使得关节能够掌握如何在Box2D使用关节约束.HelloWorldScene.cpp中与使用关节的相关代码如下: [html] view plaincopy void HelloWorld::addNewSpriteAtPosition(Vec2 p) { log("Add sprite %0.2f x %02.f",p.x,p.y); //创建物理引擎精灵对象A auto spriteA = Sprite::create("Bo

COCOS2DX学习之Box2d物理引擎使用之------动态物体的创建

1.创建一个物理世界 首先要引入一个头文件#include "Box2D\Box2D.h" 之后利用b2word创建一个对象,并且指定这个物理世界中的加速度方向. word = new b2World(b2Vec2(0,-10));                        //指定物理世界的加速度 最后还要重写一下update函数,这个函数在之前的计时器学习的时候已经说过,每一帧的变动都将自动执行这个函数.所以我们要通过这个函数来进行创建的物理世界的刷新. 2.创建一个运动的物体

COCOS2DX学习之box2d物理引擎在VS2012中的配置

因为vs中并没有继承box2dz游戏物理引擎,所以在开发有关box2d的游戏的时候,要自己将这个引擎添加进去.首先在解决方案中添加一个已经存在的项目,这个项目的路径就是你创建的cocos2dx项目的目录里面cocos2d\external\Box2D\proj.win32这个文件夹下面的一个vs工程,把它添加进去编译好,就会看到proj.win32\Debug.win32中有了Box2d的库. 之后,将生成的box2d的库添加到项目属性的连接器中即可 tool是我创建的coocs2dx项目 CO

瘸腿蛤蟆笔记42-cocos2d-x-3.2 Box2d物理引擎Motor Joint

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处: 源码下载: http://download.csdn.net/detail/notbaron/7900243 上篇回顾 本篇名言:对"战士旅行者"而言,选择其实不是去选择,而是优雅地接受"无限"的邀请.[唐望] 上篇中,蛤蟆学习了Box2d物理引擎中的持续施加力,接下去蛤蟆继续学习其他的Box2d引擎的使用.这次我们使用Box2d物理引擎来学习 Motor Joint     . 理论介绍 本次的理论知识, 咱们回顾下M

瘸腿蛤蟆笔记28-cocos2d-x-3.2 Box2d物理引擎collision模块介绍

上篇回顾 本篇名言:绝不测量山的高度─除非你已到达顶峰,那时你就会知道山有多低. [哈马绍] 上篇中,我们学习了Box2d物理引擎的三大模块之一的common模块,该模块主要包含设置,内存管理和向量数学. 这次蛤蟆接着学习collison模块. 理论介绍 这个collision模块包括了shapes和函数.同时包括一个动态树和broad-phase(蛤蟆不知道怎么解释这个)用于加速碰撞系统.这个模块设计的时候是在动态系统之外使用的.        Shape 这里的shapes描述了碰撞几何,可

libgdx学习记录19——图片动态打包PixmapPacker

libgdx中,opengl 1.x要求图片长宽必须为2的整次幂,一般有如下解决方法 1. 将opengl 1.x改为opengl 2.0.(libgdx 1.0版本后不支持1.x,当然不存在这个问题,这里针对的是0.9.9版本) 2. 使用TexturePacker将图片打包好然后作成一张大图添加进来. 第二种方法是常用方法,但是不太灵活,添加.删除某些图片不太方便,改动较大.这里可以考虑使用PixmapPacker将图片进行动态打包. 主要方法: pack(String name, Pixm

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

Cocos2d-x 是时下最热门的手游引擎,在国内和国外手机游戏开发使用的份额各自是70%和25%,在App Store的top10中,有7个是用它开发的. 本节课程为Cocos2d-x系列课程之九,学习BOX2D物理引擎! 学习路径图: 课程适合小白系统学习,仅需6个课时,在极客学院首席讲师风趣幽默的课程里轻松掌握BOX2D物理引擎.恭喜你也从此将走上为牛X程序员的不归路. 今年上午9点正式上线,请别再期待娱乐圈的新闻了,马上開始学习吧>>> 我们还有很多其它更新更实战的课程,登录极客