Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C# et XNA]

Sujet résolu
    18 décembre 2006 à 20:44:36

    Bonjour tout le monde :D

    j'ai 2 petites questions (enfin une question et un problème en fait)

    Je voulais savoir si il était possible en C# de créer des fonctions inline ? Et si oui comment ?

    La 2ième chose ça concerne XNA studios (bien que ça puisse sans doute s'appliquer à d'autres moteurs gérant les collisions). En fait voilà j'ai fait une scène de test avec 2 objets pour tester les collisions, un des 2 objets est contrôlable, l'autre pas. Je crée une bounding sphere pour chaque objet (j'aurais pu utiliser bounding box, d'ailleur dans ce cas ça aurait été plus judicieux, mais comme je l'ai dit c'est juste un test et ça me semblait plus simple de faire une sphere, enfin bref). Arrivé au moment des déplacements (dans la fonction update()), je place ma bouding sphere aux coordonnées de l'obet comme ceci bSphere = new BoundingSphere(new Vector3(positionX, 0.0f, positionZ), 140.0f) (il s'agit donc du vector de coordonées suivi du rayon de la sphere). Alors à partir de là ça m'ennuie. les coordonnées de la sphere sont définies par bSphere.Center.X(ou Y ou Z), mais je n'arrive pas à affecter une valeur à ces variables, ça veut dire que pour que bSphere soit constamment à la position de l'objet, j'appelle
    bSphere = new BoundingSphere(new Vector3(positionX, 0.0f, positionZ), 140.0f) dans la boucle update(). Déjà ici ce qui m'embête un peu c'est que je recrée l'objet à chaque passage dans la boucle :-° c'est pas génial comme truc, m'enfin si ça n'était que ça...
    Pour tester la collision, je fais donc :

    if(!this.bSphere.Intersects(bSphere2))
    {
    if(onAppuyeSurHaut)
    {
    allerVersLeHaut...
    }
    etc...
    }
    Seulement jpeux pas faire comme ça, pck si Intersects est vrai, les déplacements ne s'effectuent plus et donc jpeux plus bouger (c'est pas génial dans un jeu si il faut éviter de toucher les murs si on veut pas rester bloquer ^^). Le résultat c'est que j'ai pas trouvé d'autre moyen que de tester la collision APRES chaque déplacement, et si il y a collision on le remet à la position qu'il était juste avant OUI MAIS, moi qui n'aimais déjà me retrouver avec une création d'objet BoundingBox à chaque boucle, voilà mtn que je me retrouve avec 4 par boucle (si on ne compte que les déplacements haut, bas, gauche et droite). Alors je sais qu'il y aurait un moyen de récupérer les données d'avant le déplacement, puis de tester si il y a intersection, et si il y en a alors restaurer les valeurs qui sont stoquées dans les variables... mais c'est pas vraiment propre jvais dire. Alors voilà si quelqu'un avait une idée qui pourrait m'être utile (bon si y a vraiment aucun autre moyen je ferais le truc avec la restauration des données d'avant collisions mais c'est en dernier recours).

    Merci (d'avoir eu la patience de me lire :p )
    • Partager sur Facebook
    • Partager sur Twitter
      18 décembre 2006 à 21:28:12

      Citation : MythTitans

      Bonjour tout le monde :D

      j'ai 2 petites questions (enfin une question et un problème en fait)

      Je voulais savoir si il était possible en C# de créer des fonctions inline ? Et si oui comment ?



      Non ce n'est pas possible, c'est au runtime de décider si il va inliner ta fonction pour plus de performance (dans la pratique les petites routines qui font un return directement son inliner).

      Citation : MythTitans

      La 2ième chose ça concerne XNA studios (bien que ça puisse sans doute s'appliquer à d'autres moteurs gérant les collisions). En fait voilà j'ai fait une scène de test avec 2 objets pour tester les collisions, un des 2 objets est contrôlable, l'autre pas. Je crée une bounding sphere pour chaque objet (j'aurais pu utiliser bounding box, d'ailleur dans ce cas ça aurait été plus judicieux, mais comme je l'ai dit c'est juste un test et ça me semblait plus simple de faire une sphere, enfin bref). Arrivé au moment des déplacements (dans la fonction update()), je place ma bouding sphere aux coordonnées de l'obet comme ceci bSphere = new BoundingSphere(new Vector3(positionX, 0.0f, positionZ), 140.0f) (il s'agit donc du vector de coordonées suivi du rayon de la sphere). Alors à partir de là ça m'ennuie. les coordonnées de la sphere sont définies par bSphere.Center.X(ou Y ou Z), mais je n'arrive pas à affecter une valeur à ces variables, ça veut dire que pour que bSphere soit constamment à la position de l'objet, j'appelle
      bSphere = new BoundingSphere(new Vector3(positionX, 0.0f, positionZ), 140.0f) dans la boucle update(). Déjà ici ce qui m'embête un peu c'est que je recrée l'objet à chaque passage dans la boucle :-° c'est pas génial comme truc, m'enfin si ça n'était que ça...
      Pour tester la collision, je fais donc :

      if(!this.bSphere.Intersects(bSphere2))
      {
      if(onAppuyeSurHaut)
      {
      allerVersLeHaut...
      }
      etc...
      }
      Seulement jpeux pas faire comme ça, pck si Intersects est vrai, les déplacements ne s'effectuent plus et donc jpeux plus bouger (c'est pas génial dans un jeu si il faut éviter de toucher les murs si on veut pas rester bloquer ^^). Le résultat c'est que j'ai pas trouvé d'autre moyen que de tester la collision APRES chaque déplacement, et si il y a collision on le remet à la position qu'il était juste avant OUI MAIS, moi qui n'aimais déjà me retrouver avec une création d'objet BoundingBox à chaque boucle, voilà mtn que je me retrouve avec 4 par boucle (si on ne compte que les déplacements haut, bas, gauche et droite). Alors je sais qu'il y aurait un moyen de récupérer les données d'avant le déplacement, puis de tester si il y a intersection, et si il y en a alors restaurer les valeurs qui sont stoquées dans les variables... mais c'est pas vraiment propre jvais dire. Alors voilà si quelqu'un avait une idée qui pourrait m'être utile (bon si y a vraiment aucun autre moyen je ferais le truc avec la restauration des données d'avant collisions mais c'est en dernier recours).

      Merci (d'avoir eu la patience de me lire :p )



      Pour traiter les collisions il y'a pas mal de méthodes différentes (XNA te permet juste de tester si il y'a collision après c'est à toi de te débrouiller pour savoir comment réagir). J'ai un bon papier sur la physique par ici qui utilise la projection pour gérer les collisions. Mais bon dans la logique de Update() on casse généralement le TimeStep en plusieurs étapes à savoir 1° on acquiert les déplacements (+ éventuellement d'autre force) 2° On calcule les nouvelles positions 3° on vérifie que les contraintes sont respecté et on ajuste la position suivant le résultat 4° on répercute les changements graphiquements.

      Pour les BoudingSphere c'est normal que rien ne change en modifiant Center.(X,Y,Z) vu que c'est directement un champ. Même si c'est pas moi qui implémente ça sur Mono.Xna je pense que c'est la méthode à effectuer (vu qu'en fait les BoudingSphere ne sont utile que lorsque tu testes les collisions) de plus ce sont des structures, donc des types valeurs qui sont donc stocké sur la pile et qui donc sont nettoyé à la fin de chaque Update il n'y a donc pas de problème de performance AMHA.
      • Partager sur Facebook
      • Partager sur Twitter
        18 décembre 2006 à 23:59:42

        Merci pour ta réponse Garuma. Je vais essayer de décomposer update() comme tu l'as dit. Celà en reviendrait donc à :

        1)Récupérer la touche sur laquelle on appuye et calculer les nouvelles positions
        2)Appliquer ces nouvelles positions à bSphere
        3)Si bSphere entre en collision, remettre bSphere aux positions de l'objet, sinon mettre l'objet aux positions de bSphere
        4)Afficher l'objet

        Ai-je bien interprété ton raisonnement ?
        • Partager sur Facebook
        • Partager sur Twitter
          19 décembre 2006 à 0:22:54

          oui c'est çà (si le 3) signifie "remettre bSphere à ses coordonnées précédentes")
          • Partager sur Facebook
          • Partager sur Twitter
            19 décembre 2006 à 12:06:16

            Merci ^^

            Alors voilà ça donne ça :
            public void actualisation(BoundingSphere objet)
                    {
                        if (Keyboard.GetState().IsKeyDown(Keys.Up))
                        {
                            bSphere = new BoundingSphere(new Vector3(positionX + vitesseDeplacement‚ 0.0f‚ positionZ – vitesseDeplacement)‚ rayonSphere);
                            if (!bSphere.Intersects(objet))
                            {
                                positionX += vitesseDeplacement;
                                positionZ –= vitesseDeplacement;
                            }
                            bSphere = new BoundingSphere(new Vector3(positionX‚ 0.0f‚ positionZ)‚ rayonSphere);
                        }
                        if (Keyboard.GetState().IsKeyDown(Keys.Right))
                        {
                            bSphere = new BoundingSphere(new Vector3(positionX + vitesseDeplacement‚ 0.0f‚ positionZ + vitesseDeplacement)‚ rayonSphere);
                            if (!bSphere.Intersects(objet))
                            {
                                positionX += vitesseDeplacement;
                                positionZ += vitesseDeplacement;
                            }
                            bSphere = new BoundingSphere(new Vector3(positionX‚ 0.0f‚ positionZ)‚ rayonSphere);
                        }
                        if (Keyboard.GetState().IsKeyDown(Keys.Left))
                        {
                            bSphere = new BoundingSphere(new Vector3(positionX – vitesseDeplacement‚ 0.0f‚ positionZ – vitesseDeplacement)‚ rayonSphere);
                            if (!bSphere.Intersects(objet))
                            {
                                positionX –= vitesseDeplacement;
                                positionZ –= vitesseDeplacement;
                            }
                            bSphere = new BoundingSphere(new Vector3(positionX‚ 0.0f‚ positionZ)‚ rayonSphere);
                        }
                        if (Keyboard.GetState().IsKeyDown(Keys.Down))
                        {
                            bSphere = new BoundingSphere(new Vector3(positionX – vitesseDeplacement‚ 0.0f‚ positionZ + vitesseDeplacement)‚ rayonSphere);
                            if (!bSphere.Intersects(objet))
                            {
                                positionX –= vitesseDeplacement;
                                positionZ += vitesseDeplacement;
                            }
                            bSphere = new BoundingSphere(new Vector3(positionX‚ 0.0f‚ positionZ)‚ rayonSphere);
                        }
                    }


            Ca fonctionne très bien mais, ça sera pas un peu lourd avec beaucoup d'objets ?

            Désolé pour l'affichage du code ça bug légèrement on dirait.
            • Partager sur Facebook
            • Partager sur Twitter
              19 décembre 2006 à 17:54:37

              Non là tu met justement tout dans le même sac. Fais 3 méthodes que tu appelles à la suite dans Update. La première tu l'appelle par exemple AcquireInput(). Dedans tu fait tes tests de clavier et tu updates les coordonnées de tes objets SANS te soucier des collisions comme si tout était parfait. Ensuite tu créer une méthode SatisfyConstraint() et dedans tu va créer UNE BoundingBox et tester la collision une seule fois (d'ailleurs à chaque if ta deuxième instantiation de BoudingBox ne sert à rien il me semble) et adapter la position en conséquence (moi je ferais une boucle while avec bBox.Intersects(objet) comme condition et à chaque passage tu recules l'objet d'une petite valeur, comme ça dès que tu sort de la boucle tu es sur que tout est bien placer). Et à la fin tu met à jour l'affichage graphique.
              • Partager sur Facebook
              • Partager sur Twitter
                19 décembre 2006 à 19:22:05

                D'accord je vois, j'ai compris cette fois, je vais essayer ^^ et merci pr tes réponses.
                • Partager sur Facebook
                • Partager sur Twitter

                [C# et XNA]

                × 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