Forums Développement Multimédia

Aller au contenu

Labyrinthe, tableau et collision

CODE

9 réponses à ce sujet

#1 Maloria

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 24 November 2011 - 13:29 PM

Bonjour, je suis en train de faire un petit jeu avec un labyrinthe ! J'ai utilisé un tableau pour générer le niveau, je désire placer des monstres qui apparaissent par une entrée dans le laby et se déplace par eux même et gèrent leur collision. Malheureusement je suis bloqué avec une erreur 1009!!!

J'upload le fichier, j'ai pu isoler une certaine partie du code: si les lignes 110, 111, 119, 120 (image 2) sont en commentaires, l'erreur 1009 ne survient plus. Malheureusement je n'arrive pas a fixer le problème.

Merci pour tout aide !

Fichier(s) joint(s)

  • Fichier joint  tab_01.fla   10.46 Ko   12 téléchargement(s)


#2 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 24 November 2011 - 14:03 PM

Bonjour Maloria.
Et bienvenue.


Citer les lignes qui plantent, c'est très bien. Si, si ;-) Déjà, c'est rare, ça montre que tu as creusé la question…
Par contre, tu devrais, soit les citer dans ton sujet (avec la balise code que tu ajouterais grâce au bouton en forme de <>) pour que tout le monde puisse intervenir sans charger un fichier (on est nombreux à préférer agir comme ça), soit enregistrer ton fichier au format CS4 pour ceux qui sont à la traîne.

Soit les 2, d'ailleurs

par exemple, là, je ne peut rien pour toi…

Sauf généralité : l'erreur 1009 dit qu'il est impossible d'accéder à la propriété ou à la méthode d'une référence d'objet nul.
Fais un trace de toutes les variables auxquelles tu tentes d'acceder dans ces fameuses lignes et tu sauras laquelle vaut null.

#3 Maloria

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 24 November 2011 - 14:24 PM

Merci pour la réponse ! Je vais en ligne la version CS4 . Et voici la fonction concernées par mon problème:


function deplacer_PNJ(event:Event):void{

        for(var n:Number=0; n<liste_PNJ.length; n++) {
                var nom:String="monstre"+n;

                if ((monstres.getChildByName(nom).x%25==0)&&(monstres.getChildByName(nom).y%25==0)){
                        reflechir_PNJ(n) ;
                }

                var type:Number=liste_PNJ[n][0];
                var directions:Number=liste_PNJ[n][3];
                var action:Number=liste_PNJ[n][5];
                var vitesse:Number=liste_PNJ[n][4];
       
                avancer_PNJ(n) ;
                MovieClip(monstres.getChildByName(nom)).gotoAndStop(1);
        }
}
 

J'ai placé un écouteur sur l'image 1:

stage.addEventListener(Event.ENTER_FRAME, deplacer_PNJ);

Quand je met l'écouteur en commentaire, l'erreur 1009 ne survient plus.


#4 Maloria

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 24 November 2011 - 14:25 PM

Voici le fichier en CS4.

Fichier(s) joint(s)



#5 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 24 November 2011 - 14:58 PM

Ton soucis vient bien de la fonction deplacer_PNJ.

En commentant l'intérieur de la boucle for et en traçant le monstre de chaque boucle comme ceci :

function deplacer_PNJ(event:Event):void{

        for(var n:Number=0; n<liste_PNJ.length; n++) {
                var nom:String="monstre"+n;
                trace("Le monstre "+nom+ " est : "+monstres.getChildByName(nom));
//
//              if ((monstres.getChildByName(nom).x%25==0)&&(monstres.getChildByName(nom).y%25==0)){
//                      reflechir_PNJ(n) ;
//              }
//
//              var type:Number=liste_PNJ[n][0];
//              var directions:Number=liste_PNJ[n][3];
//              var action:Number=liste_PNJ[n][5];
//              var vitesse:Number=liste_PNJ[n][4];
//     
//              avancer_PNJ(n) ;
//              MovieClip(monstres.getChildByName(nom)).gotoAndStop(1);//(action *4)+directions);
        }
}
 


