IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XNA/Monogame Discussion :

Simuler l'attraction terrestre


Sujet :

XNA/Monogame

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut Simuler l'attraction terrestre
    Bonjour à tous !

    Je suis un petit nouveau dans le monde de XNA.
    Je débute à l'aide du livre "Développement XNA pour la XBox et le PC"


    J'ai crée un fenêtre, ou il y a une petite fusée ( déplaçable à l'aide du clavier ) qui ne peut pas dépasser les bords. Rien de bien compliqué :





    A ce stade, je voudrais mettre ne place de l'attraction terrestre afin que le fusée soit attiré vers le sol.
    Je coince à ce niveau. Je ne vois pas comment faire, ou mettre le code etc...

    J'ai pensé à un astuce qui consiste à faire baisser le position de la fusée de X pixel à chaque appel de la fonction Update, mais bon

    A terme, j'aimerai mettre en place des fonctions exponentielles afin que la démarrage de la fusée et sa perte de vitesse se fasse progressivement, mais j'en suis pas encore la !



    Merci de votre aide

  2. #2
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Points : 683
    Points
    683
    Par défaut
    C'est une histoire de gravitation entre deux corps donc il doit exister une formule mathématique qui reproduit cela à l'aide de la masse de ta fusée et la masse de la terre (enfin un truc dans le genre). Mais il existe peut être des moyens plus simple pour le faire, je n'ai pas encore fait ce genre de chose donc j'avoue ne pas en savoir trop, désolé.

  3. #3
    Membre éclairé
    Homme Profil pro
    NoOb
    Inscrit en
    Mai 2007
    Messages
    554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : NoOb

    Informations forums :
    Inscription : Mai 2007
    Messages : 554
    Points : 852
    Points
    852
    Par défaut
    Bonjour,

    Pourquoi ne pas simplement retrancher à chaque déplacement un coefficient qui représente la gravité, quand tu ne déplace pas, c'est à dire que tu n'ajoute pas de valeur en y, la fusée retombe toute seule ...

    Exemple: - en permanence, déplacement de 3 pixel vers le bas
    - quand tu appuie sur haut, déplacement de 10 pixel vers le haut - 3vers le bas
    c'est à dire 7 vers le haut ...

    Après faudrait implémenter l'accélération ...

  4. #4
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Merci quand même

    EDIT:

    Oui, pour le moment je fais quelque chose comme ça.

    J'ai une vitesse de déplacement de la fusée, et une vitesse de chute.

    Si je n'accélère pas, la fusée tombe jusqu'au sol. Si j'accélère, la vitesse de chute n'est pas prit en compte et le fusée décolle.


    Comme tu le dis, il reste a implémenter les systèmes d'accélération et de décélération...
    La je vois pas du tout comment procéder
    Je suppose qu'il faut utilise une fonction exponentielle ?
    J'ai jamais fait

    Merci à vous deux

  5. #5
    Membre éclairé
    Homme Profil pro
    NoOb
    Inscrit en
    Mai 2007
    Messages
    554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : NoOb

    Informations forums :
    Inscription : Mai 2007
    Messages : 554
    Points : 852
    Points
    852
    Par défaut
    Il faudrait que tu créer 2 variables monter et descendre, qui augmente ou diminue au fur et a mesure, avec une valeur maximale et minimale.

    Lorsque que tu appuie sur haut, la valeur descendre va diminuer et ta valeur monter augmenter, jusqu'à dépassé celle ci, ainsi la fusée va remonter.
    Inversement lors ce que tu n'appuie pas sur monter...

    ton déplacement en y sera alors de monter - descendre.

    Après il faudra régler les mins et max, ainsi que les coefficients d'ajouts de soustraction à ces valeurs.

    Je trouve que je suis pas très clair!

    EDIT: bon ca c'est de la bidouille hein, normalement c'est une formule mathématique

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2002
    Messages : 255
    Points : 445
    Points
    445
    Par défaut
    Salut le_viking,

    Si tu as le Livre de Labat, tu vois qu'il parle (et montre une implémentation) de Farseer. Utilise Farseer pour simuler tout ce que tu veux, il est d'une simplicité enfantine. Il y a une surcharge du constructeur (PhysicSimulator) qui prend un Vector2 pour la gravité en paramêtre. Par la suite tu peux très bien ne pas en tenir compte (de la gravité) pour certains objets avec : Body.IgnoreGravity=true;

    Salutations.

  7. #7
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Salut !

    En effet, je n'avais pas fait attention , merci pour l'info !

  8. #8
    Nouveau membre du Club
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2010
    Messages : 17
    Points : 25
    Points
    25
    Par défaut
    Farseer, pour ce genre de taches, c'est carrément oversized.

    défini ceci dans les membres de ta classe:

    const float attraction = 2.0f;

    float verticalSpeed = 0f;

    Dans la méthode Update: L'appui sur la touche "haut" :

    if( [APPUI sur HAUT ] )
    {
    verticalSpeed -= 1f * GameTime.ElapsedTime.TotalSeconds;
    }

    verticalSpeed += attraction * GameTime.ElapsedTime.TotalSeconds;

    position vaisseau += verticalSpeed;

    Cela devrait faire un effet de gravitation, sans s'emmerder avec tous les détails physiques réels. Toutefois, si tu veux simuler une vrai gravitation, réfère toi à la Loi universelle de gravitation de Newton (http://fr.wikipedia.org/wiki/Loi_uni...la_gravitation) qui te donne:

    -G * (Masse Fusée * Masse Planète) / (distance fusée planète au carré)

    Avec G = 6.674 * 10^-11. Cette valeur te donne la magnitude du vecteur à appliquer à la fusée en direction de la planète.

  9. #9
    Membre averti Avatar de yodaime
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    282
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2006
    Messages : 282
    Points : 340
    Points
    340
    Par défaut
    Citation Envoyé par PERECil Voir le message
    Farseer, pour ce genre de taches, c'est carrément oversized.
    Oui et non.

    Oui si c'est juste pour un effet de gravité.

    Non si par la suite du doit gérer des collisions avec des astéroïdes ( au autre chose ), Farseer sera utile.

  10. #10
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Merci PERECil pour ta contribution. J'utilise déjà cette technique sur mon mini projet. Je ne compte pas en effet reproduire avec exactitude l'attraction terrestre

    Pour ceux qui est de Farseer. Je vais commencer plutôt par tenter de maitriser XNA et je verrais par la suite. Bien qu'il faudra détecter des collision.

    J'essaie déjà de faire pivoter ma fuser, pas facile

  11. #11
    Nouveau membre du Club
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2010
    Messages : 17
    Points : 25
    Points
    25
    Par défaut
    Collision avec des objets sphériques (astéroides), c'est encore une tâche simple: suffit de vérifier que la distance entre l'objet A et B est moins grande que le cercle de collision de A additionné à celui de B .

    Mais bon après c'est vrai que cela se complexifie vite: les boundings box rectangulaires orientées, c'est déjà carrément moins simple (transformations de repères, etc...)

  12. #12
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2002
    Messages : 255
    Points : 445
    Points
    445
    Par défaut
    Salut le_viking,

    Je ne pense pas que ce soit une perte de temps que de passer directement à un moteur physique. Tu devras un jour ou l'autre gérer les collisions, l'inertie, les accélérations,la masse etc... et tout écrire seul en cherchant un peu partout des algos ça te prendra beaucoup de temps. Je n'ai jamais écris aucun gestionnaire de collisions (ou alors au tout tout début) grâce à Farseer (JigLibx actuellement). J'utilise simplement les évènements des Geom (CollisionEventHandler) et les délégués.
    Mon principe est simple: pourquoi se casser le c.. quand d'autres l'ont fait pour vous ? (et pour vous éviter de le faire ! ).
    Si des librairies te permettent de faire exactement ce que tu souhaites, pourquoi chercher plus loin ? Par contre si tu cherches quelque chose de plus pointu, de spécial , alors là oui , faut mettre les mains dans le cambouis.
    PERECil a bien raison mais sur le long terme je ne pense pas avoir tord.
    Pour ta rotation, un exemple:
    Vector2 origin = new Vector2(vaisseau.Width/2, vaisseau.Height/2);
    //Update
    float X = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;
    float Y= GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y;
    angle = (float)Math.Atan2(X, Y);

    Salutations.

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Points : 228
    Points
    228
    Par défaut
    Je pense moi aussi que l'utilisation de Farseer n'est pas une aberration. A terme cela simplifie énormément les choses, quoi qu'on en dise.

    Le code s'en retrouve énormément simplifié, et beaucoup moins sujet à des bugs, la bibliothèque étant très bien faîte

  14. #14
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Merci à tous pour vos réponses !

    Je pense que je me mettrais à farseer, car au final j'aurais besoin de gérer les colisions, les accélérations et l’attraction...

    Cependant, il y a un truc que je ne comprend pas avec ton bout de code Fabiani.
    Quand je l'implémente dans mon code j'ai droit à un

    Erreur 1 'Gravitation.Fuse' ne contient pas une définition pour 'Width' et aucune méthode d'extension 'Width' acceptant un premier argument de type 'Gravitation.Fuse' n'a été trouvée (une directive using ou une référence d'assembly est-elle manquante*?)
    ( je re-précise, je suis débutant en C#, mais pas en programmation )

    Ce que j'ai fait dans la méthode initialize(), c'est une instance d'un joueur qui pilote une fusée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    joueur = new Fuse(new Vector2(0, 0));
    Dans la class Fuse, j'ai deux méthode : update() et Fuse().

    Donc, faut-il que je crée des méthode Height() et width() dans ma class fuse qui me retourne ces valeurs?

  15. #15
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    ME revoilà ! ( désolé pour le double post )


    J'ai réussi à faire pivoter ma fusée à l'aide de tuto sur XNA creators club


    Maintenant ce que j'aimerais c'est que la fusée ce déplace dans dans un certain angle et pas de haut en bas.
    Actuellement je modifie fuse.position.Y pour la faire monter ou descendre.
    Je suppose qu'il faut modifier fuse.position.Y et fuse.position.X en même temps, et en fonction de l'angle de ma rotation.
    J'ai pensé à modifier les valeurs de position X et Y par la valeur de la rotation, mais il faudrait que cette valeur soit un vector2D et pas un float

    Si vous avez une piste, je suis preneur

    Merci à tous !

    EDIT:

    J'ai presque trouvé ce que je veux. Encore sur le XNA creators il y a un tuto pour faire un mini jeux 2D.
    C'est un canon qui peut pivoter et qui peut tirer sur des navettes qui passe.
    En fonction de l'angle du canon, la balle qui est tiré se dirige vers une certaine position.

    Je crois que c'est ce bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
            public void FireCannonBall()
            {
                foreach (GameObject ball in cannonBalls)
                {
                    if (!ball.alive)
                    {
                        ball.alive = true;
                        ball.position = cannon.position - ball.center;
                        ball.velocity = new Vector2(
                            (float)Math.Cos(cannon.rotation),
                            (float)Math.Sin(cannon.rotation)) * 5.0f;
                        return;
                    }
                }
            }

    J'ai essayé de l'appliqué à mon jeux, ce qui donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                    fuse.velocity = new Vector2(
                             (float)Math.Cos(fuse.rotation),
                             (float)Math.Sin(fuse.rotation)) * vitesse; // vitesse = 0.2f
     
     
                    fuse.position = fuse.velocity;
    Or ma fusée ce déplace toujours dans le coin supérieur gauche

    Merci !



    EDIT :

    J'ai réussi !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
                   fuse.velocity = new Vector2((float)Math.Sin(fuse.rotation),
                       -(float)Math.Cos(fuse.rotation));
     
     
     
                    fuse.position += fuse.velocity ;

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 36
    Points : 20
    Points
    20
    Par défaut
    Je débute moi aussi, et comme toi j'avais bloquer au même endroit avec la rotation du canon, enfin, drôle de coïncidence.

    Pour l'attraction, moi pour le moment je ne me casse pas la tête. Dans le update j'ajoute disons 0.05f du float qui me sert de velocity(vitesse). L'effet est graduelle et pour un début, ça me semble tout à fait acceptable pour une attraction terrestre.

    Pour exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Vector2 position = new vector2(400,100);
    float velocity = 0;
     
    Update
    {
    if(Keyboard.GetState().IsKeyDown(Keys.Up))
      {
         velocity = -5;
      }
     
    position.Y += velocity;
    velocity += 0.05f;
    }
    C'est sur que c'est du code de débutant, mais ça donne un certain résultat quand même.

  17. #17
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Salut

    J'ai fait exactement la même chose de mon coté.
    Cependant, je ne suis pas convaincu du résultat et me penche vers le moteur farseer, dont les exemple fourni dans l'archive donne très envie


    En passant, j'ai un problème pour l'implémenter. Je me sers du livre de Labat "Développement XNA pour la Xbox et le PC".
    Est-ce que les directive using change de la version 2.01 à la 3.0 de Farseer ?

    Dans le livre ils disent d'utiliser "FarseerGames.FarseerPhysics;" mais elle ne marche pas.


  18. #18
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2002
    Messages : 255
    Points : 445
    Points
    445
    Par défaut
    Salut le_viking,

    Pour Farseer, ils ont un peu modifié le principe avec la version 3.0.
    Le livre de Labat est un peu obsolète maintenant mais le principe reste le
    même donc tu peux quand même jeter un œil pour comprendre le mécanisme.
    Pour ne pas rentrer dans les détails, on part de l'exemple fourni sur leur site en téléchargeant "Farseer Physics Engine 3.0 HelloWorld XNA".Compile le projet.
    Tu obtiens deux fichiers : DebugViewXNA.dll et Farseer Physics 3.0 XNA.dll.
    Crée un nouveau projet (xna 3.1) et fais référence à ces 2 fichiers (Références>Ajouter une référence...), et rajoute ces lignes dans ton projet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    using FarseerPhysics.Dynamics;
    using FarseerPhysics.Factories;
    using FarseerPhysics.DebugViewXNA;
    La classe World remplace PhysicsSimulator donc ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    World world = new World(new Vector2(0, -20));//paramêtre=gravité
    On le met à jour dans Update comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    world.Step((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f);
    La classe Fixture remplace Body donc ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //global
            Fixture rectangle;
            Fixture circle;     
    //global
     
    //load content
    rectangle = FixtureFactory.CreateRectangle(world, 50, 5, 1, new Vector2(0, 0));
                circle = FixtureFactory.CreateCircle(world, 2, 1, new Vector2(10, 10));//load content
                circle.Body.BodyType = BodyType.Dynamic;
    //load content
    Et la modif la plus importante c'est qu'on a maintenant une caméra à créer comme en 3D, mais au lieu d'utiliser CreatePerspectiveFieldOfView on utilise
    CreateOrthographic. Donc ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DebugViewXNA debugView;//global
    debugView = new DebugViewXNA(world);//dans le constructeur
    DebugViewXNA.LoadContent(graphics.GraphicsDevice, Content);//load content
    et on dessine les formes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //draw
    Matrix proj = Matrix.CreateOrthographic(50 * graphics.GraphicsDevice.Viewport.AspectRatio, 50, 0, 1);
                Matrix view = Matrix.Identity;
                debugView.RenderDebugData(ref proj, ref view);
    //draw
    Pour finir , la méthode LoadContent de la classe DebugViewXNA exige une font du contentManager donc il suffit d'en créer une:
    Content>Ajouter Nouvel Elément... et tu sélectionnes "Sprite Font" que tu nommes "font".
    Voilà, tout ça est loin d'être exhaustif mais pour débuter ça suffit.

    Salutations.

  19. #19
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    Merci beaucoup pour ces explications Fabiani

    Je retournerai sur Farseer un peu plus tard, pour le moment j'essaie de faire du scrolling en fonction de la position de ma fusée.


    Merci

Discussions similaires

  1. Probleme Voyageur de Commerce - Recuit Simulé
    Par dinver dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 21/06/2009, 22h26
  2. Développpement d'une application de simulation .....
    Par dada5455 dans le forum OpenGL
    Réponses: 6
    Dernier message: 14/12/2003, 10h27
  3. simuler l'execution d'un message
    Par gaut dans le forum C
    Réponses: 14
    Dernier message: 24/07/2003, 23h01
  4. Simuler un coup de molette sur un memo...
    Par dynobremo dans le forum Composants VCL
    Réponses: 2
    Dernier message: 28/02/2003, 11h31
  5. Simulation de transmission de paquet entre différent réseaux
    Par MelloW dans le forum Développement
    Réponses: 2
    Dernier message: 12/07/2002, 19h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo