You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpriteKit:多敌人跟随玩家时仅单个移动的问题求助

解决SpriteKit多敌人仅单个移动的问题

嘿,这个问题我太熟悉啦!核心原因很明显——你用了单个SKSpriteNode变量spawnZombie来存储敌人,当生成第二个敌人时,这个变量会被新的敌人实例覆盖,导致只有最后生成的那个敌人能执行移动逻辑,之前的敌人就“失联”了,自然不会动。

解决方案步骤:

  • 改用数组存储所有敌人:把单个变量替换成数组,这样可以保存所有生成的敌人引用。
  • 封装敌人生成逻辑:每次生成新敌人时,创建独立的实例并添加到数组和场景中。
  • 遍历数组更新所有敌人的移动:在update方法里逐个处理每个敌人的移动逻辑。

修改后的代码示例:

import SpriteKit

class GameScene: SKScene {
    var player: SKSpriteNode?
    // 替换单个变量为数组,存储所有敌人
    var zombies = [SKSpriteNode]()
    var playerTexture: SKTexture!
    private var lastUpdateTime: TimeInterval = 0
    
    override func didMove(to view: SKView) {
        playerTexture = SKTexture(imageNamed: "player_2")
        player = SKSpriteNode(texture: playerTexture)
        player?.name = "player"
        player?.position = CGPoint(x: frame.midX, y: frame.midY)
        addChild(player!)
        
        // 生成两个测试敌人
        spawnZombie(at: CGPoint(x: frame.minX + 100, y: frame.midY))
        spawnZombie(at: CGPoint(x: frame.maxX - 100, y: frame.midY))
    }
    
    // 封装生成敌人的方法,每次生成独立实例
    func spawnZombie(at position: CGPoint) {
        let zombieTexture = SKTexture(imageNamed: "zombie") // 替换成你的敌人纹理
        let zombie = SKSpriteNode(texture: zombieTexture)
        zombie.name = "zombie"
        zombie.position = position
        zombies.append(zombie)
        addChild(zombie)
    }
    
    override func update(_ currentTime: TimeInterval) {
        guard let player = player else { return }
        
        // 初始化时间差(避免第一次update时的异常)
        if lastUpdateTime == 0 {
            lastUpdateTime = currentTime
            return
        }
        let deltaTime = currentTime - lastUpdateTime
        
        // 遍历所有敌人,逐个处理移动逻辑
        for zombie in zombies {
            // 计算敌人到玩家的方向向量
            let directionX = player.position.x - zombie.position.x
            let directionY = player.position.y - zombie.position.y
            let distance = sqrt(directionX * directionX + directionY * directionY)
            
            // 当距离足够远时才移动,避免近距离抖动
            if distance > 20 {
                let moveSpeed: CGFloat = 150 // 自定义移动速度
                // 归一化方向向量并乘以速度和时间差
                let moveX = directionX / distance * moveSpeed * CGFloat(deltaTime)
                let moveY = directionY / distance * moveSpeed * CGFloat(deltaTime)
                
                zombie.position.x += moveX
                zombie.position.y += moveY
                
                // 可选:让敌人朝向玩家
                zombie.zRotation = atan2(directionY, directionX)
            }
        }
        
        lastUpdateTime = currentTime
    }
}

关键说明:

  • 用[SKSpriteNode]()数组替代单个spawnZombie变量,确保每个生成的敌人都被保存和管理。
  • 在update方法中遍历数组,对每个敌人单独计算移动路径,这样所有敌人都会响应玩家位置变化。
  • 加入deltaTime(时间差)来保证移动速度在不同帧率下一致,避免卡顿或过快的问题。

内容的提问来源于stack exchange,提问作者sicvayne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:32:08