ios - OpenGL 游戏引擎能否创建它自己的 UIResponder 子类,类似于 Sprite Kit 为 SKNode 所做的?

标签 ios iphone opengl-es uikit uiresponder

看起来像 UIResponder与 UIView 交织在一起。然而,Sprite Kit 有 SKNode从 UIResponder 继承的类,因此它可以处理触摸事件。

如果您自己创建基于节点的游戏引擎:您能否创建自己的 UIResponder 子类,以便 OpenGL 渲染的对象可以响应类似于 UIView 层次结构的触摸事件?

触摸事件是如何进入 UIResponder 子类的?

最佳答案

UIResponder 没有什么特别之处- 确实可以按照您的建议进行操作。 (虽然可能不像你想象的那么容易。)

实际上,UIResponder是一个抽象父类(super class)。它(AFAIK)本身不实现事件调度;相反,它为处理事件的类定义了一个接口(interface)。如何处理事件取决于子类的实现。 UIApplication , UIWindow , 和 UIView实现响应方法以将触摸事件传递到触摸下的 View ——大概是 UIView调用自己的 hitTest:withEvent: 方法来找到触摸下的 subview 并将事件转发给它。 Sprite Kit 将响应者模式扩展到其节点树模型中,因此 SKView可能实现 UIResponder通过调用其场景的 convertPointFromView: 方法和 nodeAtPoint: 在将事件传递给该节点之前找到触摸下的节点的方法。

如果您实现自己的UIView (或 GLKView 或任何类型的 View )子类,您可以扩展响应者模式以包含您的自定义对象。如果您正在使用 OpenGL ES 绘制 3D 场景,并且有用于表示该场景元素的 Objective-C 类,请随意让这些类继承自 UIResponder。 .

不过,这样做不会神奇地将触摸事件转发给这些对象——就像 UIView确实 HitTest 以将事件转发到 subview 和 SKView确实 HitTest 以将事件转发到节点,您的 View 将需要进行 HitTest 以确定您的哪些自定义对象应该接收触摸事件(然后在该对象上调用适当的响应器方法)。

如何在您的 OpenGL ES View 中进行 HitTest 取决于您...您必须找到一种适合您应用需求的方法。 HitTest (又名选择或挑选)是 3D 编程中的大问题领域之一,因此有很多关于它的文章——进行一些搜索,您会发现很多建议。以下是两种最常见方法的快速概述:

  • 使用特殊的片段着色器(或重新配置的 GLKBaseEffect )将场景重新渲染到屏幕外帧缓冲区,输出对象 ID 而不是像素颜色,然后使用 glReadPixels找到触摸下的像素。 (OpenGL ES 3.0 中的多个渲染目标可能有助于提高性能。)使用 glReadPixels 从 GPU 内存读取速度很慢,所以只读取触摸下的点(或者如果你想允许一些误差范围,则读取它周围的小区域)以保持性能。
  • 如果您知道场景元素在其 3D 坐标空间中的位置,您可以使用 GLKMathUnproject 将触摸位置(2D 屏幕空间中的一个点)转换为场景 3D 世界空间中的一条线的函数,然后查看该线与场景几何体(或场景几何体的边界框)相交的位置,以确定哪个对象被感动了。 (这种方法称为光线转换。)

  • 如果您将响应者模式扩展到您自己的自定义对象体系结构中,您将需要确保您的类将事件正确地转发到响应者链上。阅读 Event Handling Guide for iOS详情。

    关于ios - OpenGL 游戏引擎能否创建它自己的 UIResponder 子类,类似于 Sprite Kit 为 SKNode 所做的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20264957/

    相关文章:

    iphone - OpenGL ES - 如何绘制填充多边形?

    iphone - Unrar4iOS 错误,File::tell() 抛出到 asm 代码,我该怎么办?

    iphone - 一个应用程序需要 iphone4 才能运行,我是否需要在 plist 文件中设置一些键来排除 iphone3 和其他?

    iphone - 如何从一个 View 复制一个字符串并在下一个 View 中显示它?(iphone)

    android - Android glTexSubImage2D 是否有效?

    安卓 OpenGl : When to start calling API functions?

    ios - 如何在 scenekit 的 SCNNodeRendererDelegate 中使用 openGL 进行绘制

    ios - Swift 选择器和闭包讨论

    ios - 获取所有喜欢的页面按一般喜欢排序

    ios - 检查 iOS 设备首次解锁以确定使用 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 存储的项目是否可用