我如何更好地定义一个区域来检测拖放节点?
Posted
技术标签:
【中文标题】我如何更好地定义一个区域来检测拖放节点?【英文标题】:How do i better define an area to detect a dragged and dropped node? 【发布时间】:2019-05-11 14:09:53 【问题描述】:我正在尝试扩展我从Drag and drop example 研究的拖放示例,方法是添加一个可以检测到已删除节点的位置。
从我检测丢弃节点的尝试中,我了解到丢弃一个节点并期望它精确地击中一个预定义的位置是很困难的。
如何定义一个更大的位置或类似矩形来检测丢弃的节点?
//: A SpriteKit based Playground
import PlaygroundSupport
import SpriteKit
class GameScene: SKScene
private var currentNode: SKNode?
override func didMove(to view: SKView)
let node = SKSpriteNode(
color: .red,
size: CGSize(width: 50, height: 50)
)
node.name = "draggable"
self.addChild(node)
let blueNode = SKSpriteNode(
color: .blue,
size: CGSize(width: 50, height: 50)
)
blueNode.name = "draggable"
self.addChild(blueNode)
let greenNode = SKSpriteNode(
color: .green,
size: CGSize(width: 50, height: 50)
)
greenNode.name = "droppable"
greenNode.position = CGPoint(x: 100, y: 100)
self.addChild(greenNode)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
if let touch = touches.first
let location = touch.location(in: self)
let touchedNodes = self.nodes(at: location)
for node in touchedNodes.reversed()
if node.name == "draggable"
self.currentNode = node
@objc static override var supportsSecureCoding: Bool
// SKNode conforms to NSSecureCoding, so any subclass going
// through the decoding process must support secure coding
get
return true
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
if let touch = touches.first, let node = self.currentNode
let touchLocation = touch.location(in: self)
node.position = touchLocation
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
print(self.currentNode!.position);
if self.currentNode!.position == CGPoint(x:100,y:100)
let yellowNode = SKSpriteNode(
color: .yellow,
size: CGSize(width: 50, height: 50)
)
yellowNode.name = "droppable"
yellowNode.position = CGPoint(x: 200, y: 200)
self.addChild(yellowNode)
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)
self.currentNode = nil
override func update(_ currentTime: TimeInterval)
// Called before each frame is rendered
// Load the SKScene from 'GameScene.sks'
let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
if let scene = GameScene(fileNamed: "GameScene")
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
sceneView.presentScene(scene)
PlaygroundSupport.PlaygroundPage.current.liveView = sceneView
【问题讨论】:
【参考方案1】:我假设您是在 touchesEnded(...)
函数中寻求建议。
你是对的:像在
中那样检查精确位置if self.currentNode!.position == CGPoint(x:100,y:100)
不会让你走得太远。手动点击屏幕上的特定点非常困难。
例如,您可以使用CGRect
指定目标区域,然后检查触摸的位置是否在矩形内。
let targetRect = CGRect(x: 0, y: 0, width: 200, height: 200)
guard let node = self.currentNode else return // Just to avoid forced unwrapping
if targetRect.contains(node.position)
// Do stuff
【讨论】:
感谢您,我注意到 CGRect 和 SKSpriteNode 之间似乎存在我不理解的差异。 IE 当我使用: let targetRect = CGRect(x: 100, y: 100, width: 200, height: 200) 与 let greenNode = SKSpriteNode( color: .green, size: CGSize(width: 200, height: 200) ) greenNode.name = "droppable" greenNode.position = CGPoint(x: 100, y: 100) 似乎表明 CGRect 定位与 SKSpriteNode 不同。你能帮我理解一下吗? 出现这种情况是因为 CGrect 和 SKSpriteNode 使用不同的坐标系。 CGRect 的 (x,y) 对指定其原点,即左上角。 SKSpriteNode 的 position 属性指定了它的中心。以上是关于我如何更好地定义一个区域来检测拖放节点?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用jQuery Draggable和Droppable实现拖拽功能
TVirtualStringTree - 如何在单击所选行的任何区域时启用拖动?