having a node follow at a constant speed

Viewed 93

I'm trying to make a small mini game where you drag a ball around the screen and every 10 seconds a ball gets added in that follows you. so far the you can drag a ball around the screen and a ball follows you, but when another ball gets added in the balls group together. I think this is because the ball is following me depending on how fast I'm going. so is there a certain way in which I can have the balls follow me at a certain speed constantly, like 10 pixels a second or something, and that should prevent the balls from grouping together.

I am currently working on the score so it should soon go up every second you survive. and you die if you touch one of the balls.

below is the code and a short gif of my current code

!(https://gyazo.com/1d6a56527bfd0884e8a26cff730f4e03)

  import SpriteKit
  import GameplayKit

   struct physicsCatagory{
     static let me : UInt32 = 0x1 << 1
     static let enemy : UInt32 = 0x1 << 2

    }

  class GameScene: SKScene, SKPhysicsContactDelegate {


private func makeEnemyName() -> String {
    enemyCounter += 1
    return "enemy\(enemyCounter)"
}

private func addEnemyToDict(enemy: SKSpriteNode, target: SKSpriteNode) {
    if let name = enemy.name { spriteDictionary[name] = (enemy, target) }
    else { print("enemy not found") }
}

private func removeEnemyFromDict(enemy: SKSpriteNode) {
    if let name = enemy.name { spriteDictionary[name] = nil }
    else { print("enemy not removed from dictionary!") }
}

private func moveFollowerToTarget(_ sprites: FollowerAndTarget) {
    let action = SKAction.move(to: sprites.target.position, duration: 1)
    sprites.follower.run(action)
}



private func allEnemiesMoveToTarget() {
    for sprites in spriteDictionary.values {
        moveFollowerToTarget(sprites)
    }
}

let enemySpeed: CGFloat = 300
var me = SKSpriteNode()
// Tuple to keep track of enemy objects:
typealias FollowerAndTarget = (follower: SKSpriteNode, target: SKSpriteNode)
// [followerName: (followerSprite, targetSprite):
var spriteDictionary: [String: FollowerAndTarget] = [:]
// Give each enemy a unique name for the dictionary:
var enemyCounter = 0
var died = Bool()




override func didMove(to view: SKView) {

    createScene()
}



func createEnemy () {
    if died == true{

    }
    else {
    let enemy = SKSpriteNode(imageNamed: "enemy1")
    enemy.name = makeEnemyName()
    addEnemyToDict(enemy: enemy, target: me)
    moveFollowerToTarget((follower: enemy, target: me))
    enemy.size = CGSize(width: 60, height: 60)
    enemy.position = CGPoint(x:667, y: 200)
    enemy.physicsBody?.restitution = 0.5
    enemy.physicsBody = SKPhysicsBody(circleOfRadius: 60)
    enemy.physicsBody?.affectedByGravity = false
    enemy.zPosition = 2
    enemy.physicsBody?.linearDamping = 0
    enemy.physicsBody?.isDynamic = true
    enemy.physicsBody?.categoryBitMask = physicsCatagory.enemy
    enemy.physicsBody?.collisionBitMask = physicsCatagory.me
    enemy.physicsBody?.contactTestBitMask = physicsCatagory.me
    addChild(enemy)
    }
}


func didBegin(_ contact: SKPhysicsContact) {

    let firstBody = contact.bodyA
    let secondBody = contact.bodyB

    if firstBody.categoryBitMask == physicsCatagory.me && secondBody.categoryBitMask == physicsCatagory.enemy || firstBody.categoryBitMask == physicsCatagory.enemy && secondBody.categoryBitMask == physicsCatagory.me {
        died = true
        restartScene()
    }

}
var lose: SKLabelNode!


func restartScene(){
    self.removeAllChildren()
    self.removeAllActions()
    died = false

    if let nextScene = GameScene(fileNamed: "menuScene"){
        nextScene.scaleMode = self.scaleMode
        let transition = SKTransition.fade(withDuration: 1)
        view?.presentScene(nextScene, transition: transition)
    }
}

func createScene(){
    me = self.childNode(withName: "me") as! SKSpriteNode
    me.physicsBody = SKPhysicsBody(circleOfRadius: 20)
    me.physicsBody?.affectedByGravity = false
    me.physicsBody?.categoryBitMask = physicsCatagory.me
    me.physicsBody?.collisionBitMask = physicsCatagory.enemy
    me.zPosition = 2

    self.physicsWorld.contactDelegate = self

    let border = SKPhysicsBody (edgeLoopFrom: self.frame)
    border.friction = 0
    self.physicsBody = border

    run(SKAction.repeatForever(SKAction.sequence([SKAction.run(createEnemy), SKAction.wait(forDuration: 4.0)])))
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches{

        let location = touch.location(in: self)
        me.run(SKAction.moveTo(x: location.x, duration: 0))
        me.run(SKAction.moveTo(y: location.y, duration: 0))
        allEnemiesMoveToTarget()
    }




}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches{

        let location = touch.location(in: self)
        me.run(SKAction.moveTo(x: location.x, duration: 0))
        me.run(SKAction.moveTo(y: location.y, duration: 0))
        allEnemiesMoveToTarget()
    }
}

override func update(_ currentTime: TimeInterval) {

    // Will iterate through dictonary and then call moveFollowerToTarget()
    // thus giving each enemy a new movement action to follow.
    allEnemiesMoveToTarget()
}

}

1 Answers
Related