2014-06-26 35 views
2

我正在尝试在3d中创建弹跳球uisng libgdx的程序。我完全初学者刚刚开始在libgdx上进行操作。我能够检测球拍和球却无力间的冲突让它反弹使用bullet3d物理弹跳在libgdx中的球

Here is my complete code 

    public class Main implements ApplicationListener { 
     final static short GROUND_FLAG = 1 << 8; 
     final static short OBJECT_FLAG = 1 << 9; 
     final static short ALL_FLAG = -1; 

     class MyContactListener extends ContactListener { 
      @Override 
      public boolean onContactAdded(int userValue0, int partId0, int index0, 
        int userValue1, int partId1, int index1) { 
       //instances.get(userValue0).moving = false; 
       //instances.get(userValue1).moving = false; 
       return true; 
      } 
     } 

     static class MyMotionState extends btMotionState { 
      Matrix4 transform; 

      @Override 
      public void getWorldTransform(Matrix4 worldTrans) { 
       worldTrans.set(transform); 
      } 

      @Override 
      public void setWorldTransform(Matrix4 worldTrans) { 
       transform.set(worldTrans); 
      } 
     } 

     static class GameObject extends ModelInstance implements Disposable { 

      public final btRigidBody body; 
      public boolean moving; 
      public final MyMotionState motionState; 

      public GameObject(Model model, String node, 
        btRigidBody.btRigidBodyConstructionInfo constructionInfo) { 
       super(model, node); 
       motionState = new MyMotionState(); 
       motionState.transform = transform; 
       body = new btRigidBody(constructionInfo); 
       body.setMotionState(motionState); 
      } 

      @Override 
      public void dispose() { 
       // TODO Auto-generated method stub 
       body.dispose(); 
       motionState.dispose(); 
      } 

      static class Constructor implements Disposable { 
       public final Model model; 
       public final String node; 
       public final btCollisionShape shape; 
       public final btRigidBody.btRigidBodyConstructionInfo constructionInfo; 
       public static Vector3 inertia = new Vector3(); 

       public Constructor(Model model, String node, 
         btCollisionShape shape, float mass) { 
        this.model = model; 
        this.node = node; 
        this.shape = shape; 
        if (mass > 0f) { 
         shape.calculateLocalInertia(mass, inertia); 
        } else { 
         inertia.set(0, 0, 0); 
        } 
        this.constructionInfo = new btRigidBody.btRigidBodyConstructionInfo(
          mass, null, shape, inertia); 
       } 

       public GameObject construct() { 
        return new GameObject(model, node, constructionInfo); 
       } 

       @Override 
       public void dispose() { 
        shape.dispose(); 
        constructionInfo.dispose(); 
       } 
      } 
     } 

     PerspectiveCamera camera; 
     Environment environment; 
     ModelBatch modelBatch; 
     Model model; 
     Array<GameObject> instances; 
     ArrayMap<String, GameObject.Constructor> constructors; 
     btCollisionConfiguration configuration; 
     btDispatcher dispatcher; 
     btBroadphaseInterface broadphaseInterface; 
     btDynamicsWorld dynamicWorld; 
     btConstraintSolver solver; 
     MyContactListener contactListener; 
     float spawTimer; 

     @Override 
     public void create() { 
      // TODO Auto-generated method stub 
      Bullet.init(); 

      modelBatch = new ModelBatch(); 
      environment = new Environment(); 
      environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 
        0.4f, 0.4f, 1f)); 
      environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, 
        -0.8f, -0.2f)); 

      camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), 
        Gdx.graphics.getHeight()); 
      camera.position.set(3f, 7f, 10f); 
      camera.lookAt(0, 4f, 0); 
      camera.near = 1f; 
      camera.far = 300f; 
      camera.update(); 

      ModelBuilder builder = new ModelBuilder(); 

      builder.begin(); 
      builder.node().id = "ground"; 
      builder.part("ground", GL20.GL_TRIANGLES, 
        Usage.Position | Usage.Normal, 
        new Material(ColorAttribute.createDiffuse(Color.RED))).box(5f, 
        1f, 5f); 
      builder.node().id = "sphere"; 
      builder.part("sphere", GL20.GL_TRIANGLES, 
        Usage.Position | Usage.Normal, 
        new Material(ColorAttribute.createDiffuse(Color.GREEN))) 
        .sphere(1f, 1f, 1f, 10, 10); 
      model = builder.end(); 
      constructors = new ArrayMap<String, Main.GameObject.Constructor>(
        String.class, GameObject.Constructor.class); 

      constructors.put("ground", new GameObject.Constructor(model, "ground", 
        new btBoxShape(new Vector3(2.5f, .5f, 2.5f)), 0f)); 
      constructors.put("ball", new GameObject.Constructor(model, "sphere", 
        new btSphereShape(0.5f), 3f)); 

      configuration = new btDefaultCollisionConfiguration(); 
      dispatcher = new btCollisionDispatcher(configuration); 
      solver = new btSequentialImpulseConstraintSolver(); 
      broadphaseInterface = new btDbvtBroadphase(); 
      dynamicWorld = new btDiscreteDynamicsWorld(dispatcher, 
        broadphaseInterface, solver, configuration); 
      dynamicWorld.setGravity(new Vector3(0, -10, 0)); 
      contactListener = new MyContactListener(); 

      instances = new Array<Main.GameObject>(); 
      GameObject object = constructors.get("ground").construct(); 
      object.body.setCollisionFlags(object.body.getCollisionFlags() 
        | btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT); 
      instances.add(object); 
      dynamicWorld.addRigidBody(object.body); 
      object.body.setActivationState(Collision.DISABLE_DEACTIVATION); 
      createBall(); 

     } 

     public void createBall() { 
      GameObject obj = constructors.get("ball").construct(); 
      //obj.moving = true; 
      obj.transform.setFromEulerAngles(MathUtils.random(360f), 
        MathUtils.random(360f), MathUtils.random(360f)); 
      obj.transform.trn(0f, 9f, 0f); 
      //obj.body.proceedToTransform(obj.transform); 
      obj.body.setRestitution(1.0f); 
      obj.body.setFriction(1.0f); 
      obj.body.setWorldTransform(obj.transform); 
      obj.body.setUserValue(instances.size); 
      obj.body.setCollisionFlags(obj.body.getCollisionFlags() 
        | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); 
      instances.add(obj); 
      // dynamicWorld.addCollisionObject(obj.body, OBJECT_FLAG, GROUND_FLAG); 
      dynamicWorld.addRigidBody(obj.body); 
     } 

     @Override 
     public void resize(int width, int height) { 

     } 

     float angle, speed = 10f; 

     @Override 
     public void render() { 
      // TODO Auto-generated method stub 
      final float delta = Gdx.graphics.getDeltaTime(); 

      angle = (angle + delta+speed) % 360; 
      instances.get(0).transform.setTranslation(0f,MathUtils.sinDeg(angle),0f); 
      //instances.get(0).body.setWorldTransform(instances.get(0).transform); 
      dynamicWorld.stepSimulation(delta, 5, 1/60f); 


      Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.f); 
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 

      modelBatch.begin(camera); 
      modelBatch.render(instances, environment); 
      modelBatch.end(); 
     } 

     @Override 
     public void pause() { 

     } 

     @Override 
     public void resume() { 

     } 

     @Override 
     public void dispose() { 
      // TODO Auto-generated method stub 
      for (GameObject obj : instances) 
       obj.dispose(); 
      instances.clear(); 

      for (GameObject.Constructor ctor : constructors.values()) 
       ctor.dispose(); 
      constructors.clear(); 

      dynamicWorld.dispose(); 
      solver.dispose(); 
      broadphaseInterface.dispose(); 
      dispatcher.dispose(); 
      configuration.dispose(); 

      contactListener.dispose(); 

      modelBatch.dispose(); 
      model.dispose(); 
     } 

    } 
} 

