如何识别Swift代码中的持续用户触摸?连续我的意思是用户将手指放在屏幕上。只要用户触摸屏幕,我想将精灵套件节点移动到用户触摸的方向。
答案 0 :(得分:18)
基本步骤
touchesBegan
/ touchesMoved
)update
)touchesEnded
)这是一个如何做到这一点的例子
Xcode 8
let sprite = SKSpriteNode(color: SKColor.white, size: CGSize(width:32, height:32))
var touched:Bool = false
var location = CGPoint.zero
override func didMove(to view: SKView) {
/* Add a sprite to the scene */
sprite.position = CGPoint(x:0, y:0)
self.addChild(sprite)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touched = true
for touch in touches {
location = touch.location(in:self)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
location = touch.location(in: self)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// Stop node from moving to touch
touched = false
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
if (touched) {
moveNodeToLocation()
}
}
// Move the node to the location of the touch
func moveNodeToLocation() {
// Compute vector components in direction of the touch
var dx = location.x - sprite.position.x
var dy = location.y - sprite.position.y
// How fast to move the node. Adjust this as needed
let speed:CGFloat = 0.25
// Scale vector
dx = dx * speed
dy = dy * speed
sprite.position = CGPoint(x:sprite.position.x+dx, y:sprite.position.y+dy)
}
Xcode 7
let sprite = SKSpriteNode(color: SKColor.whiteColor(), size: CGSizeMake(32, 32))
var touched:Bool = false
var location = CGPointMake(0, 0)
override func didMoveToView(view: SKView) {
self.scaleMode = .ResizeFill
/* Add a sprite to the scene */
sprite.position = CGPointMake(100, 100)
self.addChild(sprite)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Start moving node to touch location */
touched = true
for touch in touches {
location = touch.locationInNode(self)
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Update to new touch location */
for touch in touches {
location = touch.locationInNode(self)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
// Stop node from moving to touch
touched = false
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if (touched) {
moveNodeToLocation()
}
}
// Move the node to the location of the touch
func moveNodeToLocation() {
// How fast to move the node
let speed:CGFloat = 0.25
// Compute vector components in direction of the touch
var dx = location.x - sprite.position.x
var dy = location.y - sprite.position.y
// Scale vector
dx = dx * speed
dy = dy * speed
sprite.position = CGPointMake(sprite.position.x+dx, sprite.position.y+dy)
}
答案 1 :(得分:11)
此过程最困难的事情是跟踪多点触控环境中的单个触控。 &#34;简单&#34;的问题对此的解决方案(即,在touchesBegan
中转动&#34; istouched&#34;并在touchesEnded
中将其关闭)是因为如果用户触摸屏幕上的另一个手指然后将其抬起,则将取消第一次触摸的动作。
要使这种防弹,您需要跟踪其生命周期内的各个触摸。当第一次触摸发生时,您保存该触摸的位置并将对象移向该位置。任何进一步的触摸都应该与第一次触摸相比较,如果它们不是第一次触摸就应该被忽略。这种方法还允许您处理多点触控,其中对象可以朝向当前在屏幕上的任何手指移动,然后如果第一个手指被抬起则移动到下一个手指,依此类推。
值得注意的是UITouch
对象在touchesBegan
,touchesMoved
和touchesEnded
之间保持不变。您可以将UITouch
对象视为在touchesBegan
中创建,在touchesMoved
中更改,并在touchesEnded
中销毁。您可以通过将触摸对象的引用保存到touchesBegan
中创建的字典或数组,然后在touchesMoved
中查看,可以跟踪触摸过程中的触摸阶段。任何现有触摸的新位置,如果用户移动手指,则改变对象的路线(您可以应用公差以防止抖动,例如,如果x / y距离小于某个容差,则不要改变课程)。在touchesEnded
中,您可以检查焦点中的触摸是否是结束的触摸,并取消对象的移动,或将其设置为朝向仍在发生的任何其他触摸移动。这很重要,就像你只检查任何旧的触摸物体结束一样,这也会取消其他触摸,这会产生意想不到的结果。
这篇文章在Obj-C中,但代码很容易移植到Swift并向您展示您需要做什么,只需查看&#34;处理复杂多点触控序列下的内容&#34;:{{3 }}
答案 2 :(得分:0)
下面是在X位置(左右)上拖动节点的代码,添加Y位置并执行相同的操作非常容易。
let item = SKSpriteNode(imageNamed: "xx")
var itemXposition = 50
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
// updates itemXposition variable on every touch
for touch in touches {
let location = touch.location(in: self)
itemXposition = Int(location.x)
}
}
// this function is called for each frame render, updates the position on view
override func update(_ currentTime: TimeInterval) {
spaceShip.position = CGPoint(x: self.itemXposition , y: 50 )
}