我是 SpriteKit 的新手,我不确定我正在尝试完成的事情是否无法通过内置对象(例如 SKPhysics 和 SKRegion)实现。
简而言之,我需要一个事件处理程序来在敌人 SKSpriteNode 进入一定范围内时触发 SKSpriteNode 的自定义子类。
我正在构建一个 RTS,到目前为止,我几天来一直面临的最大问题是如何让 2 个 SKSpriteNode 检测它们是否彼此靠近。
现在,我的解决方案看起来很老套。在我的 SKScene 中的 SKSpriteNode 将 50
或 -50
点移动到场景中的任何位置 X
或 Y
之前,它将首先检查是否允许该移动。
这是我的抽象类“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/