4 votes

Double curseur dans un jeu opengl fenêtré sous le dock

J'ai créé un jeu en opengl et j'ai un problème avec le double curseur (mon et système) en mode fenêtré. Je cache le curseur système et n'utilise que mon curseur dans le jeu.

Lorsque la fenêtre est sous le dock et que je déplace le curseur sur le dock (le curseur est toujours dans la fenêtre), le curseur du système est affiché. A partir de ce moment, j'ai un double curseur (le mien et celui du système).

J'essaie trois solutions :

  1. Utiliser des événements lorsque le curseur est au-dessus et lorsque le curseur est en dehors du dock, mais je n'ai pas trouvé de tels événements :(
  2. Utiliser des événements lorsque le curseur du système est déplacé ou caché, mais je n'ai pas trouvé de tels événements, aussi :(
  3. Obtenir des informations sur le nombre de curseurs cachés. Lorsque je fais "CGDisplayHideCursor", le nombre de curseurs cachés est décrémenté. Lorsque le curseur se détache du dock, je ne le sais pas parce que je n'ai pas d'événement, mais je pourrais vérifier dans mon timer si le curseur doit être caché et je pourrais le cacher, mais de cette façon, j'aurai plusieurs fois le curseur caché, donc je ne sais pas combien de fois le curseur est caché et je ne le fais pas correctement disparaître :(

Peut-être que ce problème devrait être résolu d'une manière complètement différente.

0voto

the swine Points 4204

Vous pouvez essayer l'une des solutions suivantes :

  • Ne pas afficher le curseur du jeu en mode fenêtré (bien que cela puisse ne pas convenir à votre jeu).
  • Placez la fenêtre de jeu en haut de l'écran pour qu'elle soit au-dessus du dock (je ne suis pas sûr que ce soit possible sur Mac).
  • Ne permettez pas à votre fenêtre de jeu d'afficher quoi que ce soit sous le dock, afin que l'utilisateur n'ait pas besoin de cliquer à cet endroit (ou ne permettez pas à votre fenêtre de jeu d'être positionnée sous le dock en premier lieu).
  • Utiliser une minuterie pour sonder les coordonnées de l'écran du curseur afin de déterminer si le curseur se trouve sur le dock ou non.

Il ne s'agit pas strictement d'un problème de programmation, mais d'un problème de convivialité. Vous devez décider ce que vous voulez que l'utilisateur fasse et le mettre en œuvre. Je pense qu'il est normal de ne pas afficher le curseur du jeu en mode fenêtré (sauf si vous écrivez par exemple un jeu de stratégie où vous avez besoin de plusieurs curseurs différents).

0voto

manylegged Points 133

Au lieu de s'embêter avec CGDisplayHideCursor, avec son mystérieux compte de masquage illisible, la solution consiste à mettre en place un rectangle de curseur couvrant toute votre fenêtre avec un curseur transparent. Cette méthode est vraiment robuste - elle cache de manière fiable le curseur lorsque la souris est à l'intérieur de la fenêtre et l'affiche à tout autre moment.

J'ai fini par comprendre cela en regardant le code source de Simple DirectMedia Layer (SDL) 2 - voici un exemple minimal fonctionnel extrait de ce code.

Remplacez resetCursorRects dans l'implémentation de votre sous-classe NSView :

static NSCursor* invisibleCursor()
{
    static NSCursor *invisibleCursor = NULL;
    if (!invisibleCursor) {
        /* RAW 16x16 transparent GIF */
        static unsigned char cursorBytes[] = {
            0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
            0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
            0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
            0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
        };

        NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
                                                  length:sizeof(cursorBytes)
                                            freeWhenDone:NO];
        NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
        invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
                                                  hotSpot:NSZeroPoint];
    }

    return invisibleCursor;
}

- (void)resetCursorRects
{
    [super resetCursorRects];

    [self addCursorRect:[self bounds] cursor:invisibleCursor()];
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X