On obtient les trace suivants :
Le monstre monstre0 est : null
Le monstre monstre1 est : null
Le monstre monstre0 est : null
Le monstre monstre1 est : null
PNJtemp.name=monstre0
0
0
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
Le monstre monstre1 est : null
Le monstre monstre0 est : [object monstre1]
 

On a donc des appels aux monstres qui renvoient null.
A partir du moment ou ils sont nulls, tu ne peut pas cibler leurs propriétés x et y dans la ligne :
if ((monstres.getChildByName(nom).x%25==0)&&(monstres.getChildByName(nom).y%25==0)){
C'est cet appel qui déclenche la première erreur… idem pour les autres appels.

Il semble (mais ça, tu devrais mieux t'y retrouver que moi) que tu appelles une première fois cette fonction avant que les monstres soient créés. Et là, ça plante.
Ensuite, il y a appel aux monstres, mais un seul est créé. Le monstre 0.

Ce qui me semble louche, c'est que le monstre0 soit de type monstre1…

…est-ce que tu n'aurais pas oublié quelque part qu'un tableau commence à l'indice 0 et non pas 1 ?


Voilà.
J'espère que tu trouveras d'ou ça peut venir.

2 conseils en parallèle :
- utiliser des getChildByName et des noms avec des indices est une mauvais habitude selon moi. Les objets n'ont pas besoin de noms pour qu'on les retrouve. C'est lent et pas souple du tout.
- faire un jeu tout au scénario, c'est encore plus difficile que d'apprendre à écrire des classes…
:) … et quand on connaît les classes, tout est plus simple si tu vois ou je veux en venir.

#6 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 24 November 2011 - 15:14 PM

Bon, je suis plutôt perdu dans ta structure mais en tirant les bonnes ficelles on trouve ceci :


function initialiser_PNJ(){
        for (var n:Number=0; n<1; n++) {
 

Ce qui veut dire que tu ne crées qu'un seul PNJ : le PNJ 0.
Quand n augmente à 1, le test (n<1) est faux et la boucle ne s'exécute plus.

Je pense que toi, tu voudrais plutôt faire la boucle for en fonction du tableau de paramètres liste_PNJ. Non ?

function initialiser_PNJ(){
        for (var n:Number=0; n<liste_PNJ.length; n++) {
 

PS :
J'ai déplacé des morceaux de code pour mettre les fonctions d'initalisation dans la première image. C'était surtout pour comprendre, mais du coup je ne sais pas si la correction ci dessus est suffisante pour que ça marche. Je te remets mon fla.

Fichier(s) joint(s)



#7 Maloria

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 24 November 2011 - 15:23 PM

Merci pour ta réponse, je creuse la question!

#8 Maloria

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 25 November 2011 - 15:10 PM

J'ai encore un petit problème. j'ai placé le code de mon tableau sur ma timeline et j'aimerais accéder à ses valeurs pour la fonction test_case qui se trouve dans le fichier joueur.as à la ligne 48 mais je ne sais pas comment m'y prendre.
J'ai tenté une solution trouvée grâce à google:
package laby
{
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.display.Stage;

        public class joueur extends MovieClip
        {
                // ------- Declaration constantes ------------- //
                const tailleTuile:uint= 25;
                // ------- Declaration variables -------------- //
                public var nom:int;
                public var coordX:int;
                public var coordY:int;
                public var genre:int;

                // Variables servant à accéder au stage
                public var main_tableau:MovieClip;
                public var stage_instance:Stage;
               
                var PopAleatoire:uint;
               
                var caseHaut: Boolean= false;
                var caseBas: Boolean= false;
                var caseDroite: Boolean= false;
                var caseGauche: Boolean= false;
               
               
                //constructeur:fonction appelée lors de la création d'une instance de la classe "joueur"
                public function joueur(tableau_ref:MovieClip):void {
                        PopAleatoire=randomNumber(1,2);
                        if (PopAleatoire==1) {
                                coordY= 8;
                                coordX= 1;
                                this.y= coordY*tailleTuile;
                                this.x= coordX*tailleTuile;
                        }
                        if (PopAleatoire==2) {
                                coordY= 4;
                                coordX= 33;
                                this.y= coordY*tailleTuile;
                                this.x= coordX*tailleTuile;
                        }

                        // Affectation des variables d'accès au stage
                        this.main_tableau= tableau_ref;
                        var stage_:Stage= main_tableau.stage;
                        stage_instance= stage_;
                }
               
                public function test_case():void {

                        // Tentative d'accès au tableau carte déclaré dans le stage
                        if (stage_instance.carte[coordY-1][coordX]==0) {
                                caseHaut=true;
                        }
                        if (stage_instance.carte[coordY+1][coordX]==0) {
                                caseBas=true;
                        }
                        if (stage_instance.carte[coordY][coordX+1]==0) {
                                caseDroite=true;
                        }
                        if (stage_instance.carte[coordY][coordX-1]==0) {
                                caseGauche=true;
                        }
                }

Fichier(s) joint(s)



#9 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 25 November 2011 - 15:29 PM

Bravo pour t'être attaqué à une classe :)

Pour l'accès au tableau, tenter d'accéder à un parent n'est pas forcément une bonne idée. Surtout que tu vas le faire à chaque instant. Le joueur va le faire, les monstres vont le faire…

Moi, je passerais le tableau via un paramètre du constructeur.

Au départ, c'est simple : tu fais :

private var carte_:Array;
                //constructeur:fonction appelée lors de la création d'une instance de la classe "joueur"
                public function joueur(tableau_ref:MovieClip,carte:Array):void {
                        carte_=carte;
                        // ETC
 


[EDIT] Oublie la 2e partie. J'ai dit une grosse bêtise :-)[/EDIT]

Reste un problème, les arrays ne sont pas des objets partageables. En faisant ainsi, tu te retrouves avec 2 tableaux et ce que tu vas modifier dans l'un d'eux ne sera pas reporté sur l'autre…

La solution, c'est de créer également une classe pour ta carte.
Dans cette classe, tu auras un tableau et une fonction public pour accéder à une case x/y.
Tu pourras également avoir une fonction public pour récupérer les voisins nord,sud,est,ouest d'une case, etc.
Autant d'outils (de fonctions) qui seront disponibles pour joueurs et monstres, ça serait plus pratique.
Et du coup pour partage l'info, plus de souci car il n'y aura pas de copie de ta carte lors du passage de paramètre.



private var carte_:Carte;
                //constructeur:fonction appelée lors de la création d'une instance de la classe "joueur"
                public function joueur(tableau_ref:MovieClip,carte:Carte):void {
                         carte_=carte;
                        // ETC
 


Evidemment, dans ton code principal :

var Personnage:laby.joueur= new laby.joueur(this,carte);

Si tu réussis a adapter ta logique a ce principe, tu devrais avancer vite maintenant :)


#10 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 25 November 2011 - 16:39 PM

Salut,

Je plussoie ce que dit Didier, en particulier sur ce point :

if ((monstres.getChildByName(nom).x%25==0)&&(monstres.getChildByName(nom).y%25==0)){
                        reflechir_PNJ(n) ;
                }
 

C'est une grosse erreur à mon sens de passer par des noms.
Il vaut mieux passer par un tableau qui contient tous les monstres et que tu mets à jour au moment voulu.

De même, à part certains monstres qui se déplacent tout le temps, il est préférable de ne faire réfléchir que les monstres qui sont dans la zone visible (ou dans une zone où ils sont en mesure de voir le héros et de réagir en conséquence), ce qui limite fortement la vérification.



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)