2017-03-08 6 views
1

J'essaie de créer une classe dérivée ContactListener dans Libgdx en utilisant Bullet wrapper pour la détection de collision comme dans ce tutorial mais dans des classes séparées. Il sépare les classes pour le rendu et le monde du jeu. Dans render() méthode de classe Render je passe un tableau d'instances de modèle à cette classe dérivée. Mais quand je cours, ça donne un parce que la taille du tableau est nulle. Voici la classe dérivée:Pourquoi la taille de tableau dans ma classe dérivée ContactListener dans Libgdx Bullet est toujours zéro?

package com.anutrix.brickbreaker3d.Helpers; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.g3d.ModelInstance; 
import com.badlogic.gdx.physics.bullet.collision.ContactListener; 
import com.badlogic.gdx.utils.Array; 

public class CollisionListener extends ContactListener { 

    private Array<ModelInstance> instances; 

    public CollisionListener() { 
     this.instances = new Array<ModelInstance>(); 
    } 

    public void setModelInstances(Array<ModelInstance> instances) { 
     this.instances = instances; 
    } 

    @Override 
    public boolean onContactAdded(int userValue0, int partId0, int index0, int userValue1, int partId1, int index1) { 
//instances.get(colObj1Wrap.getCollisionObject().getUserValue()).collided = false;error 
     Gdx.app.log("instances.size", Integer.toString(instances.size));//zero 
     Gdx.app.log("ddhbdfhd", "fhfgjfgj"); 
     return true; 
    } 
} 

Voici la classe Renderer:

package com.anutrix.brickbreaker3d.gameWorld; 

import com.anutrix.brickbreaker3d.gameObjects.Ball; 
import com.anutrix.brickbreaker3d.gameObjects.Brick; 
import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.graphics.PerspectiveCamera; 
import com.badlogic.gdx.graphics.g3d.Environment; 
import com.badlogic.gdx.graphics.g3d.ModelBatch; 
import com.badlogic.gdx.graphics.g3d.ModelInstance; 
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; 
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight; 
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController; 
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; 
import com.badlogic.gdx.physics.bullet.DebugDrawer; 
import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher; 
import com.badlogic.gdx.physics.bullet.collision.btCollisionWorld; 
import com.badlogic.gdx.physics.bullet.collision.btDbvtBroadphase; 
import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration; 
import com.badlogic.gdx.physics.bullet.linearmath.btIDebugDraw; 
import com.badlogic.gdx.utils.Array; 
import com.badlogic.gdx.utils.Disposable; 

public class GameRenderer implements Disposable { 

    private GameWorld gameWorld; 
    private PerspectiveCamera cam; 
    public ModelBatch modelBatch; 
    private CameraInputController camController; 
    private Environment environment; 
    public Array<ModelInstance> instances; 
    ModelBuilder mb = new ModelBuilder(); 
    btCollisionDispatcher dispatcher; 

    public GameRenderer(GameWorld world) { 
     this.modelBatch = new ModelBatch(); 
     this.environment = new Environment(); 
     this.instances = new Array<ModelInstance>(); 

     gameWorld = world; 
     cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 
     cam.position.set(10f, 10f, 0f); 
     cam.lookAt(0, 0, 0); 
     cam.near = 1f; 
     cam.far = 300f; 
     cam.update(); 

     camController = new CameraInputController(cam); 
     Gdx.input.setInputProcessor(camController); 
     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)); 


    } 

    public void render() { 
     //Gdx.app.log("GameRenderer", "render"); 
     Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 
     Gdx.gl.glClearColor(0f, 0.2f, 0.2f, 1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 

     for (Brick b : gameWorld.bricks) { 
      b.getObject().setUserValue(instances.size); 
      instances.add(b.getModelInstance()); 
     } 
     for (Ball b : gameWorld.balls) { 
      b.getObject().setUserValue(instances.size); 
      instances.add(b.getModelInstance()); 
     } 

     gameWorld.collisionListener.setModelInstances(instances); 

     modelBatch.begin(cam); 
     modelBatch.render(instances, environment); 
     modelBatch.end(); 

     instances.clear(); 

    } 

    @Override 
    public void dispose() { 
     modelBatch.dispose(); 
    } 

} 

Qu'est-ce que je fais mal? À l'intérieur de setModelInstances(), la propriété instances.size est correcte. Mais après chaque appel, le instances.size est égal à 0. Aussi je n'étais pas sûr de passer par référence (puisque Java utilise la valeur de passe). Alors est-ce mieux (si cela fonctionne) si j'appelle setInstances() juste une fois?

Répondre

2

Tant vos CollisionListener#instances et GameRenderer#instances pointent vers la même référence après votre appel à gameWorld.collisionListener.setModelInstances(instances); à l'intérieur de votre méthode GameRenderer#render().

Puis, à la fin de la méthode, vous invoquez:

instances.clear(); 

Ce serait curage instances. Ainsi, la taille deviendrait 0 lorsque vous appelez render.


Au lieu de cela, à l'intérieur de votre méthode setModelInstances, vous pouvez créer une nouvelle instance Array comme ceci:

public void setModelInstances(Array<ModelInstance> instances) { 
    this.instances = new Array<>(instances); 
} 

Hope this helps!

+0

Puis comment puis-je remplacer 'instances.clear();'. Si j'enlève cela, le nombre d'instances après chaque boucle augmenterait simplement. – Anutrix

+1

@Anutrix vous pouvez copier le tableau dans 'setModelInstances' (au lieu d'assigner la référence) – UnholySheep

+0

Voir ma mise à jour de la réponse. – anacron