Gestion du clavier [Résolu]

Messages postés
3
Date d'inscription
lundi 24 mai 2010
Dernière intervention
5 juillet 2010
- 4 juil. 2010 à 16:23 - Dernière réponse :
Messages postés
3
Date d'inscription
lundi 24 mai 2010
Dernière intervention
5 juillet 2010
- 5 juil. 2010 à 17:49
Bonjour.

Actuellement, j'essaye de développer un petit jeux du genre rpg. J'arrive à déplacer mon personnage (dans un tableau à deux dimension affiché par une pictureBox) mais je ne suis pas vraiment satisfait du résultat. J'aimerais déplacer mon personnage grâce aux flèches directionnelles, pour cela j'utilise l'événement KeyDown. Mais le problème, c'est que si je maintient une flèche appuyé, mon personnage se déplace correctement une fois et puis se déplacer de plusieurs cases d'un coup.

J'aimerais que son mouvement soit constant et qu'en maintenant une touche enfoncé il continue à se déplacer et qu'il s'arrête dès que la touche est relâché. Le meilleur résultat que j'ai obtenu, c'est ceci :

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
            switch (e.KeyCode)
            {
                case Keys.Up:
                    player.moveUp();
                    break;
                case Keys.Left:
                    player.moveLeft();
                    break;
                case Keys.Down:
                    player.moveDown();
                    break;
                case Keys.Right:
                    player.moveRight();
                    break;
                default:
                    break;
            }

            my_UCMap.pb_main.Invalidate(); // C'est la pictureBox qui affiche la carte.
            
            System.Threading.Thread.Sleep(300);
            this.Enabled = false;
            this.Enabled = true;
        }


Mais je doute fortement que c'est la meilleur façon de faire. De plus les autres composant clignote sans arrêt (bonjour l'épilepsie). En fait d'après ce que j'ai compris de mes recherches, il faudrait que j'arrive à vider la file d'événement du formulaire à la fin de chaque déplacement, mais je n'ai aucune idée de comment faire cela.

Merci d'avance pour vos réponses.
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
Messages postés
1863
Date d'inscription
lundi 28 novembre 2005
Dernière intervention
14 février 2015
- 5 juil. 2010 à 10:15
3
Merci
Salut

Tout d'abord, System.Threading.Thread.Sleep(...), je te conseille de ne JAMAIS l'utiliser sur le thread principal. En effet, cette instruction bloque complètement le thread (donc en l'occurrence, l'affichage et l'interaction utilisateur).

Je te conseille de te pencher du côté des Timers (System.Windows.Forms.Timer).

En gros, au départ, tu associes une méthode à l'événement Tick.
monTimer.Tick += new EventHandler(maMethode);

avec bien sûr maMethode avec ce prototype :
void maMethode(object sender, EventArgs e);

L'important, c'est la valeur que tu donnes à Interval.
monTimer.Interval = 300;

Toujours à l'initialisation, tu associes ta méthode Form1_KeyDown à l'événement KeyDown.
this.KeyDown += new KeyEventHandler(Form1_KeyDown);


Tu fais la même chose dans la méthode maMethode
this.KeyDown += new KeyEventHandler(Form1_KeyDown);

Puis, tu arrêtes le timer :
monTimer.Stop();


Dans ta méthode Form1_KeyDown, tu vires les 3 dernières lignes. Puis tu enlèves la méthode Form1_KeyDown de l'événement KeyDown :
this.KeyDown -= new KeyEventHandler(Form1_KeyDown);

et tu démarres le timer :
monTimer.Start();



Si je résume ce que ton programme fait : au départ, il est normal : quand tu appuies sur une touche, ça appelle Form1_KeyDown. Puis, tu dis qu'il ne doit plus appeler cette méthode quand tu appuies sur une touche, mais tu démarres un Timer qui appellera une méthode 300ms après. Et cette méthode reprépare l'événement KeyDown, donc ta méthode Form1_KeyDown sera rappelée 300ms plus tard si tu appuies encore sur ta touche.

Je ne garantis absolument pas que ce soit la méthode la plus propre, mais elle me semble assez simple, et devrait résoudre ton problème.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -

Merci krimog 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de krimog
Messages postés
3
Date d'inscription
lundi 24 mai 2010
Dernière intervention
5 juillet 2010
- 5 juil. 2010 à 12:03
0
Merci
Merci beaucoup ca marche très bien, j'ai juste un petit problème.
A chaque fois que je laisse une touche appuyé pour me déplacer de plusieurs cases, lorsque je relâche la touche il y a un petit son genre erreur Windows qui est joué.

Je n'arrive pas à savoir d'où provient ce son car en essayant de déboguer je ne peux me déplacer que d'une case à la fois et cela ne joue pas de son.

Si quelqu'un à une bonne idée, je suis preneur.

Merci d'avance.

Ps: est-ce que je met déjà "réponse acceptée" ou cela bloque le post ?
Commenter la réponse de cs_Tomvan
Messages postés
1863
Date d'inscription
lundi 28 novembre 2005
Dernière intervention
14 février 2015
- 5 juil. 2010 à 12:20
0
Merci
Désolé, mais je ne vois pas d'où peut venir ce son. De plus, je ne peux pas tester mon code en ce moment, donc je ne peux pas voir si j'ai aussi ce problème. J'essaierai de me pencher dessus ce soir si j'ai un peu de temps (je ne garantis cependant rien).

En ce qui concerne "Réponse acceptée", non, ça ne bloque absolument pas le post. Tu peux même accepter plusieurs réponses.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Commenter la réponse de krimog
Messages postés
3
Date d'inscription
lundi 24 mai 2010
Dernière intervention
5 juillet 2010
- 5 juil. 2010 à 17:49
0
Merci
J'ai finalement trouvé une solution. Si j'ai bien compris, tous les événements n'était pas bien gérer.
Si ca intéresse quelqu'un, voici ma solution :

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = true;
            if (ActiveKeyboard == true)
            {
                e.SuppressKeyPress = true;
                switch (e.KeyCode)
                {
                    case Keys.Up:
                        player.moveUp();
                        break;
                    case Keys.Left:
                        player.moveLeft();
                        break;
                    case Keys.Down:
                        player.moveDown();
                        break;
                    case Keys.Right:
                        player.moveRight();
                        break;
                    default:
                        break;
                }

                ActiveKeyboard = false;
                timerPlayer.Start();
            }
        }


avec :

bool ActiveKeyboard;


et pour la méthode lancé par le timer :

        private void pausePlayer(object sender, EventArgs e)
        {
            ActiveKeyboard = true;
            timerPlayer.Stop();
        }


Ps: encore merci krimog !
Commenter la réponse de cs_Tomvan

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.