Comment identifier les clics de souris par rapport à la souris vers le bas dans les jeux?

8

Quelle est la façon la plus courante de gérer les clics de souris dans les jeux?

Étant donné que tout ce que vous avez pour détecter les entrées de la souris est de savoir si un bouton est en haut ou en bas.

Pour l'instant, je compte uniquement sur le clic de la souris, mais cette approche simple me limite considérablement dans ce que je veux réaliser. Par exemple, j'ai du code qui ne doit être exécuté qu'une fois sur un clic de souris, mais en utilisant la souris vers le bas comme un clic de souris, le code peut s'exécuter plus d'une fois selon la durée pendant laquelle le bouton est maintenu enfoncé. Je dois donc le faire en un clic!

Mais quelle est la meilleure façon de gérer un clic? Est-ce un clic lorsque la souris passe de la souris de haut en bas ou de bas en haut ou est-ce un clic si le bouton était enfoncé pendant moins de x images / millisecondes et si oui, est-il considéré comme la souris vers le bas et un clic si son bas pour x images / millisecondes ou un clic puis la souris vers le bas?

Je peux voir que chacune des approches peut avoir son utilité mais quelle est la plus courante dans les jeux? Et peut-être que je demanderai plus précisément quel est le plus courant dans les jeux RTS?

Tristan
la source
1
Vous êtes sur la bonne voie. Ajoutez quelque chose à ce sujet: la souris vers le bas et la souris vers le haut doivent être proches l'une de l'autre (ou à l'intérieur des limites de l'objet cliqué) et vous l'avez. Cliquer sur un bouton, puis faire glisser, puis relâcher le bouton n'est pas un clic de souris. Mais cliquer sur le bouton et lâcher n'importe où dans le bouton est un clic de souris.
Tim Holt

Réponses:

12

Vous êtes sur la bonne voie pour savoir quand la souris passe de bas en haut et écrire un gestionnaire pour cela. Pour de nombreux jeux, il suffit de traiter un événement mouseUp comme un clic.

Selon votre jeu, vous voudrez probablement gérer les deux événements - par exemple, dans un RTS, vous voudrez probablement intégrer la sélection par glisser-déplacer ainsi que la sélection en un seul clic. La différence consiste à déterminer combien de temps la souris était à l'état Down avant sa sortie.

(Oui, vous avez essentiellement répondu à votre propre question)

Facture
la source
2
Comme d'autres commentateurs l'ont souligné, vous voudrez probablement également vérifier que la même cible a été pointée sur mouseDown et mouseUp lorsque vous travaillez avec des clics simples.
Bill
Je ne suis pas si sûr. Par exemple, les boutons Windows ne se soucient pas de l'endroit où la souris était enfoncée, tant que le bouton reçoit l'événement souris vers le haut. Peut-être que d'autres systèmes d'exploitation se soucient plus.
John McDonald
@John McD Ce n'est pas tant une exigence technique qu'une exigence de "déterminer ce que votre utilisateur voulait réellement cliquer".
Bill
1
@John McD. ce n'est pas vrai. Appuyez sur le bouton de la souris quelque part sur votre bureau, déplacez le curseur sur le menu Démarrer et relâchez - le menu Démarrer apparaît-il? Ce n'est pas pour moi.
Kylotan
@Kylotan, vous auriez raison, bien que le "bouton" du menu Démarrer se comporte différemment de tous les autres boutons standard. Il semble que les boutons standard dans les fenêtres nécessitent réellement les événements souris vers le bas et souris vers le haut, bien que votre souris puisse se déplacer en dehors des limites des boutons entre les deux. Minimize, Maximize et Close fonctionnent tous comme ceci, ainsi que les boutons normaux dans les applications. Mais veuillez noter qu'aucune action ne se produit (sauf avec le bouton Démarrer) tant que le bouton de la souris n'est pas relâché, des gens comme moi le remarqueront. Annyway ... Bill a raison, il se résume aux exigences.
John McDonald
4

Il n'y a pas de «meilleur» - vous avez besoin de tous.

Si je tire avec un pistolet, je ne veux pas attendre que la souris soit relâchée pour déclencher l'effet de tir de l'arme. Et si vous faites glisser une boîte autour d'un tas d'unités, vous démarrez l'action de glisser-déplacer vers le bas.

D'un autre côté, si je clique sur un élément de l'interface graphique, je veux attendre le clic complet, car c'est à cela que je suis habitué.

Donc, vous devriez probablement implémenter la souris vers le bas, la souris vers le haut, la souris glisser (la souris vers le haut dans un endroit significativement différent de la souris vers le bas) et le clic de souris (la souris vers le haut au même endroit que la souris vers le bas), et les raccorder à des parties de votre jeu comme vous voyez bon.

Kylotan
la source
1

La façon dont la plupart des systèmes de fenêtrage le gèrent, ainsi que les jeux sur lesquels j'ai travaillé (et j'ai dû m'implémenter partiellement) est d'avoir un peu sur chaque bouton qui détecte si la souris est entrée dans l'état bas de la souris sur le bouton donné. Il est uniquement défini le cadre que la souris descend et effacé uniquement lorsque le bouton de la souris est relâché. Si et seulement si la souris est relâchée sur le bouton et que le bit est activé, déclenchez l'événement cliqué sur le bouton.