这是我更新的代码,现在我能够反弹地面这不是我的目标,但我的目标是当它碰到代码申请移动的地面无法接球时弹跳球。请帮忙。

回答

1

下面是代码。最后球反弹

public class Main implements ApplicationListener { 
    final static short GROUND_FLAG = 1 << 8; 
    final static short OBJECT_FLAG = 1 << 9; 
    final static short ALL_FLAG = -1; 
    public float delta; 

    class MyContactListener extends ContactListener { 
     @Override 
     public boolean onContactAdded(int userValue0, int partId0, int index0, 
       int userValue1, int partId1, int index1) { 
      // Gdx.app.log("onContact", "onContact Added"); 
      instances.get(1).body.setLinearVelocity(new Vector3(0, 10f, 0f)); 
      return true; 
     } 
    } 

    static class MyMotionState extends btMotionState { 
     Matrix4 transform; 

     @Override 
     public void getWorldTransform(Matrix4 worldTrans) { 
      worldTrans.set(transform); 
     } 

     @Override 
     public void setWorldTransform(Matrix4 worldTrans) { 
      transform.set(worldTrans); 
     } 
    } 

    static class GameObject extends ModelInstance implements Disposable { 

     public final btRigidBody body; 
     public boolean moving; 
     public final MyMotionState motionState; 

