zoukankan      html  css  js  c++  java
  • 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也能够很好的结合起来一起显示,很方便。

  • 相关阅读:
    jQuery的优点——(一)
    js学习之函数表达式及闭包
    js的面向对象的程序设计之理解继承
    js之引用类型
    js的基本概念详解
    有关js的变量、作用域和内存问题
    js和HTML结合(补充知识:如何防止文件缓存的js代码)
    富豪凯匹配串
    2018 ccpc final
    蒟蒻的个人第一篇博客
  • 原文地址:https://www.cnblogs.com/MiniHouse/p/3779764.html
Copyright © 2011-2022 走看看