(Vous souhaitez probablement également un indicateur défini sur true lorsque le bit est défini et que la souris survole votre bouton, de sorte que vous pouvez modifier le bouton pour utiliser une texture pressée au lieu de la texture normale.)

C'est le schéma de base derrière la plupart des boutons. Allez-y et trouvez une invite de dialogue. Appuyez sur le bouton Annuler mais ne lâchez pas. Le bouton devient enfoncé lorsque la souris est au-dessus de lui et revient à la normale si votre souris arrête de survoler, mais il redeviendra enfoncé si vous vous déplacez dessus. Il n'exécute son action que si vous lâchez prise et que vous en avez terminé. N'utilisez pas un décompte de millisecondes, c'est principalement juste pour détecter les doubles clics dans votre seuil.

(et si vous voulez vraiment devenir fantaisiste, ayez des événements que vous pouvez connecter à chacune de ces transitions. Par exemple, MouseOver à l'entrée et à la sortie, MouseDown entrée / sortie, MouseUp entrée / sortie, MouseClicked entrée / sortie, etc. )

Alex Ames
la source
1

Les boutons de la souris et les touches du clavier peuvent avoir un certain nombre d'événements différents, ce qui est disponible dépend de votre choix de langue / bibliothèque, le plus courant:

Touche enfoncée, se déclenche lorsqu'un bouton est enfoncé.
Key up, se déclenche lorsqu'un bouton est relâché.
Touche retardée enfoncée, se déclenche lorsqu'un bouton est enfoncé, puis se déclenche à plusieurs reprises à un intervalle dépendant du système jusqu'à ce que la touche soit relâchée.

En plus de cela, il peut également y avoir un appel pour dire si une touche est actuellement enfoncée.

Il est important que vous sachiez exactement quel outil vous utilisez, le plus souvent vous aurez besoin des deux premiers, s'ils ne sont pas disponibles, construisez-les à partir de ce qui est disponible.

La méthode standard pour enregistrer qu'un bouton à l'écran est enfoncé à l'aide de la souris consiste à affirmer que le même bouton était pointé vers le bas et vers le haut. Pour de nombreux éléments de jeu, cela peut cependant être trop lent, donc pour de nombreuses actions, il peut être prudent de les faire se produire lors de l'événement down.

aaaaaaaaaaaa
la source
0

XOr peut être votre ami dans cette situation.

bool oldIsButtonUp = true;

void pollMouse(bool isButtonUp) {
    if ((oldIsButtonUp ^ isButtonUp) && isButtonUp) {
        sendMouseClickEvent();
    }
    oldIsButtonUp = isButtonUp;
}

Cela appellera sendMouseClickEvent () chaque fois que l'état du bouton de la souris passe de faux à vrai.

Asgeir
la source
4
Ou, pour ne pas faire un programmeur créer un truthtable dans son (elle?) La tête: if (!oldIsButtonUp && isButtonUp) {.
deceleratedcaviar
-1

Une version XNA de ce code serait quelque chose comme (simplifié juste pour détecter l'événement souris vers le bas, pour détecter les doubles clics, vous aurez besoin de quelque chose de plus sophistiqué);

MouseState previousMouseState; 
protected override void Initialize() 
{ 
    // TODO: Add your initialization logic here 
    //store the current state of the mouse 
    previousMouseState = Mouse.GetState(); 
} 


protected override void Update(GameTime gameTime) 
{ 
    // .. other update code 


    //is there a mouse click? 
    //A mouse click begins if the button goes from a released state 
    //in the previous frame  to a pressed state  
    //in the current frame 
    if (previousMouseState.LeftButton == ButtonState.Released  
        && Mouse.GetState().LeftButton == ButtonState.Pressed) 
    { 
        //do your mouse click response... 

    } 

    //save the current mouse state for the next frame 
    // the current  
    previousMouseState = Mouse.GetState(); 

    base.Update(gameTime); 
} 
Ken
la source
En dehors de cela, il y a un code pour MouseUp, pas MouseClick - À quelle fréquence la mise à jour est-elle effectuée? Que se passerait-il si un clic est plus court que votre temps de jeu?
Kromster
dépend du jeu mais dans XNA la mise à jour se produit environ 60fps par défaut. Il serait très difficile d'appuyer sur ET de relâcher un bouton de la souris dans ce laps de temps.
Ken
En fait, c'est du code pour détecter un événement de souris enfoncée.
Ken
Je ne vois pas de réponse réelle à la question réelle dans cet exemple de code XNA abstrait
Kromster
Merci pour les corrections cependant, j'ai fait un petit test et Click a effectivement pris 16-100 ms, ce qui est légèrement plus que la durée de la mise à jour. Pourtant, je n'encouragerais pas le traitement des entrées dans une boucle de mise à jour car le pas de temps pourrait être inférieur à 60 images par seconde, en particulier sans mettre les entrées en file d'attente.
Kromster