2

我有GKEntity一个GKAgent2D组件。它的行为GKGoaltoWander:toStayOnPath:maxPredictionTime:。实体在场景中不断游荡;但是,我希望它停止徘徊一段时间。例如,如果实体是一只四处游荡的羊,我希望它定期停下来吃东西,并在延迟之后再次开始游荡。

更新:

实体中:

addComponent(MoveIdleComponent(maxSpeed: 60, maxAcceleration: 6, radius: Float(node.texture!.size().width * 0.3), entityManager: entityManager))

移动空闲组件

class MoveIdleComponent : GKAgent2D, GKAgentDelegate {

let entityManager: EntityManager

init(maxSpeed: Float, maxAcceleration: Float, radius: Float, entityManager: EntityManager) {
    self.entityManager = entityManager
    super.init()
    delegate = self
    self.maxSpeed = maxSpeed
    self.maxAcceleration = maxAcceleration
    self.radius = radius
    print(self.mass)
    self.mass = 0.01
}


func agentWillUpdate(agent: GKAgent) {
    guard let spriteComponent = entity?.componentForClass(SpriteComponent.self) else {
        return
    }

    self.position = float2(spriteComponent.node.position)
}

func agentDidUpdate(agent: GKAgent) {
    guard let spriteComponent = entity?.componentForClass(SpriteComponent.self) else {
        return
    }

    spriteComponent.node.position = CGPoint(position)
}



override func updateWithDeltaTime(seconds: NSTimeInterval) {

    super.updateWithDeltaTime(seconds)

    behavior = WanderBehavoir(targetSpeed: maxSpeed)
}
}

流浪行为:

class WanderBehavoir: GKBehavior {

  init(targetSpeed: Float) {
    super.init()

    if targetSpeed > 0 {
        setWeight(0.5, forGoal: GKGoal(toWander: targetSpeed))
    }
}
}

我怎样才能做到这一点?

提前致谢

4

2 回答 2

1

似乎没有GKGoal(toEatFood:withFrequency:)API,因此您必须退后一步考虑如何设置代理的目标以实现您的目标。

如果您希望代理在一段时间内停止徘徊或停止遵循某条路径,那么您想要的是那些不再是它的目标。(此外,当您取消其目标时,您希望它停止,而不是以任何方向和速度继续,因此您需要引入toReachTargetSpeed:一个速度为零的目标。)

有两种一般方法可以做到这一点:

  • 让您的行为包括徘徊、跟随路径和速度(零)目标,并设置权重以使徘徊和跟随路径超过速度。当您想在徘徊+路径行为和停止行为之间切换时,使用setWeight(_:forGoal:)使速度目标超过其他目标。

  • 有一种行为包括徘徊和跟随路径目标,另一种行为具有速度(零)目标,并behavior在您想要在它们之间切换时设置代理的属性。

于 2016-01-28T20:15:01.587 回答
0

好的,我找到了@rickster 建议的解决方案。如果可以帮助某人,我会发布它。我添加了暂停值。如果 pause 为真,则 speed 的权重变为 1,其中GKGoal(toReachTargetSpeed: 0)

WanderBehavoir类中:

class WanderBehavoir: GKBehavior {

init(targetSpeed: Float, entityManager: EntityManager, pause: Bool) {

    super.init()

    var weightWander : Float = 1.0
    var weightSpeed  : Float = 0.0

    if pause {
        weightWander = 0
        weightSpeed = 1
    }

    //   |  |
    // --A--B--
    //   |  |

    if targetSpeed > 0 {
        let lato = Float(500.0)
        let pts = [vector_float2(-lato,0),vector_float2(+lato,0)]

        let path = GKPath(points: UnsafeMutablePointer(pts), count: pts.count, radius: 980, cyclical: true)

        let obstacleNode = entityManager.nodesWithUnitType(Tree)
        let obstacles = SKNode.obstaclesFromNodePhysicsBodies(obstacleNode)

            setWeight(0.5,          forGoal: GKGoal(toAvoidObstacles: obstacles, maxPredictionTime: 0.5))
            setWeight(0.2,          forGoal: GKGoal(toStayOnPath: path, maxPredictionTime: 0.5))
            setWeight(weightWander, forGoal: GKGoal(toWander: targetSpeed))
            setWeight(weightSpeed,  forGoal: GKGoal(toReachTargetSpeed: 0))
        }
    }
}

class MoveIdleComponent : GKAgent2D, GKAgentDelegate增量时间后随机切换真假

private var lastUpdateInterval: NSTimeInterval = 0
var setPause = true
var randomTimeStop = NSTimeInterval(Int(5...8))
var randomTimeMove = NSTimeInterval(Int(10...20))

override func updateWithDeltaTime(seconds: NSTimeInterval) { 
    super.updateWithDeltaTime(seconds)        

    lastUpdateInterval += seconds

    if setPause {
        if lastUpdateInterval > randomTimeStop {
            setPause = !setPause
            lastUpdateInterval = 0
            randomTimeMove = NSTimeInterval(Int(10...20))
        }
    }
    else {
        if lastUpdateInterval > randomTimeMove {
            setPause = !setPause
            lastUpdateInterval = 0
            randomTimeStop = NSTimeInterval(Int(5...8))
        }

    }
    print("randomTimeMove \(randomTimeMove)")

    behavior = WanderBehavoir(targetSpeed: maxSpeed, entityManager: entityManager, pause: setPause)
}
于 2016-01-29T18:56:08.223 回答