Partage
  • Partager sur Facebook
  • Partager sur Twitter

[LUA] problème de tableau

Sujet résolu
    1 septembre 2020 à 17:22:35

    Bonjour à tous, je m'adresse à vous dans ce post car j'ai un petit problème avec des tableaux en lua voici le code :

    raquette = {}
    raquette.x = 0
    raquette.y = 0
    
    player1 = {}
    player1.raquette = raquette
    player1.raquette.x = 50
    
    player2 = {}
    player2.raquette = raquette
    player2.raquette.x = 500
    
    print(player1.raquette.x)
    print(player2.raquette.x)

    En gros mon problème est que avec ce code que ce soit le player1 ou 2 si je change la valeur de x elle change pour les deux...

    Pourtant ce sont deux variables différentes dans deux tableaux différents non ?

    Si quelqu'un peut m'expliquer pourquoi c'est sympa ! :D

    • Partager sur Facebook
    • Partager sur Twitter
      2 septembre 2020 à 3:26:44

      En lua, mettre une valeur dans une variable ne la duplique pas, mais partage la référence sur la valeur. Ce qui veut dire que les variables raquette, player1.raquette et player2.raquette font toutes 3 référence à la même table.

      Cela ne se voit qu'avec les tables puisque tous les autres types sont immutables et le seul moyen d'altérer la valeur est d'en mettre une nouvelle, donc modifier la référence.

      Pour ton problème, il te faut copier chaque élément dans une nouvelle table ou faire une fonction qui retourne une nouvelle raquette.

      • Partager sur Facebook
      • Partager sur Twitter
        4 septembre 2020 à 12:07:09

        Salut,

        Comme dit jo_link_noir ce comportement vient du fait que l'assignation de tableau partage la référence et pas une copie

        Ce que tu souhaites faire avec raquette ressemble à une classe. Malheureusement il n'y a pas de mécanisme de classe dans le language donc il faut l'implementer si besoin

        Je te laisse cet exemple d'implémentation simple qui m'avait bien aidé à comprendre pour que tu puisse à ton tour l'étudier et comprendre, pour l'appliquer à ta raquette

        Vector2D = {}
        Vector2D.__index = Vector2D
        
        -- constructeur
        function Vector2D.new(x, y)
          local instance = {}
          setmetatable(instance, Vector2D)
          
          -- definition des variables membres
          instance.x = x or 0
          instance.y = y or 0
          
          return instance
        end
        setmetatable(Vector2D, {__call = function(self, ...) return Vector2D.new(...) end})
        
        -- redéfinition des opérateurs
        function Vector2D:__tostring()
          return "(" .. self.x .. ", " .. self.y .. ")"
        end
        
        function Vector2D.__add(lhs, rhs)
          return Vector2D(lhs.x+rhs.x, lhs.y+rhs.y)
        end
        
        function Vector2D.__sub(lhs, rhs)
          return Vector2D(lhs.x-rhs.x, lhs.y-rhs.y)
        end
        
        function Vector2D.__eq(lhs, rhs)
          return lhs.x == rhs.x and lhs.y == rhs.y
        end
        
        -- définition des fonctions membres
        function Vector2D:invert()
          local oldX = self.x
          self.x = self.y
          self.y = oldX
        end
        
        a = Vector2D(2, 5)
        b = Vector2D(5, 2)
        print(a)
        print(b)
        print(a==b)
        print(a+b)
        print(a-b)
        print(b-a)
        a:invert()
        print(a)
        print(a==b)
        

        N'hésite pas à te renseigner sur des sites tel que lua users wiki

        • Partager sur Facebook
        • Partager sur Twitter
        Dream on, Dream on, Dream until your dream comes true
          4 septembre 2020 à 15:37:49

          Bonjour ! Alors d'abord merci beaucoup pour vos réponses ! J'ai bien compris ! :D

          Voici du coup la solution que j'avais mis en place je suis sur que l'on peut faire mieux mais au moins ça marche !

          Je trouve ça un peu répétitif comme façon de faire et j'ai cru comprendre que réécrire deux fois le même code est signe d' "erreur"...

          (Il y a un peu plus de chose qu'avant mais je pense pas vous perdre :P)

          player1 = {}
            player1.score = 0
            player1.raquette = {}
            player1.raquette.w = 30
            player1.raquette.h = 200
            player1.raquette.x = 0
            player1.raquette.y = fenetre.h / 2 - player1.raquette.h / 2
            player1.raquette.vitesse = 300
          
            player2 = {}
            player2.score = 0
            player2.raquette = {}
            player2.raquette.w = 30
            player2.raquette.h = 200
            player2.raquette.x = fenetre.w - player2.raquette.w
            player2.raquette.y = fenetre.h / 2 - player2.raquette.h / 2
            player2.raquette.vitesse = 300

          Si vous avez d'autre moyen de faire ça, je prend !

          Sinon Romantik j’avoue ne pas tout comprendre dans l'exemple donné mais je vais m'y pencher un peu plus et tester le code !

          Encore un grand merci à vous deux !

          • Partager sur Facebook
          • Partager sur Twitter
            4 septembre 2020 à 16:11:24

            jo_link_noir a écrit:

            Pour ton problème, il te faut copier chaque élément dans une nouvelle table ou faire une fonction qui retourne une nouvelle raquette.


            Pour éviter d'écrire deux fois le même code, tu peux en faire une fonction et l'appeler deux fois, c'est d'ailleurs à ça que sert une fonction

            et donc avoir quelque chose comme cela

            RAQUETTE_HEIGHT = 200
            RAQUETTE_WIDTH = 30
            
            function createRaquette(x, y)
              local raquette = {}
              raquette.w = RAQUETTE_WIDTH
              raquette.h = RAQUETTE_HEIGHT
              raquette.x = x
              raquette.y = y
              raquette.vitesse = 300
              return raquette
            end
            
            player1 = {}
            player1.score = 0
            player1.raquette = createRaquette(0, fenetre.h/2-RAQUETTE_HEIGHT/2)
            
            player2 = {}
            player2.score = 0
            player2.raquette = createRaquette(fenetre.w-RAQUETTE_WIDTH, fenetre.h/2-RAQUETTE_HEIGHT/2)

            En regardant mon exemple de plus près tu t'appercevras que mon exemple avec Vector2D est juste un exemple plus complet de ça en ajoutant les opérateurs et des fonctions membres, mais c'est vraiment le même principe

            EDIT : Connais-tu déjà un autre langage de programmation pour adapté les explications et/ou vocabulaire ?

            EDIT2 : On peut voir que tu construis également tes 2 players de la même manière, tu pourrais là encore rassembler le processus de construction dans une fonction (d'où le terme constructeur)

            -
            Edité par romantik 4 septembre 2020 à 16:55:45

            • Partager sur Facebook
            • Partager sur Twitter
            Dream on, Dream on, Dream until your dream comes true
              4 septembre 2020 à 22:11:29

              Alors si j'ai bien compris la je dois être pas mal !

              La création des joueurs :

              player1 = createPlayer(1)
              player2 = createPlayer(2)

              La fonction createPLayer :

              function createPlayer(nJoueur)
                local player = {}
                
                player.score = 0
                if nJoueur == 1 then
                  player.raquette = createRaquette(0, fenetre.h / 2 - raquetteH / 2) --raquette à gauche
                elseif nJoueur == 2 then
                  player.raquette = createRaquette(fenetre.w - raquetteW, fenetre.h / 2 - raquetteH / 2) -- raquette à droite
                end
                
                return player
              end



              la fonction create raquette :

              function createRaquette(x ,y)
                local raquette = {}
                
                raquette.w = 30
                raquette.h = 200
                raquette.x = x
                raquette.y = y
                raquette.vitesse = 300
                
                return raquette
              end

              Pas trop mal ? :-°

              romantik a écrit:

              EDIT : Connais-tu déjà un autre langage de programmation pour adapté les explications et/ou vocabulaire ?

              Edité par romantik il y a environ 4 heures

              Oui j'ai du mal avec les citations...

              J'ai des bases en C++ et si j'essaye de faire le lien et pas d'énervement si j'ai tord :P. Dans l'exemple que tu m'as donné enfaîtes les fonctions sont un peu comme de la surcharge d'opérateur ?

              Mais dans un contexte plus général c'est juste des méthodes mais d'une variable au lieu d'un objet ?

              Encore un grand merci pour votre aide !

              Et si vous vous posiez la question le code c'est pour un pong ! :D

              -
              Edité par MagretsDeCanard 4 septembre 2020 à 22:13:55

              • Partager sur Facebook
              • Partager sur Twitter
                7 septembre 2020 à 14:43:15

                Si tu caractérises un joueur par son numéro, ok

                D'un point de vue implémentation, tu peux factoriser ton if, seul le premier argument de createRaquette change

                MagretsDeCanard a écrit:

                J'ai des bases en C++ et si j'essaye de faire le lien et pas d'énervement si j'ai tord :P. Dans l'exemple que tu m'as donné enfaîtes les fonctions sont un peu comme de la surcharge d'opérateur ?

                Mais dans un contexte plus général c'est juste des méthodes mais d'une variable au lieu d'un objet ?


                Oui, le mécanisme n'est pas du tout le même, mais c'est bien cet effet, je défini des fonctions particulières, données par la doc, dans une table, puis je me sers de cette table en tant que metatable de mon instance. C'est ce mécanisme de metatable qui permet de surcharger les opérateurs, mais effectivement la table Vector2D est aussi une simple variable contenant une table, et peut être modifiée à tout moment, ce n'est pas statique comme une classe C++ qui n'est évaluée qu'à la compilation
                • Partager sur Facebook
                • Partager sur Twitter
                Dream on, Dream on, Dream until your dream comes true
                  20 septembre 2020 à 18:22:15

                  OK super merci beaucoup pour vos réponses !

                  Magrets.

                  • Partager sur Facebook
                  • Partager sur Twitter

                  [LUA] problème de tableau

                  × 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