我一直在尝试做的是创建一个可以移动玩家的“操纵杆”。这是我到目前为止所知道的:
import UIKit
import SpriteKit
import SceneKit
class GameViewController: UIViewController, SCNSceneRendererDelegate {
var isTracking = false
var firstTrackingLocation = CGPoint.zero
var trackingVelocity = CGPoint.zero
var trackingDistance : CGFloat = 0.0
var previousTime : NSTimeInterval = 0.0
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene(named: "art.scnassets/level.scn")!
let scnView = self.view as! SCNView
scnView.delegate = self
scnView.scene = scene
scnView.showsStatistics = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if isTracking == false {
for touch in touches {
isTracking = true
let location = touch.locationInView(self.view)
firstTrackingLocation = location
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if isTracking {
trackingVelocity = touches.first!.locationInView(self.view)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
isTracking = false
trackingVelocity = CGPoint.zero
}
func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if isTracking == true {
let scnView = self.view as! SCNView
let character = scnView.scene!.rootNode.childNodeWithName("person", recursively: true)
let deltaTime = time - previousTime
let pointsPerSecond: CGFloat = 1.0 * CGFloat(deltaTime)
var xResult:CGFloat = 0.0
var yResult:CGFloat = 0.0
let point = firstTrackingLocation
let endPoint = trackingVelocity
let direction = CGPoint(x: endPoint.x - point.x, y: endPoint.y - point.y)
if direction.x > direction.y {
let movePerSecond = pointsPerSecond/direction.x
xResult = direction.x*movePerSecond
yResult = direction.y*movePerSecond
} else {
let movePerSecond = pointsPerSecond/direction.y
xResult = direction.x*movePerSecond
yResult = direction.y*movePerSecond
}
character!.position = SCNVector3(CGFloat(character!.position.x) + (xResult), CGFloat(character!.position.y), CGFloat(character!.position.z) + (yResult))
let camera = scnView.scene?.rootNode.childNodeWithName("camera", recursively: true)
camera?.position = SCNVector3(CGFloat(camera!.position.x) + (xResult), CGFloat(camera!.position.y), CGFloat(camera!.position.z) + (yResult))
}
previousTime = time
}
override func shouldAutorotate() -> Bool {
return true
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Landscape
}
}现在,这个方法起作用了,除非你把手指拖到手机的另一边,人物移动的速度比你几乎不动手指的速度快10倍。所以我想要的是一个操纵杆,如果你拖动一点或者移动到屏幕的另一边,它会以相同的速度移动角色。我也希望如果你在屏幕的另一边改变方向,角色就会朝另一边移动。因此,我的猜测是,需要保存一个lastPoint,然后当调用touchesMoved时,我们以某种方式计算从lastPoint到currentPoint的方向,然后在渲染器中移动角色。我知道这段代码中的大部分可能都是垃圾,但还是要提前谢谢你。
发布于 2016-08-30 00:29:27
你的操纵杆应该是一个从0到1的值,你需要确定你的操纵杆的半径,然后计算距离(触摸到控制中心的点)和控制的角度。
现在我们需要确保我们永远不会超过半径,所以如果我们的距离> maxRadius,我们只需要将它设置为最大半径,然后我们将这个值除以我们的maxRadius得到距离比。
然后我们只需取角度的cos和sin,并将其乘以距离比,就可以得到x和y的比值。(应介于0和1之间)
最后,取此x和y值,并将其乘以您的对象应该移动的速度。
let maxRadius = 100 //Your allowable radius
let xDist = (p2.x - p1.x)
let yDist = (p2.y - p1.y)
let distance = (sqrt((xDist * xDist) + (yDist * yDist))
let angle = atan2(yDist , xDist )
let controlDistanceRatio = (distance > maxRadius) ? 1 : distance / maxRadius
let controllerX = cos(angle) * controlDistanceRatio
let controllerY = sin(angle) * controlDistanceRatio发布于 2016-08-30 00:06:24
这似乎是一个使用自定义UIGestureRecognizer.的好例子参见Apple API Reference。
在这种情况下,您将创建一个连续的手势。生成的CGVector将从屏幕上操纵杆的中心(原点)计算得出。如果未选中操纵杆节点,识别器将失败;如果未选中(取消选中),识别器将终止。当手势的状态为moved时,生成的CGVector将被更新。
现在,要弄清楚的棘手部分是以这样一种方式移动节点图像,使用户有操纵杆的感觉。为此,您可能需要更新节点纹理并对节点位置进行细微调整,以提供四处移动节点的外观。
看看这是否对你有帮助:Single Rotation Gesture Recognizer
如果这给你指明了正确的方向,请告诉我。
发布于 2016-08-30 00:35:41
你所说的问题是角色以不同的速率移动,这取决于用户拖动手指离起始点有多远。代码中的关键点似乎是这样的
let direction = CGPoint(x: endPoint.x - point.x, y: endPoint.y - point.y)endPoint和point之间的差异是可变的,所以你在你的方向上得到了一个可变的幅度。为了简化,您可以只放入一个常量值,如
let direction = CGPoint(x: 10, y: 10)当用户按下操纵杆时,这会使角色以恒定的速度移动,但角色总是朝同一方向移动。
所以你必须在变量的方向值中加上括号。首先想到的是使用min和max
let direction = CGPoint(x: endPoint.x - point.x, y: endPoint.y - point.y)
direction.x = min(direction.x, 10)
direction.x = max(direction.x, -10)
direction.y = min(direction.y, 10)
direction.y = max(direction.y, -10)这似乎会使方向值的大小保持在-10到10之间。这并不能使速度完全恒定,而且它允许沿对角线的移动比平行于x或y轴的移动更快,但也许它更接近于您想要的。
https://stackoverflow.com/questions/39209661
复制相似问题