【问题标题】:Spawn objects at random durations without overlaying随机生成对象而不叠加
【发布时间】:2016-05-26 17:02:25
【问题描述】:

说明

我正在构建一个我面临一些问题的游戏。我有两个按照相同规则运行的对象(A 和 B):从上到下,它们产生、向下移动并在到达边缘时被移除。它们中的每一个在生成之前都有其特定的持续时间,这样,有时它们会被覆盖(如下所示)。


问题

问题很简单:有没有办法让 A 和 B 产生不同的持续时间,但仍然是随机的?


代码

如果你愿意,可以下载这个项目here

import SpriteKit

class GameScene: SKScene {

    //Declarations
    var A = SKSpriteNode()
    var B = SKSpriteNode()
    var durationA = CGFloat()
    var durationB = CGFloat()

    //Setup
    func setupA(){
        A = SKSpriteNode(imageNamed: "A")
        A.position = CGPoint(x: self.frame.width / 2, y: self.frame.height)
    }
    func setupB(){
        B = SKSpriteNode(imageNamed: "B")
        B.position = CGPoint(x: self.frame.width / 2, y: self.frame.height)
    }

    //Actions
    func actionsA(){

        //Start spawning, moving and removing
        let spawnA = SKAction.runBlock({
            () in

            //Spawn A
            self.setupA()
            self.addChild(self.A)

            //Move left and remove when go off screenk
            let frameHeight = CGFloat(self.frame.height)
            let moveA = SKAction.moveByX(0, y: -frameHeight, duration: NSTimeInterval(0.0028 * frameHeight))  //duration: faster or slower
            let removeA = SKAction.removeFromParent()

            let moveAndRemoveA = SKAction.sequence([moveA, removeA])

            self.A.runAction(moveAndRemoveA)
        })

        //Spawn A each 1.75~2.25 seconds
        durationA = (CGFloat(arc4random_uniform(51)) + 175.0) / 100.0
        let spawnAfterDurationA = SKAction.repeatActionForever(SKAction.sequence([SKAction.waitForDuration(Double(durationA)), spawnA]))
        runAction(spawnAfterDurationA)
    }
    func actionsB(){

        //Start spawning, moving and removing
        let spawnB = SKAction.runBlock({
            () in

            //Spawn B
            self.setupB()
            self.addChild(self.B)

            //Move left and remove when go off screen
            let frameHeight = CGFloat(self.frame.height)
            let moveB = SKAction.moveByX(0, y: -frameHeight, duration: NSTimeInterval(0.0028 * frameHeight))   //duration: faster or slower
            let removeB = SKAction.removeFromParent()

            let moveAndRemoveB = SKAction.sequence([moveB, removeB])

            self.B.runAction(moveAndRemoveB)
        })

        //Spawn B each 0.5~1.0 seconds
        durationB = (CGFloat(arc4random_uniform(51)) + 50.0) / 100.0
        let spawnAfterDurationB = SKAction.repeatActionForever(SKAction.sequence([SKAction.waitForDuration(Double(durationB)), spawnB]))
        runAction(spawnAfterDurationB)
    }

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        actionsA()
        actionsB()
    }
}

蒂莫西·史密斯的尝试

如果需要,可以here下载。

import SpriteKit

class GameScene: SKScene {

    //Declarations
    var A = SKSpriteNode()
    var B = SKSpriteNode()

    //Setup
    func setupA(){
        A = SKSpriteNode(imageNamed: "A")
        A.position = CGPoint(x: self.frame.width / 2, y: self.frame.height)
    }
    func setupB(){
        B = SKSpriteNode(imageNamed: "B")
        B.position = CGPoint(x: self.frame.width / 2, y: self.frame.height)
    }

