2014-06-26 3 views
2

J'essaie de créer un programme de balles rebondissantes uisng libgdx en 3d.Je suis débutant complet a commencé à mettre la main sur libgdx. Je suis en mesure de détecter la collision entre la chauve-souris et la balle, mais incapable de l'obtenir rebondiBouncing ball dans libgdx en utilisant la physique bullet3d

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(); 
     } 

    } 
} 

Voici mon code mis à jour en ce moment je suis en mesure de faire rebondir le terrain qui n'est pas mon objectif, mais mon objectif est de rebondir la balle quand il frappe le code appliqué pour le déplacement du sol est incapable d'être apposé à la balle. S'il vous plaît aider.

Répondre

1

Voici le code. Enfin la balle rebondit

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

Vous lisez collision de if déclaration qui teste !collision et en cas de collision, aucune autre lecture ne sera effectuée et la collision restera vraie pour toujours.

Ce que vous devez faire est:

  • ont des variables pour stocker x, y et z coords de la balle, mais aussi stocker vX VY VZ et pour la vitesse de balle.
  • vérification de collision chaque fois (mouvement lecture de la valeur de collision sur instruction if)
  • lorsque la collision vous arrive doit vérifier dans quelle boule de côté frappé et inverser la vitesse appropriée de variable
  • si vous la balle en mouvement en fonction du temps passé depuis la dernière image, il peut arriver qu'après que la balle a rebondi la première fois moins de temps est passé et que la balle a bougé moins que l'image précédente, la balle est toujours en collision avec le plan (surface, objet), rebondit. Pour résoudre ce problème, vous pouvez:

    a) non seulement d'inverser la vitesse de la balle, mais de définir une nouvelle vitesse en fonction du côté touché. C'est à dire. si la balle frappe le côté gauche, mettez toujours vX à + quelque chose, et pas seulement l'inverser. B) vérifier la collision à l'avance, pour la prochaine image (si possible) afin que la balle rebondisse avant même qu'elle n'entre dans la surface.

    c) une certaine façon de fournir une vitesse de balle constante, donc si la balle pénètre dans la surface et obtenir rebondissait image suivante, il sera à possition 2 cadre avant, et hors de la surface ..

+0

Veuillez vérifier la modification –

Questions connexes