1

Currently doing a SoloProject for class and decided to study SpriteKit on my own. I decided to make a top-down zombie shooter and I have a lot of questions but so far these are the two main ones I can't seem to fix or find solution for.

Problem 1

Zombies slow down the closer they get to the target, If I increase the speed they just speed in from off the screen and still slowdown as they get closer (I've read somewhere putting that function in the update is bad but I still did it...)

I want to make it where they spawn with the speed of 3 and when the player moves closer or further away it stays at 3. (Currently using an analog stick code I found that was on Youtube to move my character around)

func zombieAttack() {
    let location = player.position
    for node in enemies {
        let followPlayer = SKAction.move(to: player.position, duration: 3)
        node.run(followPlayer)
        //Aim
        let dx = (location.x) - node.position.x
        let dy = (location.y) - node.position.y
        let angle = atan2(dy, dx)

        node.zRotation = angle

        //Seek
        let velocityX =  cos(angle) * 1
        let velocityY =  sin(angle) * 1

        node.position.x += velocityX
        node.position.y += velocityY
    }
}
override func update(_ currentTime: TimeInterval) {
    zombieAttack()
}

Problem 2

Also when multiple zombies get close to the players (function above) they start to spazz so I allowed them to overlap on top of each other to stop the spazzing.

I want to make it where they are more solid? if that is the right way to describe it. Basically I want them to huddle up around the player**.

If I add enemy to the collision it will spazz trying to get into the same position.

private func spawnZombie() {
    let xPos = randomPosition(spriteSize: gameSpace.size)
    let zombie = SKSpriteNode(imageNamed: "skeleton-idle_0")
    zombie.position = CGPoint(x: -1 * xPos.x, y: -1 * xPos.y)
    zombie.name = "Zombie\(zombieCounter)"
    zombie.zPosition = NodesZPosition.enemy.rawValue
    let presetTexture = SKTexture(imageNamed: "skeleton-idle_0.png")
    zombie.physicsBody = SKPhysicsBody(texture: presetTexture, size: presetTexture.size())
    zombie.physicsBody?.isDynamic = true
    zombie.physicsBody?.affectedByGravity = false
    zombie.physicsBody?.categoryBitMask = BodyType.enemy.rawValue
    zombie.physicsBody?.contactTestBitMask = BodyType.bullet.rawValue
    zombie.physicsBody?.collisionBitMask = BodyType.player.rawValue
    zombie.zRotation = 1.5
    zombie.setScale(0.2)
    enemies.append(zombie)
    zombieCounter += 1
    run(SKAction.playSoundFileNamed("ZombieSpawn", waitForCompletion: false))
    keepEnemiesSeperated() // ADDED FROM UPDATED EDIT*
    addChild(zombie)
}

Let me know if I need to post more code or explain it better, I'm a five months in on learning Swift and have only a week and a half of SpriteKit experience and first time posting on StackOverFlow. Thanks all in advance!

EDIT: I am using a code I found from having a node follow at a constant speed but I don't think I'm doing it right since it is not working. I added the following code:

private func keepEnemiesSeparated() {
    // Assign constrain
    for enemy in enemies {
        enemy.constraints = []
        let distanceBetween = CGFloat(60)
        let constraint = SKConstraint.distance(SKRange(lowerLimit: distanceBetween), to: enemy)
        enemy.constraints!.append(constraint)
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Biron Su
  • 11
  • 2

1 Answers1

0

Problem 1, your zombie is moving based on time, not at a set speed. According to your code, he will always reach the player in 3 seconds. This means if he is 1 foot away, he takes 3 seconds. If he is 100 miles away, he takes 3 seconds. You need to use a dynamic duration if you are planning to use the moveTo SKAction based on the speed of the zombie. So if your zombie moves 10 points per second, you want to calculate the distance from zombie to player, and then divide by 10. Basically, your duration formula should be distance / speed

Problem 2, if you want the zombies to form a line, you are going to have to determine who the leading zombie is, and have each zombie follow the next leading zombie as opposed to all zombies following the player. Otherwise your other option is to not allow zombies to overlap, but again, you will still end up with more of a mosh pit then a line.

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • That makes so much sense! Thanks!! And I think we went to different buffet lines because the one in my mind was basically just a bunch of people gathering and skipping each other so I'll reword it better, I want them to huddle up around the player... yes that sounds exactly right ahahah. – Biron Su Mar 12 '19 at 18:06
  • ok, if you want them to huddle around the player then you need to give the zombies the capabilities of walking around other zombies, which involves pathfinding – Knight0fDragon Mar 12 '19 at 18:10
  • Sweet! I am going to try to make a Tower Defense game for fun after so I'll study pathfinding more in the future, thanks!! – Biron Su Mar 12 '19 at 18:12