ios - SKScene,检测到 2 个 SKSpriteNode 何时在彼此的 x 范围内?

标签 ios swift sprite-kit skspritenode skscene

我是 SpriteKit 的新手,我不确定我正在尝试完成的事情是否无法通过内置对象(例如 SKPhysics 和 SKRegion)实现。

简而言之,我需要一个事件处理程序来在敌人 SKSpriteNode 进入一定范围内时触发 SKSpriteNode 的自定义子类。

我正在构建一个 RTS,到目前为止,我几天来一直面临的最大问题是如何让 2 个 SKSpriteNode 检测它们是否彼此靠近。

现在,我的解决方案看起来很老套。在我的 SKScene 中的 SKSpriteNode 将 50-50 点移动到场景中的任何位置 XY 之前,它将首先检查是否允许该移动。

这是我的抽象类“PathFindingUnit”的示例:

override func OrderUnitToMoveOneStepLEFT() -> Bool {
    if isDead == true { return false }
    sprite.playFaceLeftAnimation()
    angleFacing = UnitFaceAngle.Left

    updateMovementBlockerPosition()
    let destination = round(sprite.position.x) - UnitDefaultProperty.Movement.Range
    var pointDestination = sprite.position
    pointDestination.x = destination


    if thereIsAnObstacleInTheWay(pointDestination) == false {
        activateEnemiesNearby(pointDestination)
        sprite.playWalkLEFTAnimation()

            self.sprite.runAction(SKAction.moveToX(self.roundToFifties(destination), duration: 0.2))


        angleFacing = UnitFaceAngle.Left
        unitDidMove(pointDestination)

        return true
    } else {
        return false
    }
}

如果此方法返回 true,则该单位的 Sprite 将执行 SKAction 以在 X 维度上移动 -50。否则,什么也不会发生。

这就是单位 Sprite 如何确定它是否可以移动:

func thereIsAnObstacleInTheWay(destination: CGPoint) -> Bool {
    let getNodesAtDestination = ReferenceOfGameScene!.nodesAtPoint(destination)
    for node in getNodesAtDestination {
        if node is SKBlockMovementSpriteNode {
            return true
        }
    }
    return false
}

在大多数情况下,它与魔兽争霸 II 中单位的寻路功能一样强大。但是每当我尝试改进这种方法时,我总是遇到:

异常:EXC_BAD_ACCESS(代码=1,地址=0xf91002028))

我一实现就开始经常遇到这个问题:activateEnemiesNearby(pointDestination)

由于单位self,会激活其他单位并命令他们攻击self

所以总而言之,SKScene 中带有 SKSpriteNode 的 Unit 是否应该通过调用敌人来调用其他带有类似 SKSpriteNode 的 Unit 的方法单位内部的 MOVE_TO_POINT 方法通过使用自身内部敌方单位的引用变量?

我尝试使用 SKPhysics,效果还不错,但是由于 2 个 SKSpriteNode 接触时发生的碰撞物理效应,SKSpriteNode 的位置会抖动。

我考虑过使用 SKRegion,但我在弄清楚如何调用它们并将它们插入 SKScene 时遇到了很多麻烦,而且关于 SKRegion 的官方苹果文档似乎非常有限: https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKRegion_Ref/

SKRegions 是否最适合“Unit sight”?为了让单位检测到敌人正在接近?

最佳答案

我倾向于使用 SKPhysicsBody 来检测物体是否与标记有另一个 SKPhysicBody 的特定区域发生碰撞,例如使用特定 创建的区域CGPath 所以你可以这样做:

SKPhysicsBody.init(edgeLoopFromPath: zonePath!) // zonePath is a CGPath

但是,如果您不想使用它,还有这个小函数可以帮助您进行计算:

func getDistance(p1:CGPoint,p2:CGPoint)->CGFloat {
    let xDist = (p2.x - p1.x)
    let yDist = (p2.y - p1.y)
    return CGFloat(sqrt((xDist * xDist) + (yDist * yDist)))
}

关于最后一种方式,您会发现这些方法也很有用:

/* Return true if `point' is contained in `rect', false otherwise. */

@available(iOS 2.0, *)
public func CGRectContainsPoint(rect: CGRect, _ point: CGPoint) -> Bool

/* Return true if `rect2' is contained in `rect1', false otherwise. `rect2'
   is contained in `rect1' if the union of `rect1' and `rect2' is equal to
   `rect1'. */

@available(iOS 2.0, *)
public func CGRectContainsRect(rect1: CGRect, _ rect2: CGRect) -> Bool

/* Return true if `rect1' intersects `rect2', false otherwise. `rect1'
   intersects `rect2' if the intersection of `rect1' and `rect2' is not the
   null rect. */

@available(iOS 2.0, *)
public func CGRectIntersectsRect(rect1: CGRect, _ rect2: CGRect) -> Bool

关于ios - SKScene,检测到 2 个 SKSpriteNode 何时在彼此的 x 范围内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38493104/

相关文章:

iphone - 当UITabBarController加载而不是在ViewController上时添加角标(Badge)

ios - 准则 2.1 - 性能 - 应用完整性

objective-c - 我应该什么时候调用 removeObserver :forKeyPath from within a closing ViewController class that is observing a persistant Model class?

swift - 观察结构数组的变化

ios - bodyWithBodies SKPhysics body

swift - 如何在多次点击时删除节点

ios - swift 2.0 : Cannot convert NSDateComponents to NSCalendarUnit

ios - 我如何在核心数据中保存图像然后检索它?使用 swift

ios - 真的没有办法设置 SKLabelNode 的样式吗?

ios - 连接ViewController和场景来展示广告(SpriteKit)