将 acceptMouseMovedEvents 用于带有故事板的 SpriteKit 鼠标操作和 Swift
Using acceptsMouseMovedEvents for SpriteKit mouse actions with Storyboards and Swift
我在 Xcode 中使用故事板引用自定义 NSView
创建了一个 SpriteKit 场景。但是,我无法使用 SpriteKit 实现任何 mouseMoved
事件,因为我不知道如何引用程序的 NSWindow
来将其 acceptsMouseMovedEvents
属性 设置为 "true"。
如何在我的 AppDelegate.swift
文件中创建对我的 NSWindow
的 @IBOutlet
引用,以便我可以更改此 属性?
您可以配置一个 NSTrackingArea
对象来跟踪鼠标的移动以及光标何时进入或退出视图。要创建 NSTrackingArea
对象,您需要指定要跟踪鼠标事件的视图区域、将接收鼠标事件消息的所有者以及跟踪发生的时间(例如,在键 window).以下是如何将跟踪区域添加到视图的示例。添加到您的 SKScene
子类,例如 GameScene.swift.
Swift 3 和 4
override func didMove(to view: SKView) {
// Create a tracking area object with self as the owner (i.e., the recipient of mouse-tracking messages
let trackingArea = NSTrackingArea(rect: view.frame, options: [.activeInKeyWindow, .mouseMoved], owner: self, userInfo: nil)
// Add the tracking area to the view
view.addTrackingArea(trackingArea)
}
// This method will be called when the mouse moves in the view
override func mouseMoved(with theEvent: NSEvent) {
let location = theEvent.location(in: self)
print(location)
}
Swift 2
override func didMoveToView(view: SKView) {
// Create a tracking area object with self as the owner (i.e., the recipient of mouse-tracking messages
let trackingArea = NSTrackingArea(rect: view.frame, options: NSTrackingAreaOptions.ActiveInKeyWindow | NSTrackingAreaOptions.MouseMoved, owner: self, userInfo: nil)
// Add the tracking area to the view
view.addTrackingArea(trackingArea)
}
// This method will be called when the mouse moves in the view
override func mouseMoved(theEvent: NSEvent) {
let location = theEvent.locationInNode(self)
println(location)
}
0x141E 的回答更新:
override func didChangeSize(_ oldSize: CGSize) {
guard let newRect = view?.bounds else {return}
let options = NSTrackingArea.Options(rawValue: NSTrackingArea.Options.activeInKeyWindow.rawValue | NSTrackingArea.Options.mouseMoved.rawValue)
let userInfo = ["SKMouseInput": 1]
let trackingArea = NSTrackingArea(rect: newRect, options: options, owner: self, userInfo: userInfo)
if let previousTrackingAreas = view?.trackingAreas {
for area in previousTrackingAreas {
if let theInfo = area.userInfo {
if let _ = theInfo["SKMouseInput"] {
view?.removeTrackingArea(area)
}
}
}
}
view?.addTrackingArea(trackingArea)
}
此 SKScene 方法覆盖将在初始化后不久调用,将允许不受 window 大小更改的影响,并将清理旧的跟踪区域。请注意,它仍然需要覆盖 mouseMoved。
我在 Xcode 中使用故事板引用自定义 NSView
创建了一个 SpriteKit 场景。但是,我无法使用 SpriteKit 实现任何 mouseMoved
事件,因为我不知道如何引用程序的 NSWindow
来将其 acceptsMouseMovedEvents
属性 设置为 "true"。
如何在我的 AppDelegate.swift
文件中创建对我的 NSWindow
的 @IBOutlet
引用,以便我可以更改此 属性?
您可以配置一个 NSTrackingArea
对象来跟踪鼠标的移动以及光标何时进入或退出视图。要创建 NSTrackingArea
对象,您需要指定要跟踪鼠标事件的视图区域、将接收鼠标事件消息的所有者以及跟踪发生的时间(例如,在键 window).以下是如何将跟踪区域添加到视图的示例。添加到您的 SKScene
子类,例如 GameScene.swift.
Swift 3 和 4
override func didMove(to view: SKView) {
// Create a tracking area object with self as the owner (i.e., the recipient of mouse-tracking messages
let trackingArea = NSTrackingArea(rect: view.frame, options: [.activeInKeyWindow, .mouseMoved], owner: self, userInfo: nil)
// Add the tracking area to the view
view.addTrackingArea(trackingArea)
}
// This method will be called when the mouse moves in the view
override func mouseMoved(with theEvent: NSEvent) {
let location = theEvent.location(in: self)
print(location)
}
Swift 2
override func didMoveToView(view: SKView) {
// Create a tracking area object with self as the owner (i.e., the recipient of mouse-tracking messages
let trackingArea = NSTrackingArea(rect: view.frame, options: NSTrackingAreaOptions.ActiveInKeyWindow | NSTrackingAreaOptions.MouseMoved, owner: self, userInfo: nil)
// Add the tracking area to the view
view.addTrackingArea(trackingArea)
}
// This method will be called when the mouse moves in the view
override func mouseMoved(theEvent: NSEvent) {
let location = theEvent.locationInNode(self)
println(location)
}
0x141E 的回答更新:
override func didChangeSize(_ oldSize: CGSize) {
guard let newRect = view?.bounds else {return}
let options = NSTrackingArea.Options(rawValue: NSTrackingArea.Options.activeInKeyWindow.rawValue | NSTrackingArea.Options.mouseMoved.rawValue)
let userInfo = ["SKMouseInput": 1]
let trackingArea = NSTrackingArea(rect: newRect, options: options, owner: self, userInfo: userInfo)
if let previousTrackingAreas = view?.trackingAreas {
for area in previousTrackingAreas {
if let theInfo = area.userInfo {
if let _ = theInfo["SKMouseInput"] {
view?.removeTrackingArea(area)
}
}
}
}
view?.addTrackingArea(trackingArea)
}
此 SKScene 方法覆盖将在初始化后不久调用,将允许不受 window 大小更改的影响,并将清理旧的跟踪区域。请注意,它仍然需要覆盖 mouseMoved。