更改 SKNode.obstaclesFromNodeBounds 中使用的坐标系?
Change the coordinate system used in SKNode.obstaclesFromNodeBounds?
我正在我的游戏中设置寻路。如果我把所有的障碍都放在自己身上,那么效果很好。
但是如果我将我的障碍物放在一个名为 "main" 的容器 (SKSpriteNode) 中,那么它根本不起作用——我的玩家走向 "end" 完全忽略了障碍物。
我已经想了一段时间了,但看起来障碍物仍然在我场景的坐标中,"self"
所以我的问题是如何更改与 SKNode.obstaclesFromNodeBounds 一起使用的坐标系?我想让它相对于"main".
的坐标系
我的代码如下:
import SpriteKit
import GameplayKit
class GameScene: SKScene {
var player:SKSpriteNode!
override func didMoveToView(view: SKView) {
let main = SKSpriteNode(color: UIColor.grayColor(), size: CGSize(width: 736, height: 414))
main.position = CGPoint(x: 736/2, y: 414/2)
self.addChild(main)
player = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: 50, height: 50))
player.position = CGPoint(x: (main.frame.size.width-player.frame.size.width)/2, y: 0)
main.addChild(player)
let end = SKSpriteNode(color: UIColor.orangeColor(), size: CGSize(width: 50, height: 50))
end.position = CGPoint(x: -(main.frame.size.width-player.frame.size.width)/2, y: 0)
main.addChild(end)
let obstacle = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 100))
main.addChild(obstacle)
let obstacleNodes = [obstacle]
let obstacles = SKNode.obstaclesFromNodeBounds(obstacleNodes)
let graph = GKObstacleGraph(obstacles: obstacles, bufferRadius: 30)
for var i = 0; i < graph.obstacles.count; i++ {
let obs = graph.obstacles[i]
var string = "Count: \(obs.vertexCount)\n"
for var k = 0; k < obs.vertexCount; k++ {
let vertex = obs.vertexAtIndex(k)
string += "Vertex \(k): \(vertex)\n"
}
print(string)
}
let startX = player.position.x
let startY = player.position.y
let endX = end.position.x
let endY = end.position.y
let startNode = GKGraphNode2D(point: float2(Float(startX), Float(startY)))
let endNode = GKGraphNode2D(point: float2(Float(endX), Float(endY)))
print(startNode)
graph.connectNodeUsingObstacles(startNode)
graph.connectNodeUsingObstacles(endNode)
let path:[GKGraphNode] = graph.findPathFromNode(startNode, toNode: endNode)
let cgPath = CGPathCreateMutable()
print(path.count)
CGPathMoveToPoint(cgPath, nil, CGFloat(startNode.position.x), CGFloat(startNode.position.y))
for node:GKGraphNode in path {
if let point2d = node as? GKGraphNode2D {
let point = CGPoint(x: CGFloat(point2d.position.x), y: CGFloat(point2d.position.y))
CGPathAddLineToPoint(cgPath, nil, point.x, point.y)
}
}
let follow = SKAction.followPath(cgPath, asOffset: false, orientToPath: true, speed: 50)
player.runAction(follow)
player.paused = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
player.paused = false
}
override func update(currentTime: CFTimeInterval) {
}
}
障碍物的输出是:
Vertex 0: float2(343.0, 157.0)
Vertex 1: float2(393.0, 157.0)
Vertex 2: float2(393.0, 257.0)
Vertex 3: float2(343.0, 257.0)
但应该是
-25, 50
25, 50
25, -50
-25, -50
感谢任何意见!
我找不到任何方法来做到这一点,但我通过手动添加 GKPolygonObstacles 解决了这个问题,例如:
func getPolygonObstacleForSpriteNode(node: SKSpriteNode) -> GKPolygonObstacle {
let pts = [vector_float2(Float(node.x-node.widthHalf), Float(node.y-node.heightHalf)), vector_float2(Float(node.x+node.widthHalf), Float(node.y-node.heightHalf)), vector_float2(Float(node.x+node.widthHalf), Float(node.y+node.heightHalf)), vector_float2(Float(node.x-node.widthHalf), Float(node.y+node.height))]
let polygonObstacle = GKPolygonObstacle(points: UnsafeMutablePointer(pts), count: pts.count)
return polygonObstacle
}
注意:此功能不适用于直接在自身中的节点(因为它们具有不同的坐标系),但仅适用于另一个节点,例如像我这样的容器。
我正在我的游戏中设置寻路。如果我把所有的障碍都放在自己身上,那么效果很好。
但是如果我将我的障碍物放在一个名为 "main" 的容器 (SKSpriteNode) 中,那么它根本不起作用——我的玩家走向 "end" 完全忽略了障碍物。
我已经想了一段时间了,但看起来障碍物仍然在我场景的坐标中,"self"
所以我的问题是如何更改与 SKNode.obstaclesFromNodeBounds 一起使用的坐标系?我想让它相对于"main".
的坐标系我的代码如下:
import SpriteKit
import GameplayKit
class GameScene: SKScene {
var player:SKSpriteNode!
override func didMoveToView(view: SKView) {
let main = SKSpriteNode(color: UIColor.grayColor(), size: CGSize(width: 736, height: 414))
main.position = CGPoint(x: 736/2, y: 414/2)
self.addChild(main)
player = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: 50, height: 50))
player.position = CGPoint(x: (main.frame.size.width-player.frame.size.width)/2, y: 0)
main.addChild(player)
let end = SKSpriteNode(color: UIColor.orangeColor(), size: CGSize(width: 50, height: 50))
end.position = CGPoint(x: -(main.frame.size.width-player.frame.size.width)/2, y: 0)
main.addChild(end)
let obstacle = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 100))
main.addChild(obstacle)
let obstacleNodes = [obstacle]
let obstacles = SKNode.obstaclesFromNodeBounds(obstacleNodes)
let graph = GKObstacleGraph(obstacles: obstacles, bufferRadius: 30)
for var i = 0; i < graph.obstacles.count; i++ {
let obs = graph.obstacles[i]
var string = "Count: \(obs.vertexCount)\n"
for var k = 0; k < obs.vertexCount; k++ {
let vertex = obs.vertexAtIndex(k)
string += "Vertex \(k): \(vertex)\n"
}
print(string)
}
let startX = player.position.x
let startY = player.position.y
let endX = end.position.x
let endY = end.position.y
let startNode = GKGraphNode2D(point: float2(Float(startX), Float(startY)))
let endNode = GKGraphNode2D(point: float2(Float(endX), Float(endY)))
print(startNode)
graph.connectNodeUsingObstacles(startNode)
graph.connectNodeUsingObstacles(endNode)
let path:[GKGraphNode] = graph.findPathFromNode(startNode, toNode: endNode)
let cgPath = CGPathCreateMutable()
print(path.count)
CGPathMoveToPoint(cgPath, nil, CGFloat(startNode.position.x), CGFloat(startNode.position.y))
for node:GKGraphNode in path {
if let point2d = node as? GKGraphNode2D {
let point = CGPoint(x: CGFloat(point2d.position.x), y: CGFloat(point2d.position.y))
CGPathAddLineToPoint(cgPath, nil, point.x, point.y)
}
}
let follow = SKAction.followPath(cgPath, asOffset: false, orientToPath: true, speed: 50)
player.runAction(follow)
player.paused = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
player.paused = false
}
override func update(currentTime: CFTimeInterval) {
}
}
障碍物的输出是:
Vertex 0: float2(343.0, 157.0)
Vertex 1: float2(393.0, 157.0)
Vertex 2: float2(393.0, 257.0)
Vertex 3: float2(343.0, 257.0)
但应该是
-25, 50
25, 50
25, -50
-25, -50
感谢任何意见!
我找不到任何方法来做到这一点,但我通过手动添加 GKPolygonObstacles 解决了这个问题,例如:
func getPolygonObstacleForSpriteNode(node: SKSpriteNode) -> GKPolygonObstacle {
let pts = [vector_float2(Float(node.x-node.widthHalf), Float(node.y-node.heightHalf)), vector_float2(Float(node.x+node.widthHalf), Float(node.y-node.heightHalf)), vector_float2(Float(node.x+node.widthHalf), Float(node.y+node.heightHalf)), vector_float2(Float(node.x-node.widthHalf), Float(node.y+node.height))]
let polygonObstacle = GKPolygonObstacle(points: UnsafeMutablePointer(pts), count: pts.count)
return polygonObstacle
}
注意:此功能不适用于直接在自身中的节点(因为它们具有不同的坐标系),但仅适用于另一个节点,例如像我这样的容器。