Partage
  • Partager sur Facebook
  • Partager sur Twitter

NullPointerException avec le JME3

Anonyme
    17 mai 2012 à 17:22:31

    Bonjours à tous,
    je sollicite aujourd'hui l'aide de quelqu’un qui connaît le JMonkeyEngine3.
    En effet je tente depuis quelque jours de faire un mini-str avec le JMonkeyEngine3 (pour m’entraîner hein ^^) ou l'on peu sélectionner puis déplacer des models 3d (actuellement des cubes) à la souris, et j'ai toujours une NullPointerException quoique je fasse.

    Je m'excuse d'avance si le sujet à déjà été posté, j'ai fait des recherches mais je n'ai rien trouver.


    Le programme fonctionne comme cela :

    -la méthode simpleInitApp créé les objets 3d et les attaches au Node select
    public void simpleInitApp() 
        	{    
            	//init Node
            	select = new Node();
            	map = new Node();
            	
            	//basic setting
            	viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
            	flyCam.setMoveSpeed(100);
            	   
            	//load scene
            	assetManager.registerLocator("town.zip", ZipLocator.class.getName());
            	sceneModel = assetManager.loadModel("main.scene");
            	sceneModel.setLocalScale(2f);
            	
            	//add initial caracter
            	Spatial ab = new Geometry("ab",new Box(new Vector3f(0,0,0), 0.5f, 0.5f, 0.5f));
            	Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            	mat1.setColor("Color", ColorRGBA.Blue);
            	ab.setMaterial(mat1);
            	select.attachChild(ab);
            	
            	//helper method
            	initCrossHairs();
            	initLight();
            	initKey();
            
            	//add initial caracter
            	map.attachChild(sceneModel);
            le principe est le suivant
            	rootNode.attachChild(select);
            	rootNode.attachChild(map);
        	}
    


    -le listener al vérifie si des touches sont actionner :
    si le bouton gauche est cliquer : le JMonkeyEngine détecte le composant sélectionner et remplis la variable int selection avec l'id du composant sélectionner
    code :
    else if(nom.equals("select"))//si le bouton gauche de la souris est cliquer la variable nom sera = à select
                {
                    CollisionResults cr2 = new CollisionResults();
                    Ray r2 = new Ray(cam.getLocation(), cam.getDirection());
                    select.collideWith(r2, cr2);
                    for(int i = 0 ; i < cr2.size() ; i++)
                    {
                        /*int*/ selection = cr2.getCollision(i).getGeometry().getMesh().getId();
                    }
                }
    


    si le bouton droit est cliquer : le JMonkeyEngine remplis l'objet Vector3f dir(ection) avec les coordonnées du clique droit
    code :
    if(nom.equals("move"))//si le bouton droit de la souris est cliquer la variable nom sera = à move
                {
                    CollisionResults cr = new CollisionResults();
                    Ray r = new Ray(cam.getLocation(), cam.getDirection());
                    map.collideWith(r, cr);
                    for(int i = 0; i < cr.size(); i++)
                    {
                        /*Vector3f*/ dir = cr.getCollision(i).getContactPoint();
                    }
                }
    


    -la méthode update est censé actualiser les coordonnées de l'objet sélectionner pour qu'il aille vers la direction obtenue précédemment
    code :
    public void simpleUpdate(float tpf)
    	    {
    	        Vector3f v = select.getChild(selection).getLocalTranslation();
    	        if(v.z > dir.z)
    	        {
    	            while(v.z > dir.z)
    	            {
    	                float ad = speed*tpf;
    	                select.getChild(selection).setLocalTranslation(v.x, v.y, v.z + ad);
    	                
    	            }
    	        }
    	        else if(v.z < dir.z)
    	        {
    	            while(v.z < dir.z)
    	            {
    	                float ad = speed*tpf;
    	                select.getChild(selection).setLocalTranslation(v.x, v.y, v.z - ad);
    	            }
    	        }
    	        else if(v.y > dir.z)
    	        {
    	            while(v.z > dir.z)
    	            {
    	                float ad = speed*tpf;
    	                select.getChild(selection).setLocalTranslation(v.x, v.y + ad, v.z);
    	            }
    	        }
    	        else if(v.y < dir.z)
    	        {
    	            while(v.z < dir.z)
    	            {
    	                float ad = speed*tpf;
    	                select.getChild(selection).setLocalTranslation(v.x, v.y - ad, v.z);
    	            }
    	        }
    	    }
    


    mais cela me donne une NullPointerExeception :
    java.lang.NullPointerException
    	at org.LR.core.Main.simpleUpdate(Main.java:162)
    	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:258)
    	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
    	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:182)
    	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
    	at java.lang.Thread.run(Thread.java:679)
    


    Le code complet si ça peut aider (sans les import et les méthode inutiles, pour plus de clarté) :

    public class Main extends SimpleApplication
    {
        public static void main(String[] args)
        {
            Main ts = new Main();
            ts.start();
        }
        
        private Vector3f dir;
        //distance per seconde
        private float speed = 1;
        
        //model
        private Spatial sceneModel;
        
        //physic
        //not implement yet
        
        //picking
        private Node select;
        private Node map;
        private int selection = 0;
        
        //other
        //private boolean ava = false, der = false, dro = false, gau = false;
        
        
        @Override
        public void simpleInitApp() 
        {    
            //init Node
            select = new Node();
            map = new Node();
            
            //basic setting
            viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
            flyCam.setMoveSpeed(100);
               
            //load scene
            assetManager.registerLocator("town.zip", ZipLocator.class.getName());
            sceneModel = assetManager.loadModel("main.scene");
            sceneModel.setLocalScale(2f);
            
            //add initial caracter
            Spatial ab = new Geometry("ab",new Box(new Vector3f(0,0,0), 0.5f, 0.5f, 0.5f));
            Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            mat1.setColor("Color", ColorRGBA.Blue);
            ab.setMaterial(mat1);
            select.attachChild(ab);
            
            initKey();
            
            //add initial caracter
            map.attachChild(sceneModel);
            
            rootNode.attachChild(select);
            rootNode.attachChild(map);
        }
        
        //input
        
        private void initKey() 
        {
            inputManager.addMapping("move", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
            inputManager.addMapping("select", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
            inputManager.addMapping("ava", new KeyTrigger(KeyInput.KEY_Z));
            inputManager.addMapping("are", new KeyTrigger(KeyInput.KEY_S));
            inputManager.addMapping("dro", new KeyTrigger(KeyInput.KEY_Q));
            inputManager.addMapping("gau", new KeyTrigger(KeyInput.KEY_D));
            inputManager.addListener(al, new String[]{"move","select","ava","are","dro","gau"});
        }
        
        private AnalogListener al = new AnalogListener()
        {
            public void onAnalog(String nom, float val, float tps)
            {
                if(nom.equals("move"))
                {
                    CollisionResults cr = new CollisionResults();
                    Ray r = new Ray(cam.getLocation(), cam.getDirection());
                    map.collideWith(r, cr);
                    for(int i = 0; i < cr.size(); i++)
                    {
                        dir = cr.getCollision(i).getContactPoint();
                    }
                }
                else if(nom.equals("select"))
                {
                    CollisionResults cr2 = new CollisionResults();
                    Ray r2 = new Ray(cam.getLocation(), cam.getDirection());
                    select.collideWith(r2, cr2);
                    for(int i = 0 ; i < cr2.size() ; i++)
                    {
                        selection = cr2.getCollision(i).getGeometry().getMesh().getId();
                    }
                }
                /**else if(nom.equals("ava"))
                {
                    ava = true; 
                    der = false; 
                    dro = false;
                    gau = false;
                }
                else if(nom.equals("are"))
                {
                    ava = false; 
                    der = true; 
                    dro = false;
                    gau = false;
                }
                else if(nom.equals("dro"))
                {
                    ava = false; 
                    der = false; 
                    dro = true;
                    gau = false;
                }
                else if(nom.equals("gau"))
                {
                    ava = false; 
                    der = false; 
                    dro = false;
                    gau = true;
                }*/
            }
        };
        
        @Override
        public void simpleUpdate(float tpf)
        {
            Vector3f v = select.getChild(selection).getLocalTranslation();
            if(v.z > dir.z)
            {
                while(v.z > dir.z)
                {
                    float ad = speed*tpf;
                    select.getChild(selection).setLocalTranslation(v.x, v.y, v.z + ad);
                    
                }
            }
            else if(v.z < dir.z)
            {
                while(v.z < dir.z)
                {
                    float ad = speed*tpf;
                    select.getChild(selection).setLocalTranslation(v.x, v.y, v.z - ad);
                }
            }
            else if(v.y > dir.z)
            {
                while(v.z > dir.z)
                {
                    float ad = speed*tpf;
                    select.getChild(selection).setLocalTranslation(v.x, v.y + ad, v.z);
                }
            }
            else if(v.y < dir.z)
            {
                while(v.z < dir.z)
                {
                    float ad = speed*tpf;
                    select.getChild(selection).setLocalTranslation(v.x, v.y - ad, v.z);
                }
            }
        }
    


    Merci mille fois d'avance pour vôtres aide.
    • Partager sur Facebook
    • Partager sur Twitter
      17 mai 2012 à 18:07:47

      Et la ligne 162 de la classe Main.java c'est quoi ?
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        17 mai 2012 à 20:12:28

        ah oui désolé, j'avais oublié la ligne 162 dans me rapport d'erreur c'est la ligne 132 du code complet
        merci de l'avoir fait remarquer ^^
        • Partager sur Facebook
        • Partager sur Twitter
          17 mai 2012 à 20:33:20

          Dans ce cas, j'aurais tendance à dire que dans ton if de la ligne 132, tu as soit v, soit dir qui vaut null.
          Donc soit select.getChild(selection).getLocalTranslation(); te renvoie null, soit dir n'a jamais été alimenté.

          Désolé, pour l'instant je n'ai rien de mieux à proposer. :-°
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            17 mai 2012 à 21:12:44

            c'est déjà gentil d'avoir cherché un problème, je te remercie je vais chercher dans cette direction
            • Partager sur Facebook
            • Partager sur Twitter
              17 mai 2012 à 23:28:47

              le seul endroit où dir est alimenté est à la ligne 84 de ton code. C'est-à-dire dans le if, c'est-à-dire lors de l'action "move". Il ne l'est pas dans le else.

              ensuite, simpleupdate va être appelée bien avant que tu ne fasse la moindre action.

              donc, soit tu initialise dir avec quelque chose, soit tu modifies le corps de ta méthode simpleupdate.

              et là, ça dépend de la logique de ton programme (de la pertinence que dir dispose d'une valeur par défaut ou non).
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                18 mai 2012 à 9:57:11

                ok merci je n'y avait pas penser,
                je test ça ce soir

                edit : ça marche quasiment parfaitement, en revanche le seul problème maintenant c'est que quand je clique sur le bouton gauche (quand le nom de l'analogListener al est égal à select)
                ça me déclenche cette exception (note que la ligne 163 de org.LR.core.Main.simpleUpdate la ligne 131 de code complet) :

                java.lang.ArrayIndexOutOfBoundsException: -1
                	at com.jme3.util.SafeArrayList.get(SafeArrayList.java:259)
                	at com.jme3.scene.Node.getChild(Node.java:418)
                	at org.LR.core.Main.simpleUpdate(Main.java:163)
                	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:244)
                	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
                	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:182)
                	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
                	at java.lang.Thread.run(Thread.java:679)
                


                veuillez m'excusez si je vous embêtent avec ça
                mille merci pour l'aide que vous m'avez déjà apporter et merci d'avance pour votre future aide
                • Partager sur Facebook
                • Partager sur Twitter
                  19 mai 2012 à 0:00:51

                  Un conseil : évites les codes du genre qu'on appelle parfois une catastrophe ferroviaire (train wreck ou train crash en anglais)
                  selection = cr2.getCollision(i).getGeometry().getMesh().getId();
                  

                  Ça transgresse la loi de Déméter et ce n'est pas lisible.

                  Préfères quelque chose dans le style :
                  CollisionResult singleCollision = cr2.getCollision(i);
                  Geometry leafNodeDefinition = singleCollision.getGeometry();
                  Mesh renderingData = leafNodeDefinition.getMesh();
                  int id = renderingData.getId();
                  

                  ... tout en essayant de trouver des noms de variables décrivant leur contenu afin de rendre ton code plus lisible et d'éviter au maximum les commentaires.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    20 mai 2012 à 15:36:23

                    merci de ta remarque je n'avait jamais entendu parler de la loi de Démeter
                    je me coucherais moins bête ce soir ^^

                    pour le nom des variables je n'ai pas chercher des nom représentant bien leur contenu car c'était juste une phase de test pour l'instant;

                    sinon c'est bon grâce a vos conseil avisé j'ai réussis a corrigé le problème pour cela,
                    voici le code ce qui change est précédé du commentaire //change

                    private Vector3f dir;
                        //distance per seconde
                        private float speed = 1;
                        
                        //model
                        private Spatial sceneModel;
                        
                        //physic
                        //not implement yet
                        
                        //picking
                        private Node select;
                        private Node map;
                        private String selection;
                        
                        //other
                        //private boolean ava = false, der = false, dro = false, gau = false;
                        
                        
                        @Override
                        public void simpleInitApp() 
                        {   
                            //change 
                            selection = new String("ab");
                            
                            //init Node
                            select = new Node();
                            map = new Node();
                            
                            //basic setting
                            viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
                            flyCam.setMoveSpeed(100);
                               
                            //load scene
                            assetManager.registerLocator("town.zip", ZipLocator.class.getName());
                            sceneModel = assetManager.loadModel("main.scene");
                            sceneModel.setLocalScale(2f);
                            
                            //add initial caracter
                            Spatial ab = new Geometry("ab",new Box(new Vector3f(0,0,0), 0.5f, 0.5f, 0.5f));
                            Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                            mat1.setColor("Color", ColorRGBA.Blue);
                            ab.setMaterial(mat1);
                            select.attachChild(ab);
                            
                            //helper method
                            initCrossHairs();
                            initLight();
                            initKey();
                            
                            //add initial caracter
                            map.attachChild(sceneModel);
                            
                            rootNode.attachChild(select);
                            rootNode.attachChild(map);
                            
                            dir = new Vector3f(0,0,0);
                        }
                        
                        //input
                        
                        private void initKey() 
                        {
                            inputManager.addMapping("move", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
                            inputManager.addMapping("select", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
                            inputManager.addMapping("ava", new KeyTrigger(KeyInput.KEY_Z));
                            inputManager.addMapping("are", new KeyTrigger(KeyInput.KEY_S));
                            inputManager.addMapping("dro", new KeyTrigger(KeyInput.KEY_Q));
                            inputManager.addMapping("gau", new KeyTrigger(KeyInput.KEY_D));
                            inputManager.addListener(al, new String[]{"move","select","ava","are","dro","gau"});
                        }
                        
                        private AnalogListener al = new AnalogListener()
                        {
                            public void onAnalog(String nom, float val, float tps)
                            {
                                if(nom.equals("move"))
                                {
                                    CollisionResults cr = new CollisionResults();
                                    Ray r = new Ray(cam.getLocation(), cam.getDirection());
                                    map.collideWith(r, cr);
                                    for(int i = 0; i < cr.size(); i++)
                                    {
                                        CollisionResult crr = cr.getCollision(i);
                                        dir = crr.getContactNormal();
                                    }
                                }
                                else if(nom.equals("select"))
                                {
                                    CollisionResults cr2 = new CollisionResults();
                                    Ray r2 = new Ray(cam.getLocation(), cam.getDirection());
                                    select.collideWith(r2, cr2);
                                    for(int i = 0 ; i < cr2.size() ; i++)
                                    {
                                        //change
                                        CollisionResult singleCollision = cr2.getCollision(i);
                                        Spatial leafNodeDefinition = singleCollision.getGeometry();
                                        selection = leafNodeDefinition.getName();
                                    }
                                }
                            }
                        };
                        
                        @Override
                        public void simpleUpdate(float tpf)
                        {
                            //change
                            Spatial v1 = new Geometry();
                            v1 = select.getChild(selection);
                            Vector3f v = new Vector3f();
                            v = v1.getLocalTranslation();
                            if(v.z > dir.z)
                            {
                                while(v.z > dir.z)
                                {
                                    float ad = speed*tpf;
                                    select.getChild(selection).setLocalTranslation(v.x, v.y, v.z + ad);
                                    
                                }
                            }
                            else if(v.z < dir.z)
                            {
                                while(v.z < dir.z)
                                {
                                    float ad = speed*tpf;
                                    select.getChild(selection).setLocalTranslation(v.x, v.y, v.z - ad);
                                }
                            }
                            else if(v.y > dir.z)
                            {
                                while(v.z > dir.z)
                                {
                                    float ad = speed*tpf;
                                    select.getChild(selection).setLocalTranslation(v.x, v.y + ad, v.z);
                                }
                            }
                            else if(v.y < dir.z)
                            {
                                while(v.z < dir.z)
                                {
                                    float ad = speed*tpf;
                                    select.getChild(selection).setLocalTranslation(v.x, v.y - ad, v.z);
                                }
                            }
                        }
                    
                    • Partager sur Facebook
                    • Partager sur Twitter

                    NullPointerException avec le JME3

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown