好吧,我可能会以类似的方式完成它,我认为使用 SKAction.follow 是一个解决方案。
但是您可以在代码中进行一些改进。第一个是您不需要将 SKAction 编写为序列,因为它仅由一个操作组成,因此您可以将代码简化为:
let squarePath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200))
let followAction = SKAction.follow(path: squarePath.cgPath, duration: 5.0)
dish?.run(followAction)
现在另一件重要的事情是,为了节省您的内存使用量,您可以在您的SKSpriteNode 上使用copy() 来创建许多不同的副本,而不是每次(20 次)重新创建一个新菜其中。根据您需要实现的目标,您当然可以自定义每个副本,更改其颜色或位置等。这样会更有效率。
您可以像这样创建 SKSpriteNode 的副本:
import GameplayKit
if let dishCopy = dish?.copy() as? SKSpriteNode {
dishCopy.position = CGPoint(x: GKRandomDistribution(lowestValue: 0, highestValue: 200).nextInt(), y: GKRandomDistribution(lowestValue: 0, highestValue: 500).nextInt())
self.addChild(dishCopy)
}
对于每个盘子副本的位置,你当然可以调整到自己的值,但这里我使用了 GameplayKit 及其非常有用的随机值生成器。
更新:
如果您想在仍然使用 copy() 的同时为每道菜设置一个唯一的名称,您有多种选择。
一种可能是使用您要递增的计数器生成一个唯一名称,另一种可能是在更新方法中使用 currentTime。
但是另一种更优雅的方法是创建一个数组来存储所有副本,并跟踪所有副本的位置。
在你的场景子类的顶部,像这样声明你的菜数组:
var dishes = [SKSpriteNode]()
目前,它仍然是空的,因此您需要在创建每个副本时将每个副本添加到数组中:
// Create (safely) a dish copy:
if let dishCopy = dish?.copy() as? SKSpriteNode {
// Add the dish copy to the dishes array:
dishes.append(dishCopy)
// And add the dish copy to the world node:
worldNode?.addChild(dishCopy)
}
如果您想创建许多这样的副本,您可以使用for loop,或者您可以使用update(_ currentTime:) 方法,指定您希望每5 秒创建一个新的寿司盘,例如:)。
而且,如果您在任何时候需要访问这些副本中的任何一个,只需访问dishes 数组即可。
例如,这就是您删除所有副本的方式(如果您将原始菜肴添加到场景中,您将不得不处理它):
// And just iterate through all of your dish copies:
for dish in dishes {
dish.removeFromParent()
// Do whatever you need here :)
}
它非常简单,它可以让您完美地控制您添加到worldNode 的所有对象和/或副本。
如果您有任何其他问题,请告诉我,我很乐意为您提供帮助!
顺便说一句,今晚我实际上会去你在你的问题中谈论的寿司店,那个有小火车的..真是巧合! :D