     public GameObject(Model model, String node, 
       btRigidBody.btRigidBodyConstructionInfo constructionInfo) { 
      super(model, node); 
      motionState = new MyMotionState(); 
      motionState.transform = transform; 
      body = new btRigidBody(constructionInfo); 
      body.setMotionState(motionState); 
     } 

     @Override 
     public void dispose() { 
      // TODO Auto-generated method stub 
      body.dispose(); 
      motionState.dispose(); 
     } 

     static class Constructor implements Disposable { 
      public final Model model; 
      public final String node; 
      public final btCollisionShape shape; 
      public final btRigidBody.btRigidBodyConstructionInfo constructionInfo; 
      public static Vector3 inertia = new Vector3(); 


      public Constructor(Model model, String node, 
        btCollisionShape shape, float mass) { 
       this.model = model; 
       this.node = node; 
       this.shape = shape; 
       if (mass > 0f) { 
        shape.calculateLocalInertia(mass, inertia); 

       } else { 
        inertia.set(0, 0, 0); 
       } 
       this.constructionInfo = new btRigidBody.btRigidBodyConstructionInfo(
         mass, null, shape, inertia); 
      } 

      public GameObject construct() { 
       return new GameObject(model, node, constructionInfo); 
      } 

      @Override 
      public void dispose() { 
       shape.dispose(); 
       constructionInfo.dispose(); 
      } 
     } 
    } 

    PerspectiveCamera camera; 
    Environment environment; 
    ModelBatch modelBatch; 
    Model model; 
    Array<GameObject> instances; 
    ArrayMap<String, GameObject.Constructor> constructors; 
    btCollisionConfiguration configuration; 
    btDispatcher dispatcher; 
    btBroadphaseInterface broadphaseInterface; 
    btDynamicsWorld dynamicWorld; 
    btConstraintSolver solver; 
    MyContactListener contactListener; 
    float spawTimer; 
    GameObject obj; 

