【问题标题】:SpriteKit - Create at random position without overlappingSpriteKit - 在随机位置创建而不重叠
【发布时间】:2015-10-10 18:40:26
【问题描述】:

我想在不重叠的随机位置创建一些精灵,这是我的代码:

var sprites = [SKSpriteNode]()

 for index in 0...spriteArray { 

                let sprite = SKSpriteNode(imageNamed: named)
                sprites.append(sprite)

                checkInterception(sprite, sprite2: sprites)// positioning using a function

                addChild(sprite)
            }

我在这里检查重叠:

func checkInterception(sprite1: SKSpriteNode, sprite2: [SKSpriteNode]) {

        let xPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxX
        let yPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxY
        sprite1.position = CGPoint(x: xPos, y: yPos )

        for index in 0...sprite2.count-1 {

            if sprite1.intersectsNode(sprite2[index]) {

                let yPos = sprite1.position.y + sprite1.size.height
                sprite1.position = CGPoint(x: xPos, y: yPos )
            }
        }
    }

但有些精灵仍然会重叠。我知道 for 循环有些地方不对劲,但就是想不通。

【问题讨论】:

    标签: swift random sprite-kit overlap


    【解决方案1】:

    我相信有几种不同的方法可以解决这个问题,这将是最接近你已经写过的。

    let sprites = [SKSpriteNode]() //loaded with your sprites to spawn
    let maxX  = size.width //whatever your max is
    let maxY  = size.height //whatever your max is
    
    var spritesAdded = [SKSpriteNode]()
    
    for currentSprite in sprites{
    
        addChild(currentSprite)
    
        var intersects = true
    
        while (intersects){
    
            let xPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxX
            let yPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxY
    
            currentSprite.position = CGPoint(x: xPos, y: yPos )
    
            intersects = false
    
            for sprite in spritesAdded{
                if (currentSprite.intersectsNode(sprite)){
                    intersects = true
                    break
                }
            }
        }
    
        spritesAdded.append(currentSprite)
    }
    

    要考虑的事情是,如果您还不知道在哪里可以安全地添加精灵,那么您将面临性能风险。例如,添加最后一个精灵可能需要 1,000,000 次尝试,然后才会随机选择一个不与其他精灵相交的点。

    如果您不必一次将它们全部添加,我会在更新循环上解决问题并执行类似的操作...

    var sprites = [SKSpriteNode]() //loaded with your sprites to spawn
    var maxX : CGFloat = 0.0 //whatever your max is
    var maxY : CGFloat = 0.0 //whatever your max is
    
    var spritesAdded = [SKSpriteNode]()
    
    override func didMoveToView(view: SKView) {
        maxX  = size.width //whatever your max is
        maxY  = size.height //whatever your max is
    }
    
    func addSprite(){
    
        if let currentSprite = sprites.first {
    
            let xPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxX
            let yPos = CGFloat( Float(arc4random()) / Float(UINT32_MAX)) * maxY
    
            currentSprite.position = CGPoint(x: xPos, y: yPos )
    
            for sprite in spritesAdded{
                if (currentSprite.intersectsNode(sprite)){
                    return
                }
            }
    
            addChild(currentSprite)
            spritesAdded.append(currentSprite)
            sprites.removeFirst()
        }
    }
    
    override func update(currentTime: NSTimeInterval) {
        addSprite()
    }
    

    有点粗略,但想法是每次更新都会尝试添加一个精灵。这样,如果您用完房间,它就不会锁定。希望这会有所帮助。

    【讨论】:

    • 内存问题发生在我的或你的函数或两者中?我只在场景开始时使用这种方法一次,这会对性能产生重大影响吗?
    • @Abdou023 这不是内存问题,而是潜在的性能问题。如果您尝试在加载时一次全部添加它们,您可能会获得不同的加载时间,具体取决于它必须获得新的随机位置的次数。如果屏幕上有足够的空间/有很多可能的位置,这没什么大不了的。
    • 好的,使用该功能后发现游戏玩了几轮就卡死了,我做了一些调试,问题很可能是在while循环里面的for循环。请记住,整个游戏在单个场景中运行,当回合结束时,主菜单会出现在游戏运行的同一场景中。
    • @Abdou023 从场景中移除 spritesAdded 数组时,您需要清除它们。猜测这就是您遇到问题的地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多