随机生成 SKSpriteNode 对象

Spawn SKSpriteNode objects at random times

我正在制作一款游戏,我想在其中随机生成障碍物。障碍物将与玩家接触。

这是我的代码:

var obstacle : SKSpriteNode?

func createObstacles() {
let obstaclesArray = ["obstacle_1", "obstacle_2", "obstacle_3", "obstacle_4", "obstacle_5"]
let randomObs = obstaclesArray.randomElement()
let selectedTexture = SKTexture(imageNamed: randomObs!)
obstacle = SKSpriteNode(imageNamed: randomObs!)
obstacle?.physicsBody = SKPhysicsBody(texture: selectedTexture, size: selectedTexture.size())
obstacle?.position = CGPoint(x: scene!.size.width/2 + selectedTexture.size().width, y: -120)
obstacle?.zPosition = -15
if let obs = obstacle?.physicsBody {
obs.affectedByGravity = true
obs.allowsRotation = false
obs.isDynamic = true
obs.restitution = 0
obs.categoryBitMask = obstacleCategory
obs.collisionBitMask = floorCategory
obs.contactTestBitMask = heroCategory
}
addChild(obstacle!)
}

func spawnObstacles() {
let wait = SKAction.wait(forDuration: 1, withRange: 0.4)
let spawn = SKAction.run {
createObstacles()
}
let moveLeft = SKAction.moveBy(x: -scene!.size.width - obstacle.size.width - 10, y: 0, duration: 2)
let sequence = SKAction.sequence([wait, spawn, moveLeft, SKAction.removeFromParent()])
self.run(SKAction.repeatForever(sequence))
}

我阅读了一些类似的问题,但响应是我的相同代码,但它不起作用。 Spawning a Spritekit node at a random time

我也试过其他方法:

var randDelay = Double.random(in: 0.7 ..< 1.4)
DispatchQueue.main.asyncAfter(deadline: randDelay, execute: {
    if self.canCreateObstacle == true {
    self.spawnObstacle()
    }})

但它不起作用,每次我重新启动游戏时,该函数似乎被调用了两次,如果我第三次重新启动游戏,它被调用了 3 次,依此类推。

谁有好的、干净的随机生成对象的解决方案?

不要像以前那样使用 DispatchQueue 使用 wait(forDuration:withRange:) 设置重复顺序操作。

https://developer.apple.com/documentation/spritekit/skaction/1417760-wait

首先,创建一个用于生成障碍物的通用节点,然后将此通用节点附加到场景中。
最后将重复的顺序动作分配给该节点。 砰,你完成了。

之所以要将其分配给随机节点是因为您希望能够让您的游戏有机会停止生成障碍物,再加上您改变速度 属性 使节点生成节点更快或更慢。

您还想将 spawning/waiting 与 moving/destroying 分离,因为到目前为止,您的代码很混乱。你说的是将场景向左移动 2 秒,然后等待一段随机的时间来生成下一个敌人,但我认为你只是想在一个时间间隔内生成敌人并将敌人移动到左边。

您的场景代码应如下所示

class GameScene : SKScene{
    let obstacleGenerator = SKNode()
    func didMove(to: view){


        let wait = SKAction.wait(forDuration: 1, withRange: 0.4)
        let spawn = SKAction.run({createObstacles()})

        let sequence = SKAction.sequence([wait, spawn])
        obstacleGenerator.run(SKAction.repeatForever(sequence))
        addChild(obstacleGenerator)

    }

    func createObstacles() {
        let obstaclesArray = ["obstacle_1", "obstacle_2", "obstacle_3", "obstacle_4", "obstacle_5"]
        let randomObs = obstaclesArray.randomElement()
        let selectedTexture = SKTexture(imageNamed: randomObs!)
        obstacle = SKSpriteNode(imageNamed: randomObs!)

        obstacle.position = CGPoint(x: scene!.size.width/2 + selectedTexture.size().width, y: -120)
        obstacle.zPosition = -15
        let body = SKPhysicsBody(texture: selectedTexture, size: selectedTexture.size())
        body.affectedByGravity = true
        body.allowsRotation = false
        body.isDynamic = true
        body.restitution = 0
        body.categoryBitMask = obstacleCategory
        body.collisionBitMask = floorCategory
        body.contactTestBitMask = heroCategory
        obstacle.physicsBody = body
        addChild(obstacle!)
        let moveLeft = SKAction.moveBy(x: -scene!.size.width - obstacle.size.width - 10, y: 0, duration: 2)
        let seq = SKAction.sequence([moveLeft,SKAction.removeFromParent()])
        obstacle.run(seq)
    }
}

现在至于每次重置都会增加产卵量,您永远不会post如何重置。我假设您在重置时永远不会删除之前的操作,这就是您的费率增加的原因。重置时最好只创建一个新的 GameScene 实例。