【问题标题】:Simulating sushi train - Swift SpriteKit模拟寿司火车 - Swift SpriteKit
【发布时间】:2017-09-22 02:37:47
【问题描述】:

我正在学习使用 SprikeKit 创建游戏,该游戏与寿司火车有关。

我有大约 20 个盘子沿着矩形路径移动,以模拟所有盘子都在移动的传送带上的样子。

我尝试使用场景编辑器放置几个精灵节点,并让它们像这样在方形路径上移动。

let dish_1 = self.childNode(withName: "dish_1");
let dish_2 = self.childNode(withName: "dish_2");

let square = UIBezierPath(rect: CGRect(x: 0, y: 0,  width: 200, height: 200));
let followSquare = SKAction.follow(square.cgPath, asOffset: true, orientToPath: false, duration: 5.0);

dish_1?.run(SKAction.sequence([followSquare]))
dish_2?.run(SKAction.sequence([followSquare]))

目前,两个菜使用的是同一个正方形,正方形的位置是相对于每个菜的,所以它们看起来像是在两条不同的矩形路径上,因为它们的起点不同。

这是模拟我所追求的外观的合理方式吗? 我问这个的原因是为了让所有盘子看起来都在同一条路径上移动,我需要调整每个盘子的 x、y 位置,这将是 20 个盘子。

我想知道是否可以使用物理工具包,让一个矩形节点让所有盘子沿着路径移动,只要它们在矩形节点区域内。

【问题讨论】:

    标签: ios swift sprite-kit skphysicsbody


    【解决方案1】:

    好吧,我可能会以类似的方式完成它,我认为使用 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

    【讨论】:

    • 非常感谢。很有帮助。我正在考虑使用 copy()。但是因为每道菜的距离都需要有实际的寿司作为子节点,所以我不确定复制的实例是否允许有一个子节点。每道菜还必须有唯一的标识符供玩家选择并补充寿司,所以我想知道如果它们是复制实例,如何知道它的 id。
    • 不客气@SeongLeem,我更新了我的答案,为您提供有关如何在您的应用中实现它的更多详细信息
    • 这很棒。谢谢!世界节点在这里而不是场景的用例是什么?每个菜复制节点都需要有一个子节点,例如鲑鱼、金枪鱼等。所以我想我可以使用循环为前 5 道菜分配鲑鱼子节点,如 for _ in 0..
    • worldNode 这里只是一个包含我场景中所有元素的 SKNode。建议这样做,这样您可以更轻松地管理所有元素,根据需要添加和删除它们,而不会出现zIndex等问题。
    • 没错,您可以使用 for 循环将您的子节点添加到每道菜中。当然,正如您所说,您仍然可以根据需要添加的内容以及添加到哪道菜将其分解为多个 for 循环。不过,我不确定您所说的多级向下或向上是什么意思?
    【解决方案2】:

    asOffset 似乎不正确。根据the documentation,这与您想要的完全相反的行为

    如果是,路径中的点是节点起始位置的相对偏移量。如果否,则节点中的点为绝对坐标值。

    将此设置为 true 将为每道菜提供它们自己的矩形路径,其坐标相对于它们的起始位置,正如您在问题中描述的那样:

    v 第一道菜 v 第二道菜 O--O-----.----。 | | | | | | | | '--'-----'---' ^^ 第二道菜的路径 ^^ 第一道菜的路径

    相反,我想您需要在绝对坐标中设置传送带,然后将每道菜的起点初始化为不同的 - 再次在绝对坐标中 - 最后让每道菜遵循上述路径:

    v 第一道菜(起点 x=0;y=0) v 第二道菜(起点 x=20;y=0) 哦--哦--。 | | | | '--------' ^^ 单条绝对路径

    (如果您正在模拟寿司传送带,它们会顺时针移动,并且上面的术语“第一”和“第二”在技术上是倒退的。交换这个留给读者作为练习。:-P)

    【讨论】:

    • 感谢您富有洞察力的回答。这似乎绝对是要走的路。抱歉,我是游戏开发新手,如何将矩形路径设置为绝对坐标?默认是相对的吗?
    • 我想这一切都在您对follow 的调用中的asOffset 参数中。如果将此设置为 false,则表示路径坐标是绝对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2022-01-20
    • 1970-01-01
    • 2015-04-03
    • 2014-05-24
    • 1970-01-01
    • 2013-06-21
    相关资源
    最近更新 更多