如何在不重叠的情况下生成多个节点?

时间:2022-01-01 07:20:32

I have nodes spawning every 0.2-5.0 seconds on my screen like so:

我的屏幕上每0.2-5.0秒就会产生一个节点,比如:

override func didMoveToView(view: SKView) {
    backgroundColor = UIColor.whiteColor()

    runAction(SKAction.repeatActionForever(
        SKAction.sequence([
            SKAction.runBlock(blackDots),
            SKAction.waitForDuration(1.0)])))
}

func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max - min) + min
}

func blackDots() {
    let dot = SKSpriteNode(imageNamed: "first@2x")
    dot.size = CGSizeMake(75, 75)
    dot.name = "dotted"
    dot.position = CGPointMake(500 * random(min: 0, max: 1), 500 * random(min: 0, max: 1))
    addChild(dot)
}

However, when they are spawned, some intersect and lay on top of one another? Is there a way to prevent this? Thanks in advance.

然而,当它们被衍生出来的时候,会有一些交叉并相互叠加?有没有办法避免这种情况?提前谢谢。

2 个解决方案

#1


2  

Here's how to check if a node exists at a particular position.

以下是检查节点是否存在于特定位置的方法。

You might want to throw the check into a loop so that if the position is taken, it will retry with a newly generated point. Otherwise you'll get some dots that just won't show. Just depends on what you're doing with them.

您可能希望将check放入一个循环中,以便如果采取了该位置,它将重新尝试使用新生成的点。否则你会得到一些不显示的点。这取决于你对他们做了什么。

override func didMoveToView(view: SKView) {
    backgroundColor = UIColor.whiteColor()

    runAction(SKAction.repeatActionForever(
        SKAction.sequence([
            SKAction.runBlock(blackDots),
            SKAction.waitForDuration(1.0)])))
}

func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max - min) + min
}

func blackDots() {
    let dot = SKSpriteNode(imageNamed: "first@2x")
    dot.size = CGSizeMake(75, 75)
    dot.name = "dotted"

    let position = CGPointMake(500 * random(min: 0, max: 1), 500 * random(min: 0, max: 1))

    if positionIsEmpty(position) {
        dot.position = position
        addChild(dot)
    }
}

func positionIsEmpty(point: CGPoint) -> Bool {
    self.enumerateChildNodesWithName("dotted", usingBlock: {
        node, stop in

        let dot = node as SKSpriteNode
        if (CGRectContainsPoint(dot.frame, point)) {
            return false
        }
    })
    return true
}

#2


0  

here is this in swift 3.1 please note that this did take me several hours to recreate successfully also a for-loop or TimerInterval won't run this properly it has to be a sequence of actions

这是在swift 3.1中,请注意,这确实花费了我几个小时来成功地重新创建一个for循环或者TimerInterval不能正常运行它必须是一个操作序列

like this

像这样

    let wait = SKAction.wait(forDuration: 1)
    let spawn = SKAction.run {
        //be sure to call your spawn function here
        example()
    }
    let sequence = SKAction.sequence([wait, spawn])
    self.run(SKAction.repeatForever(sequence))

if this is done right it should work like I have it

如果这是正确的,它应该像我一样工作

    func example() {
    //the person node is equal to an SKSpriteNode subclass 
    person = people()
    func random() -> CGFloat {
    //this is the random spawn generator increasing or decreasing these two numbers will change how far or how close they spawn together
        return CGFloat(Float(arc4random_uniform(UInt32(500 - 343))))
    }

    func random(min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }

    func spawnPeople() {
        //note that this is set to spawn them on the x-axis but can easily be changed for the y-axis
        let position = CGPoint(x: 2 * random(min: 0, max: 1),y: -290)

        if positionIsEmpty(point: position) {
        //set the position of your node and add it to the scene here any actions you want to add to the node will go here
            person.position = position
            self.addChild(person)
            //example 
            person.run(parallax1)
        }
    }

    func positionIsEmpty(point: CGPoint) -> Bool {
        if (person.frame.contains(point)) {
            print("failed")
            return false
        }
        print("success")
        return true
    }
    //make sure to call the spawn(name)() function down here or the code will not run
    spawnPeople()
}

also I have all of this code in my didMoveToView function

我在didMoveToView函数中也有这些代码

#1


2  

Here's how to check if a node exists at a particular position.

以下是检查节点是否存在于特定位置的方法。

You might want to throw the check into a loop so that if the position is taken, it will retry with a newly generated point. Otherwise you'll get some dots that just won't show. Just depends on what you're doing with them.

您可能希望将check放入一个循环中,以便如果采取了该位置,它将重新尝试使用新生成的点。否则你会得到一些不显示的点。这取决于你对他们做了什么。

override func didMoveToView(view: SKView) {
    backgroundColor = UIColor.whiteColor()

    runAction(SKAction.repeatActionForever(
        SKAction.sequence([
            SKAction.runBlock(blackDots),
            SKAction.waitForDuration(1.0)])))
}

func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max - min) + min
}

func blackDots() {
    let dot = SKSpriteNode(imageNamed: "first@2x")
    dot.size = CGSizeMake(75, 75)
    dot.name = "dotted"

    let position = CGPointMake(500 * random(min: 0, max: 1), 500 * random(min: 0, max: 1))

    if positionIsEmpty(position) {
        dot.position = position
        addChild(dot)
    }
}

func positionIsEmpty(point: CGPoint) -> Bool {
    self.enumerateChildNodesWithName("dotted", usingBlock: {
        node, stop in

        let dot = node as SKSpriteNode
        if (CGRectContainsPoint(dot.frame, point)) {
            return false
        }
    })
    return true
}

#2


0  

here is this in swift 3.1 please note that this did take me several hours to recreate successfully also a for-loop or TimerInterval won't run this properly it has to be a sequence of actions

这是在swift 3.1中,请注意,这确实花费了我几个小时来成功地重新创建一个for循环或者TimerInterval不能正常运行它必须是一个操作序列

like this

像这样

    let wait = SKAction.wait(forDuration: 1)
    let spawn = SKAction.run {
        //be sure to call your spawn function here
        example()
    }
    let sequence = SKAction.sequence([wait, spawn])
    self.run(SKAction.repeatForever(sequence))

if this is done right it should work like I have it

如果这是正确的,它应该像我一样工作

    func example() {
    //the person node is equal to an SKSpriteNode subclass 
    person = people()
    func random() -> CGFloat {
    //this is the random spawn generator increasing or decreasing these two numbers will change how far or how close they spawn together
        return CGFloat(Float(arc4random_uniform(UInt32(500 - 343))))
    }

    func random(min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }

    func spawnPeople() {
        //note that this is set to spawn them on the x-axis but can easily be changed for the y-axis
        let position = CGPoint(x: 2 * random(min: 0, max: 1),y: -290)

        if positionIsEmpty(point: position) {
        //set the position of your node and add it to the scene here any actions you want to add to the node will go here
            person.position = position
            self.addChild(person)
            //example 
            person.run(parallax1)
        }
    }

    func positionIsEmpty(point: CGPoint) -> Bool {
        if (person.frame.contains(point)) {
            print("failed")
            return false
        }
        print("success")
        return true
    }
    //make sure to call the spawn(name)() function down here or the code will not run
    spawnPeople()
}

also I have all of this code in my didMoveToView function

我在didMoveToView函数中也有这些代码