I'm trying to create a game, where the objects need to chase food. Right now the objects speeds up, when the food is within the given radius. But I need the speed to always be the same.
Any suggestions how to fix this? I have tried to add an SKAction under the chase function, where I set the position.x and position.y, but I can't make it work correct.
Fish class:
class Fish:SKSpriteNode{
private let kMovingAroundKey = "movingAround"
private let kFishSpeed:CGFloat = 4.5
private var swimmingSpeed:CGFloat = 100.0
private let sensorRadius:CGFloat = 100.0
private weak var food:SKSpriteNode! = nil //the food node that this fish currently chase
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
    super.init(texture: texture, color: color, size: size)
    physicsBody = SKPhysicsBody(rectangleOf: size)
    physicsBody?.affectedByGravity = false
    physicsBody?.categoryBitMask = Collider.fish
    physicsBody?.contactTestBitMask = Collider.food
    physicsBody?.collisionBitMask = 0x0 //No collisions with fish, only contact detection
    name = "fish"
    let sensor = SKShapeNode(circleOfRadius: 100)
    sensor.fillColor = .red
    sensor.zPosition = -1
    sensor.alpha = 0.1
    addChild(sensor)
}
func getDistanceFromFood()->CGFloat? {
    if let food = self.food {
        return self.position.distance(point: food.position)
    }
    return nil
}
func lock(food:SKSpriteNode){
    //We are chasing a food node at the moment
    if let currentDistanceFromFood = self.getDistanceFromFood() {
        if (currentDistanceFromFood > self.position.distance(point: food.position)){
            //chase the closer food node
             self.food = food
            self.stopMovingAround()
        }//else, continue chasing the last locked food node
    //We are not chasing the food node at the moment
    }else{
         //go and chase then
         if food.position.distance(point: self.position) <= self.sensorRadius {
            self.food = food
            self.stopMovingAround()
        }
    }
}
//Helper method. Not used currently. You can use this method to prevent chasing another (say closer) food while already chasing one
func isChasing(food:SKSpriteNode)->Bool{
    if self.food != nil {
        if self.food == food {
            return true
        }
    }
    return false
}
func stopMovingAround(){
    if self.action(forKey: kMovingAroundKey) != nil{
       removeAction(forKey: kMovingAroundKey)
    }
}
//MARK: Chasing the food
//This method is called many times in a second
func chase(within rect:CGRect){
    guard let food = self.food else {
        if action(forKey: kMovingAroundKey) == nil {
            self.moveAround(within: rect)
        }
        return
    }
    //Check if food is in the water
    if rect.contains(food.frame.origin) {
        //Take a detailed look in my Stackoverflow answer of how chasing works : https://stackoverflow.com/a/36235426
        let dx = food.position.x - self.position.x
        let dy = food.position.y - self.position.y
        let angle = atan2(dy, dx)
        let vx = cos(angle) * kFishSpeed
        let vy = sin(angle) * kFishSpeed
        position.x += vx
        position.y += vy
    }
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
func moveAround(within rect:CGRect){
    if scene != nil {
        //Go randomly around the screen within view bounds
        let point = rect.randomPoint()
        //Formula: time = distance / speed
        let duration = TimeInterval(point.distance(point: position) / self.swimmingSpeed)
        let move = SKAction.move(to: point, duration: duration)
        let block = SKAction.run {
            [unowned self] in
            self.moveAround(within: rect)
        }
        let loop = SKAction.sequence([move,block])
        run(loop, withKey: kMovingAroundKey)
    }
}
}
Gamescene where you can see the update function.
 override func update(_ currentTime: TimeInterval) {
    self.enumerateChildNodes(withName: "fish") {
        [unowned self] node, stop in
        if let fish = node as? Fish {
            self.enumerateChildNodes(withName: "food") {
                node, stop in
                fish.lock(food: node as! SKSpriteNode)
            }
            fish.chase(within: self.water.frame)
        }
    }
}
 
    