    @Override 
    public void create() { 
     // TODO Auto-generated method stub 
     Bullet.init(); 

     modelBatch = new ModelBatch(); 
     environment = new Environment(); 
     environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 
       0.4f, 0.4f, 1f)); 
     environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, 
       -0.8f, -0.2f)); 

     camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), 
       Gdx.graphics.getHeight()); 
     camera.position.set(3f, 7f, 10f); 
     camera.lookAt(0, 4f, 0); 
     camera.near = 1f; 
     camera.far = 300f; 
     camera.update(); 

     ModelBuilder builder = new ModelBuilder(); 

     builder.begin(); 
     builder.node().id = "ground"; 
     builder.part("ground", GL20.GL_TRIANGLES, 
       Usage.Position | Usage.Normal, 
       new Material(ColorAttribute.createDiffuse(Color.RED))).box(5f, 
       1f, 5f); 
     builder.node().id = "sphere"; 
     builder.part("sphere", GL20.GL_TRIANGLES, 
       Usage.Position | Usage.Normal, 
       new Material(ColorAttribute.createDiffuse(Color.GREEN))) 
       .sphere(1f, 1f, 1f, 10, 10); 
     model = builder.end(); 
     constructors = new ArrayMap<String, Main.GameObject.Constructor>(
       String.class, GameObject.Constructor.class); 

     constructors.put("ground", new GameObject.Constructor(model, "ground", 
       new btBoxShape(new Vector3(2.5f, .5f, 2.5f)), 0f)); 
     constructors.put("ball", new GameObject.Constructor(model, "sphere", 
       new btSphereShape(0.5f), 0.5f)); 

     configuration = new btDefaultCollisionConfiguration(); 
     dispatcher = new btCollisionDispatcher(configuration); 
     solver = new btSequentialImpulseConstraintSolver(); 
     broadphaseInterface = new btDbvtBroadphase(); 
     dynamicWorld = new btDiscreteDynamicsWorld(dispatcher, 
       broadphaseInterface, solver, configuration); 
     dynamicWorld.setGravity(new Vector3(0, -8f, 0)); 
     contactListener = new MyContactListener(); 

     instances = new Array<Main.GameObject>(); 
     GameObject object = constructors.get("ground").construct(); 
     object.body.setCollisionFlags(object.body.getCollisionFlags() 
       | btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT); 
     instances.add(object); 
     dynamicWorld.addRigidBody(object.body); 
     object.body.setActivationState(Collision.DISABLE_DEACTIVATION); 
     createBall(); 

    } 

    public void createBall() { 
     obj = constructors.get("ball").construct(); 

     obj.transform.trn(0f, 11f, 0f); 
     obj.body.setWorldTransform(obj.transform); 
     obj.body.setUserValue(instances.size); 
     obj.body.setCollisionFlags(obj.body.getCollisionFlags() 
       | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); 
     obj.body.setFriction(1.0f); 
     obj.body.setRestitution(3.0f); 
     instances.add(obj); 

     dynamicWorld.addRigidBody(obj.body); 
    } 

    @Override 
    public void resize(int width, int height) { 

    } 

    float angle, speed = 10f, yTranslate = 0f, zAngle = 0f; 

    @Override 
    public void render() { 
     // TODO Auto-generated method stub 
     delta = Gdx.graphics.getDeltaTime(); 
     angle = (angle + delta + speed) % 360; 

     if (Gdx.input.isTouched()) { 

      if (yTranslate > -60f) { 
       zAngle -= 0.2f; 
      } else { 
       // yTranslate = 30f; 
      } 
      instances.get(0).transform.setToRotation(0f, 0f, 2f, zAngle); 


     } else { 
      instances.get(0).transform.setToRotation(0f, 0f, 1f, 30f); 
      instances.get(0).transform.setTranslation(0f, 0f, 0f); 
     } 

     //instances.get(0).transform.setTranslation(0f,0f,0f); 
     dynamicWorld.stepSimulation(delta, 5, 1/60f); 

     Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.f); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 
     modelBatch.begin(camera); 
     modelBatch.render(instances, environment); 
     modelBatch.end(); 
    } 

    @Override 
    public void pause() { 

    } 

    @Override 
    public void resume() { 

    } 

    @Override 
    public void dispose() { 
     // TODO Auto-generated method stub 
     for (GameObject obj : instances) 
      obj.dispose(); 
     instances.clear(); 

     for (GameObject.Constructor ctor : constructors.values()) 
      ctor.dispose(); 
     constructors.clear(); 

     dynamicWorld.dispose(); 
     solver.dispose(); 
     broadphaseInterface.dispose(); 
     dispatcher.dispose(); 
     configuration.dispose(); 

     contactListener.dispose(); 

     modelBatch.dispose(); 
     model.dispose(); 
    } 

} 
0

您正在阅读的collisionif声明中检测到!collision并且当发生碰撞时不再进行读取并且碰撞将永远保持为真。

你应该做的是:

  • 有一些变量,用于存储球的x,y和z COORDS,而且还可以存储VX,VY和VZ的球速。每次(碰撞值的移动阅读了if语句)
  • 当碰撞发生,你应该在什么侧球检查
  • 检查碰撞命中和反转适当变速
  • 如果你是根据时间运动中的球自从最后一帧以来,可能发生的情况是,在第一次球弹起后,较少的时间已经过去,并且球移动得比之前的帧少,所以球仍然与平面(表面,物体)碰撞,再次弹起并保持弹跳(卡住)。要解决这个问题,您可以:

    a)不仅仅是反转球的速度,而是根据击中哪一侧来设置新的速度。即如果球击中左侧则始终将vX设置为+某物,而不仅仅是反转。 b)为下一帧(如果可能的话)提前检查碰撞,以便在球进入表面之前球会被反弹。

    C)以某种方式提供恒定的球的速度,因此,如果球进入表面并获得弹下一帧它会在2 possition帧之前,和出表面..

+0

请检查编辑 –