如何使 SKSpriteNode 跟随另一个 SKSpriteNode

Posted

技术标签:

【中文标题】如何使 SKSpriteNode 跟随另一个 SKSpriteNode【英文标题】:how to make an SKSpriteNode follow another SKSpriteNode 【发布时间】:2017-04-14 11:46:19 【问题描述】:

我的代码遇到了一些问题。我正在尝试使用以下代码让僵尸跟随我的玩家:

class GameScene: SKScene, SKPhysicsContactDelegate 
    func Enemies() 
        Enemy = SKSpriteNode(imageNamed: "Spaceship")
        Enemy.size = CGSize(width: 50, height: 50)
        Enemy.color = UIColor(red: 0.9, green: 0.1, blue: 0.1, alpha: 1.0)
        Enemy.colorBlendFactor = 1.0

        //physics
        Enemy.physicsBody = SKPhysicsBody(rectangleOf: Enemy.size)
        Enemy.physicsBody?.isDynamic = true
        Enemy.physicsBody?.affectedByGravity = false
        Enemy.name = "Enemy"

        Enemy.position.y = -frame.size.height/2
        let positionX = arc4random_uniform(UInt32(frame.size.width))
        Enemy.position.x = CGFloat(positionX)
        addChild(Enemy)
    

    override func didMove(to view: SKView) 

        enemyTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(GameScene.Enemies), userInfo: nil, repeats: true)

    override func update(_ currentTime: TimeInterval) 
        Enemy.run(SKAction.move(to: ship.position, duration: 3))
    

如果我运行这段代码,我可以生成僵尸,但它们不会跟随我的主玩家,它们只会回到他们生成时的位置(即在时间 = 0 时生成的僵尸将转到时间 = 0 时的船位置,在时间 = 1 产生的僵尸将在时间 = 1 时到达船位置,依此类推)。但是,如果我在只生成一个僵尸的同时运行此代码:

override func didMove(to view: SKView) 
    Enemies()

孤独的僵尸会跟着我的玩家四处走动。知道为什么代码适用于一个僵尸,但不适用于多个僵尸吗?

【问题讨论】:

这里有很多问题......你不应该使用定时器。它不与游戏循环配对。其次,您不应该每秒应用新操作 60 次以实现 target and a seeker behaviour 接下来,要记住的一件好事是,操作一旦创建就无法修改。意思是,当你设置一次动作的参数时,你以后不能修改它们。另外,你的 Enemy 变量是全局的,这对我来说没有意义。它只保留对添加的最后一个敌人的引用。我的意思是,在这种情况下你的逻辑可能也是错误的...... 【参考方案1】:

我不建议您在更新周期中不断添加操作,因为幕后发生的所有事情都会使您遭受性能损失。相反,请使用 SKAction.customAction,您只会将其添加到您的 sprite 中一次。 这是一个自定义操作的示例,它将执行您想要的操作,请记住只分配一次。 (代码未经测试,因此可能需要修改)

let customActionBlock = 

  (node,elapsedTime) in 
  let dx = ship.x - node.position.x
  let dy = ship.y - node.position.y 
  let angle = atan2(dx,dy)
  node.position.x += sin(angle) * speedPerFrame
  node.position.y += cos(angle) * speedPerFrame



let duration = TimeInterval(Int.max) //want the action to run infinitely
let followPlayer = SKAction.customAction(withDuration:duration,actionBlock:customActionBlock)
Enemy.run(action:followPlayer,withKey:"follow")

【讨论】:

【参考方案2】:

也许您应该在阅读操作之前在EnemyremoveAllActions()。看起来你有需要 3 秒的动作,但是你每帧添加一个动作,所以它一次最多有 180 个节点的动作。

【讨论】:

检查shipstruct 还是class。也许它是struct,而您只是复制该值,以后再也不更新它——它应该是class

以上是关于如何使 SKSpriteNode 跟随另一个 SKSpriteNode的主要内容,如果未能解决你的问题,请参考以下文章

如何像足球一样轻弹 SKSpriteNode

Swift Sprite Kit 相机运动

如何使任何模拟器/设备的 SKSpriteNode 位置相同?

如何检查一个 sknode 是不是触及另一个

知道 skspritenode 已经完全移过另一个 skspritenode

在SpriteKit中跟随的敌人会加班加点