    //Actions
    func actionsA(){

        //Spawn, move and remove
        let spawnA = SKAction.runBlock({
            () in

            //Spawn A
            self.setupA()
            self.addChild(self.A)

            //Move left and remove when go off screenk
            let frameHeight = CGFloat(self.frame.height)
            let moveA = SKAction.moveByX(0, y: -frameHeight, duration: NSTimeInterval(0.0028 * frameHeight))  //duration: faster or slower
            let removeA = SKAction.removeFromParent()

            let moveAndRemoveA = SKAction.sequence([moveA, removeA])

            self.A.runAction(moveAndRemoveA)
        })

        runAction(spawnA)
    }
    func actionsB(){

        //Spawn, move and remove
        let spawnB = SKAction.runBlock({
            () in

            //Spawn B
            self.setupB()
            self.addChild(self.B)

            //Move left and remove when go off screen
            let frameHeight = CGFloat(self.frame.height)
            let moveB = SKAction.moveByX(0, y: -frameHeight, duration: NSTimeInterval(0.0028 * frameHeight))   //duration: faster or slower
            let removeB = SKAction.removeFromParent()

            let moveAndRemoveB = SKAction.sequence([moveB, removeB])

            self.B.runAction(moveAndRemoveB)
        })

        runAction(spawnB)
    }

    //Spawn
    func spawn(){

        let random = Int(arc4random_uniform(10)+1) //pick a number from 1 to 10

        if random <= 8{
            actionsB()
        }
        else{
            actionsA()
        }
    }

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        runAction(SKAction.repeatActionForever(SKAction.sequence([SKAction.waitForDuration(0.5, withRange: 0.25), SKAction.runBlock(self.spawn)])))
    }
}


在此先感谢,
路易斯。

【问题讨论】:

    标签: ios swift sprite-kit


    【解决方案1】:

    一种可能的解决方案是使用单个函数spawn,每 0.25 到 1.00 秒随机调用一次。在函数内部,随机选择 A 或 B,然后生成它。您似乎希望 B 比 A 更频繁地出现,因此您可以使用加权随机性(选择一个从 0.45 到 1 的数字并四舍五入到最接近的整数)。

    这是否有效取决于是否可以接受超过 1 秒的 B 间隔。

    【讨论】:

    • 我按照你说的步骤做了,但是当你说从 0.45 到 1 中选择一个数字并四舍五入到最接近的整数时,我想我只有零和一,不是吗? ?所以我选择了一个从1到10的随机数,当 8时产生A),这样B会比A出现的频率更高。话虽如此,它仍然同时产生(覆盖)=(
    • 对不起,如果我误解了什么,我只是想帮助你帮助我=)
    • 我根据您的建议更新了代码。如果有帮助,您也可以在那里下载该项目。
    • 你将有一个 0 或一个 1。如果它是 0,则产生 A,否则产生 B。目前你正在做的是调用 actionsA。请记住,actionA 实际上并没有产生任何东西:它会创建一个随机重复的循环,它会自行产生。我不熟悉这种语言,但我认为您可以修改 actionsA 中的最后一行,这样说:runAction(spawnA) 这可能会解决问题。
    • 当我在 0.45 和 1.00 之间舍入随机值时,我有 99% 的机会得到 0 和 1% 的机会得到 1,但奇怪的是,四舍五入时返回的数字多于零(我做了测试看结果不四舍五入,1.00非常少见)。如果我们遵循“正确”规则并确定在舍入时我们应该得到更多的零,因为B 应该比A 更频繁地出现,actionsB 将在 0(99% 的机会)和 @ 时被调用987654326@ 当 1(1% 的机会)。
    【解决方案2】:

    每次运行(arc4random_uniform(50)+51)/100 时,它都会为您提供 0.5 到 1.0 秒之间的随机持续时间。您可以使用以下代码为AB 生成随机持续时间

    durationA = (arc4random_uniform(50)+51)/100 durationB = (arc4random_uniform(50)+51)/100

    此外,您可以运行一个 for 循环来比较 durationB 和 durationA,如果 durationBdurationA 不同,则只接受它。

    【讨论】:

    • 我只是尝试这样做,但它没有产生任何孩子。我所做的只是使用您所说的持续时间并将其应用于动作。我更新了代码。
    • 抱歉这么久才回答。这周我有点忙。
    • 经过一番研究,我设法让它产卵。但是因为我使用 1.75 到 2.25 来表示 durationA 和 0.5 到 1.0 来表示 durationB,所以这些数字永远不会相同,这样,它就永远不会进入循环,但有时会在相同的位置产生。
    猜你喜欢
    • 1970-01-01
    • 2014-05-13
    • 2012-12-31
    • 2019-08-02
    • 2011-06-13
    • 2015-07-30
    • 2015-12-02
    • 1970-01-01
    • 2016-03-10
    相关资源
    最近更新 更多