停靠栏下的窗口化opengl游戏中的双光标

Posted

技术标签:

【中文标题】停靠栏下的窗口化opengl游戏中的双光标【英文标题】:Double cursor in windowed opengl game under dock 【发布时间】:2011-07-06 08:45:16 【问题描述】:

我在 opengl 中创建游戏,但在窗口模式下出现双光标(我的和系统)问题。 我隐藏系统光标并在游戏中只使用我的光标。

当窗口在停靠栏下并且我将光标移到停靠栏上(光标仍在窗口内)时,系统光标会显示出来。从这一刻起,我有了双光标(我的和系统)。

我尝试了三种解决方案:

    在光标结束和光标不在停靠栏时使用事件,但我没有找到这样的事件:( 在系统光标取消隐藏或隐藏时使用事件,但我也没有找到此类事件:( 获取有关隐藏光标计数的信息。当我使“CGDisplayHideCursor”隐藏光标计数减少时。当光标在停靠栏上取消隐藏时,我不知道它,因为我没有任何事件,但我可以检查我的计时器是否应该隐藏光标,以便我可以隐藏它,但这样我将有很多次隐藏光标,所以我不知道光标隐藏计数,我没有正确取消隐藏:(

也许这应该以完全不同的方式解决。

【问题讨论】:

【参考方案1】:

您可以尝试以下任何一种方法:

不要在窗口模式下显示游戏光标(尽管这可能不适合您的游戏) 将游戏窗口设置在最顶部,使其位于 Dock 上方(不确定在 Mac 上是否可行) 不允许您的游戏窗口在 Dock 下呈现任何内容,因此用户无需单击那里(或者首先不允许您的游戏窗口位于 Dock 下) 使用计时器轮询光标屏幕坐标以确定光标是否在停靠栏上

这不是严格意义上的编程问题,而是可用性问题。您应该决定您希望用户做什么并实施它。我相信不以窗口模式显示游戏光标是可以的(除非您正在编写例如需要许多不同光标的策略游戏)。

【讨论】:

【参考方案2】:

解决方案是设置一个光标矩形,用透明光标覆盖整个窗口,而不是使用 CGDisplayHideCursor,因为它具有神秘的不可读隐藏计数。这真的很强大 - 当鼠标在窗口内时它可靠地隐藏光标并在所有其他时间显示它。

我最终通过查看 Simple DirectMedia Layer (SDL) 2 源代码发现了这一点 - 这是从那里提取的一个最小工作示例。

在你的 NSView 子类实现中覆盖 resetCursorRects:

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()];

【讨论】:

以上是关于停靠栏下的窗口化opengl游戏中的双光标的主要内容,如果未能解决你的问题,请参考以下文章

如何在可可中的应用程序停靠图标上绘制mac旋转等待光标

如何停靠,设置查询管理器

Android中的EditText中,输入信息时,怎么能让光标停靠在输入的信息的右侧而不是左侧呢?

消费者生产者模型中的双缓冲 OpenGL 对象

如何在 OpenGL 窗口模式下扩展鼠标空间

将 open gl 与应用程序代码同步