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

Windows Presentation Foundation Discussion :

Collision avec wpf


Sujet :

Windows Presentation Foundation

  1. #21
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ah ok, je vois le problème...
    En fait le Clip est une géométrie relative au contrôle : le centre de ton ellipse, c'est (150,150) par rapport à ton PacMan, pas par rapport au canvas. Il faudrait donc convertir cette géométrie dans le référentiel du Canvas.

    Pour ça il suffit de décaler le Clip (ou plutôt une copie du Clip) par rapport à la position du contrôle sur le Canvas, en appliquant une TranslateTransform :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Geometry g1 = element1.Clip.Clone();
    double offset1X = Canvas.GetLeft(element1);
    double offset1Y = Canvas.GetTop(element1);
    g1.Transform = new TranslateTransform(offset1X, offset1Y);
     
    Geometry g2 = element2.Clip.Clone();
    double offset2X = Canvas.GetLeft(element2);
    double offset2Y = Canvas.GetTop(element2);
    g2.Transform = new TranslateTransform(offset2X, offset2Y);
     
    Geometry intersect = Geometry.Combine(g1, g2, GeometryCombineMode.Intersect, null);
    return !intersect.IsEmpty();

    EDIT: comme ça risque d'être un peu lourd de cloner les géométries à chaque fois, je pense qu'il vaudrait mieux que chacun de tes UserControl définisse une propriété Geometry, initialisée en clonant le Clip. Ca renverrait toujours la même Geometry en faisant simplement varier la transformation :
    Code C# : 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
    17
    18
     
    private Geometry _geometry;
    private TranslateTransform _transform;
    public Geometry Geometry
    {
        get
        {
            if (_geometry == null)
            {
                _geometry = this.Clip.Clone();
                _transform = new TranslateTransform();
                _geometry.Transform = _transform;
            }
            _transform.X = Canvas.GetLeft(this);
            _transform.Y = Canvas.GetTop(this);
            return _geometry;
        }
    }

    Et dans la méthode TestCollision, tu n'as plus qu'à tester sur la propriété Geometry au lieu de refaire le calcul à chaque fois

  2. #22
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    J'ai essayé pour les 2 cas et ça ne marche pas,

    pour le deuxième cas, j'ai mis ça dans ma méthode de collision:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (element1.Geometry == element2.Geometry) { return true; } else { return false; }

  3. #23
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par dfiad77pro Voir le message
    J'ai essayé pour les 2 cas et ça ne marche pas,

    pour le deuxième cas, j'ai mis ça dans ma méthode de collision:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (element1.Geometry == element2.Geometry) { return true; } else { return false; }
    Ben non, elles seront jamais égales les 2 géométries... Il faut toujours tester l'intersection, comme tu faisais avec le clip :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       public bool TestCollision(Pacman_c element1, Mur element2)
            {
                Geometry intersect = Geometry.Combine(element1.Geometry, element2.Geometry, GeometryCombineMode.Intersect, null);
                return !intersect.IsEmpty(); 
     
            }
    Après, je suis pas certain que ça marche, j'ai pas vérifié... mais je suis relativement confiant

  4. #24
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    il a l'air de me détecter des collisions, mais pas au bon endroit (comme si la géométrie était déformée).

  5. #25
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par dfiad77pro Voir le message
    il a l'air de me détecter des collisions, mais pas au bon endroit (comme si la géométrie était déformée).
    Bizarre...
    Il faudrait mettre un breakpoint dans TestCollision et dans la propriété Geometry pour voir ce qui se passe. Vérifie la propriété Bounds des 2 géométries pour voir si ça colle

  6. #26
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Oula lol ça me donne des bounds bizzares, ça va être chaud à débugger

    bon j'essaye de corriger ça

  7. #27
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Bon j'ai passé la nuit dessus sans réussir à corriger ça. Rien a faire, les collisions sont hasardeuses.

    Si quelqu'un veut m'aider directement et qu'il a visual studio 2008 et .net 3.5sp1, qu'il n'hésite pas à me contacter (d'autant plus que le projet se compile se lance et est bien commenté).

    Sinon je referais ça avec des méthodes basiques de calcul de distance.

  8. #28
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Upload le projet quelque part et envoie le lien, je tacherai de jeter un oeil ce soir
    C'était mon idée d'utiliser les Geometry alors je me sens un peu responsable

  9. #29
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Alors... j'ai trouvé plusieurs problèmes :

    - la taille : dans ton UserControl Pacman, tu définis un Clip elliptique de rayon 300 (d'ailleurs il faudrait mettre 150 : c'est le rayon, pas le diamètre). Mais quand tu crées une instance de Pacman, tu changes sa taille : il faudrait donc modifier aussi la taille du Clip (en code-behind ou par un binding). Une fois ce problème corrigé, la méthode TestCollision marche bien

    - le test sur la collision : tu testes comme ça:
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!TestCollision(this, E_collision)) { /* annuler le déplacement */ ... }
    Mais c'est le contraire qu'il faut faire : on annule le déplacement s'il y a une collision, pas s'il n'y en a pas...
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    if (TestCollision(this, E_collision)) { /* annuler le déplacement */ ... }

    - l'annulation du déplacement : tu modifies la valeur de PositionX ou de PositionY, mais pas Canvas.Left et Canvas.Top, donc le Pacman reste affiché là ou il est (et la position sur le Canvas n'est plus cohérente avec PositionX et PositionY). Il faut soit appeler Canvas.SetLeft/SetTop après avoir modifié PositionX/Y, soit transformer PositionX et Y en propriétés qui mettent à jour la position sur le Canvas :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public double PositionX
    {
        get { return Canvas.GetLeft(this); }
        set { Canvas.SetLeft(this, value); }
    }
    (A mon avis cette dernière solution est la meilleure)

  10. #30
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Franchement merci 1000 fois, j'ai pu modifier mon programme et alléger le code !

    Bon pour le reste du travail, je vais essayer de continuer seul, mais j'aurais une dernière question juste pour enrichir mes connaissances:

    Y a t 'il possibilité de faire simplement détecter une collision avec tout les objets de type mur ( pour éviter que je fasse un tableau contenant les noms des murs et une boucle de test sur ce tableau) ?

  11. #31
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par dfiad77pro Voir le message
    Y a t 'il possibilité de faire simplement détecter une collision avec tout les objets de type mur ( pour éviter que je fasse un tableau contenant les noms des murs et une boucle de test sur ce tableau) ?
    Ce que je ferais à ta place, c'est un seul objet de type mur, dont la forme est définie par une géométrie (tu peux composer une géométrie "complexe" avec GeometryGroup)

  12. #32
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    ok, et y a t-il une possibilité de dessiner les géométries à la main? ( avec expression ou autre chose)

  13. #33
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    aucune idée... a priori je dirais que non

  14. #34
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    J'ai un autre petit soucis :

    Chaque Pacman peut avoir ses touches clavier de déplacement propres, mais lorsque j' instanci deux Pacmans différents, seul un Pacman peu bouger à la fois.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                    App.Window.KeyDown += recuperer_touche_deplacement;
     
                       }
    Je voudrais savoir comment permettre de récupérer plusieurs touches simultanément ( j'ai essayer les threads, mais je comprend pas trop comment les utiliser dans mon cas)

  15. #35
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Dans l'évènement KeyDown, au lieu de ne tester que sur e.Key, teste toutes les touches qui t'intéressent avec e.KeyboardDevice.IsKeyDown.

  16. #36
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    L'appui simultané marche avec ta méthode, mais lorsque je fait bouger le pacman n2, la pression de la touche arrête un petit moment le pacman n1.

  17. #37
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par dfiad77pro Voir le message
    L'appui simultané marche avec ta méthode, mais lorsque je fait bouger le pacman n2, la pression de la touche arrête un petit moment le pacman n1.
    Normal, c'est à cause du délai avant répétition de la touche : quand tu appuies sur une touche pendant longtemps, la répétition ne commence pas tout de suite, pour éviter de taper accidentellement plusieurs caractères. Quand tu appuies sur la 2e touche, ça remet à zéro ce délai avant répétition, et donc ça arrête la répétition de la 1ere touche.

    A mon avis, l'évènement KeyDown n'est pas vraiment adapté pour gérer les touches de contrôle du jeu, à cause de ce problème de répétition. Il vaudrait mieux faire un timer dans lequel tu testes l'état des touches toutes les 50 ou 100ms. Ou encore mieux, utiliser DirectInput, qui est fait pour ça...

  18. #38
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Voila, j'ai essayé ça mais ça marche pas (à noter que j' appel les fonctions de lecture d'événement clavier dans l'objet Pacman)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                TimeSpan raf = TimeSpan.FromSeconds((Double)(0.1));
                 DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(recuperer_touche_deplacement); // on charge la fonction de récupération des touches
                dispatcherTimer.Interval = raf;
                dispatcherTimer.Start();
    }
    Pour la fonction appelée par le timer:

    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
    17
    18
     
     
     public void recuperer_touche_deplacement(object sender, EventArgs e)
            {if (e is KeyboardEventArgs)
                {
                    KeyboardEventArgs clav = (KeyboardEventArgs)e;
     
     
                    if (clav.KeyboardDevice.IsKeyDown(Touche_Droite))
                    {
                        this.Deplacement_sens = "droite";
                        this.Deplacer("droite");
                    }
                    if (clav.KeyboardDevice.IsKeyDown(Touche_Gauche))
                    {
                        this.Deplacement_sens = "gauche";
                        this.Deplacer("gauche");
                    }///
    Je pense que je lui envoi rien pour détecter l'événement, mais je ne vois pas trop comment faire avec ça. j'ai regardé les directinput, ça a l'air pas mal, mais un peu lourd à écrire.

  19. #39
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ca n'a pas de sens de faire comme ça... Le paramètre de l'évènement Tick est un EventArgs, ce ne sera jamais un KeyboardEventArgs !

    Il faut récupérer l'état des touches autrement, par exemple avec la méthode statique Keyboard.IsKeyDown

  20. #40
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Oui je m'en suis rendu compte à la compilation

    Ayet ça marche enfin comme il faut.
    Et pis j'ai acheté le livre sur wpf de Thomas Lebrun ça va me permettre de mieux comprendre WPF

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Problème de "collision" avec un "EDIT"
    Par Darkenshin dans le forum Windows
    Réponses: 2
    Dernier message: 31/05/2007, 13h21
  2. Collision avec ODE
    Par chasse dans le forum ODE
    Réponses: 10
    Dernier message: 06/04/2007, 19h54
  3. Réponses: 4
    Dernier message: 21/03/2006, 17h38
  4. Collision avec le sol...
    Par conrad dans le forum Physique
    Réponses: 15
    Dernier message: 09/08/2005, 02h18
  5. Collision avec 3ds ou ms3d
    Par goutbouyo dans le forum Physique
    Réponses: 3
    Dernier message: 29/03/2005, 12h34

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