我是新来的SpriteKit,我不确定我要完成的是不是已经不可能与内置对象,如SKPhysics和SKRegion。
简而言之,一旦敌人SKSpriteNode进入某个范围,我需要一个事件处理程序来触发SKSpriteNode的自定义子类。
我正在构建一个RTS,到目前为止,我已经面临了几天的最大问题是如何让两个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,则该单元的sprite将执行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
}
在很大程度上,它和魔兽争霸2中的探路一样强大。但每当我试图改进这种方法时,我总是会遇到:
Exception: EXC_BAD_ACCESS (code=1, address=0xf91002028))
我一实施就开始经常遇到这个问题:
activateEnemiesNearby(pointDestination)
因为这个单位会激活其他单位并命令他们攻击。
因此,总而言之,
self
中有self
的单位是否应该通过使用关于其内部敌方单位的参考变量调用其内部敌方单位的移动点方法来调用具有类似SKSpriteNode
的其他单位的方法?我试着使用SKPhysics,它工作得有点好,但是SKSpriteNodes的位置抖动是由于当两个SKSpriteNodes接触时发生的碰撞物理效应。
我考虑过使用SKRegion,但是我很难弄清楚它们是如何被调用并插入到SKScene中的,而且关于SKRegion的苹果官方文档似乎非常有限:
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKRegion_Ref/
SKRegions是“单位视野”的最佳选择吗?为了让部队发现敌人正在逼近?
最佳答案
我倾向于使用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个SKSpriteNodes何时彼此之间处于x范围内?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38493104/