我是SpriteKit的新手,我不确定我是否已经尝试使用SKPhysics和SKRegion等内置对象来实现。
简而言之,一旦敌人的SKSpriteNode进入某个范围内,我需要一个事件处理程序来触发SKSpriteNode的自定义子类。
我正在构建一个RTS,到目前为止,我现在面临的最大问题是如何让2个SKSpriteNodes检测它们是否在彼此的近距离范围内。
现在,我的解决方案似乎相当黑客。在我的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,则单位的精灵将执行SKAction以在X维上移动-50。否则,什么都不会发生。
这是单位精灵如何确定它是否可以移动:
func thereIsAnObstacleInTheWay(destination: CGPoint) -> Bool {
let getNodesAtDestination = ReferenceOfGameScene!.nodesAtPoint(destination)
for node in getNodesAtDestination {
if node is SKBlockMovementSpriteNode {
return true
}
}
return false
}
在大多数情况下,它与寻找魔兽争霸II中的单位一样强大。但每当我尝试改进这种方法时,我都会不断遇到:
Exception: EXC_BAD_ACCESS (code=1, address=0xf91002028))
我在实施后立即开始解决此问题:activateEnemiesNearby(pointDestination)
由于单位self
,将激活其他单位并命令他们攻击self
。
总而言之,SKSpriteNode
中SKScene
的单位是否应通过调用敌方单位的MOVE_TO_POINT方法调用具有类似SKSpriteNode
的其他单位的方法通过使用关于敌人单位的参考变量本身?
我尝试使用SKPhysics,效果不错,但由于2个SKSpriteNodes触摸时发生的碰撞物理效应,SKSpriteNodes位置抖动。
我考虑过使用SKRegion,但是我很难弄清楚它们是如何被调用并插入到SKScene中的,而且关于SKRegion的官方苹果文档看起来非常有限: https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKRegion_Ref/
SKRegions最适合"单位视线"?为了让单位能够发现敌人正在接近?
答案 0 :(得分:0)
我倾向于使用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