更改SKNode.obstaclesFromNodeBounds中使用的坐标系?

时间:2023-01-23 00:12:38

I'm setting up pathfinding in my game. If I place all my obstacles in self, then it works great.

我正在我的游戏中设置寻路。如果我把所有障碍都放在自己身上,那么它就会很好。

If however I put my obstacles in a container (SKSpriteNode) called "main", then it doesn't work at all -- my player walks to "end" completely ignoring the obstacles.

然而,如果我将障碍物放在一个名为“main”的容器(SKSpriteNode)中,那么它根本不起作用 - 我的玩家走到“尽头”完全无视障碍物。

I've been trying to figure it out for a while now, but it looks like the obstacles are still in the coordinates of my scene, of "self"

我一直试图弄清楚它一段时间,但看起来障碍仍然在我的场景坐标中,“自我”

So my question is how can I change the coordinate system that's used with SKNode.obstaclesFromNodeBounds? I want it to be relative to the coordinate system of "main".

所以我的问题是如何更改与SKNode.obstaclesFromNodeBounds一起使用的坐标系?我希望它相对于“main”的坐标系。

My code is as follows:

我的代码如下:

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) {
}
}

The output from the obstacles is:

障碍物的输出是:

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)

But it should be

但它应该是

-25, 50
25, 50
25, -50
-25, -50

Appreciate any input!

感谢任何输入!

1 个解决方案

#1


0  

I wasn't able to find any way to do this but I did work around it by manually adding the GKPolygonObstacles such as this:

我无法找到任何方法来做到这一点,但我通过手动添加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
}

Note: this function doesn't work for nodes directly in self (as they have a different coordinate system) but only in another node such as a container like I have.

注意:此函数不适用于直接在自身中的节点(因为它们具有不同的坐标系),但仅在另一个节点(如我所拥有的容器)中。

#1


0  

I wasn't able to find any way to do this but I did work around it by manually adding the GKPolygonObstacles such as this:

我无法找到任何方法来做到这一点,但我通过手动添加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
}

Note: this function doesn't work for nodes directly in self (as they have a different coordinate system) but only in another node such as a container like I have.

注意:此函数不适用于直接在自身中的节点(因为它们具有不同的坐标系),但仅在另一个节点(如我所拥有的容器)中。