Sprite kit 我可以使用某种容器节点而不是SKSpriteNode来表示敌人吗?

Sprite kit 我可以使用某种容器节点而不是SKSpriteNode来表示敌人吗?,sprite-kit,skspritenode,Sprite Kit,Skspritenode,我对我的敌人有意见。我拍了5张,每一张都独立出现在一个场景中。但事实是——除了外表,它们几乎是一样的。它们喜欢成群结队地产卵,一个接一个,因为它们对每个人都有一个随机的耳鸣机制。 我试图用SKConstraint在他们之间制造一个缺口,但对我来说不起作用 所以我考虑了不同的方法:我想使用一些东西,比如在敌人出现在场景中之前用一个空节点来表示敌人(它们就像从右侧到左侧的flappy bird中较低的管道)。在它们出现在屏幕上之前,我希望我的游戏在它们的5个节点之间随机选择,并执行正确的动画。正因为

我对我的敌人有意见。我拍了5张,每一张都独立出现在一个场景中。但事实是——除了外表,它们几乎是一样的。它们喜欢成群结队地产卵,一个接一个,因为它们对每个人都有一个随机的耳鸣机制。 我试图用SKConstraint在他们之间制造一个缺口,但对我来说不起作用

所以我考虑了不同的方法:我想使用一些东西,比如在敌人出现在场景中之前用一个空节点来表示敌人(它们就像从右侧到左侧的flappy bird中较低的管道)。在它们出现在屏幕上之前,我希望我的游戏在它们的5个节点之间随机选择,并执行正确的动画。正因为如此,我的小组出现的问题将得到解决

我怎么做呢

现在我使用它们的节点。如果有帮助,我将提供代码:

var robot = SKSpriteNode()
let robotAtlas = SKTextureAtlas(named: "robot")
var robotArray = [SKTexture]()

robotArray.append(robotAtlas.textureNamed("robot0"));
robotArray.append(robotAtlas.textureNamed("robot1"));
然后我给他们做了物理实验

robot = SKSpriteNode(texture: robotArray[0]);
robot.position = CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMidY(self.frame) - 138)
self.robot.name = "robot"
self.addChild(robot)
我该怎么做,或者可能有其他方法来做这样的事情

现在,这是我的计划: 这是随机函数:

func random() -> UInt32 {
var range = UInt32(60)..<UInt32(200)
return range.startIndex + arc4random_uniform(range.endIndex - range.startIndex + 1)}
然后我有一个追踪敌人的状态:

var enemyStatus:Dictionary<String,EnemyAppear> = [:]


enemyStatus["robot"] = EnemyAppear(nowAppear: false, waitToAppear: random(), currentInterval: UInt32(0))
enemyStatus["drone"] = EnemyAppear(nowAppear: false, waitToAppear: random(), currentInterval: UInt32(0))

我所需要的只是设置敌人之间的距离。

我认为你把不必要的事情复杂化了,或者我仍然误解了你:(但这里有一些建议。如果你只是需要随机产生敌人,你可以从以下几种方式中选择:

1.制作定制机器人类

您可以创建一个名为Robot的类,并随机选择不同的纹理。若要实现随机纹理(来自纹理图集或纹理数组),可以使用方法

用法示例(伪代码):

在本例中,Robot类将是SKSpriteNode的子类,您可以通过构造函数(如上面的示例)使用纹理初始化它,或者您可以将所有纹理选择逻辑移动到构造函数(init方法)中。这取决于您

用法示例:

Robot.init()

整个逻辑在init方法中调用,init方法调用SKSpriteNode的方法

如果你真的需要你的机器人有一个骨架和一个皮肤,并且你不能为每种类型的机器人使用单一的纹理,那么你可以创建robot类,它是SKNode(空容器)的子类

在这种情况下,Robot类应该有两个变量,SKSpriteNode skeleton和SKSpriteNode skin。在这种情况下,skin变量将随机选择。骨架和皮肤节点应作为子节点添加到self(在这种情况下,self是Robot类,即SKNode).SKNode没有可视表示,但它具有position属性,因此移动SKNode时,也会移动其子节点

2.使用SKSpriteNode

如果你决定不使用机器人类,只使用SKSpriteNode,故事是一样的。我会为每种类型的敌人使用不同的纹理,但如果这是不可管理的,你可以为每个机器人使用多个SKSpriteNode

所以,你应该创建一个方法,它将返回一个敌人,即SKSpriteNode。在该方法中,你将创建带有骨架纹理的SKSpriteNode,然后你将作为子对象添加蒙皮,将蒙皮的zPosition设置为高于骨架的zPosition,创建物理体并返回该节点

一件有用的事情(如果您只需要更改精灵的颜色)是您可以轻松地(为纹理着色)

编辑:

使用动作序列在随机持续时间后繁殖敌人的简单示例:

import SpriteKit

class GameScene: SKScene {

    var enemies: NSMutableArray = []
    var textures = [SKTexture]()

    let debugLabel = SKLabelNode(fontNamed: "Arial-BoldMT")

    override func didMoveToView(view: SKView) {

        /* Setup your scene here */

        debugLabel.fontColor = SKColor.purpleColor()
        debugLabel.fontSize = 20.0
        debugLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(debugLabel)


        let atlas = SKTextureAtlas(named: "enemies")

        //Fill the array with textures to use them later
        //Not needed IMO, but suitable to show you how to pick a random element from an array
        for var i = 1; i<=atlas.textureNames.count; i++ {

            textures.append(atlas.textureNamed( "enemy\(i)"))

        }


         debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)"

        spawnEnemiesWithDelay(3)

    }


    //This method is just for creating a sprite
    func createRandomEnemy() ->SKSpriteNode{

        let rand = Int(arc4random_uniform(UInt32(textures.count)))

        let enemy =  SKSpriteNode(texture: textures[rand])

        //setup here enemy physics body

        return enemy

    }

    //This method spawns enemies after random period of time. You can stop this by removing an action key
    func spawnEnemiesWithDelay(delay: NSTimeInterval){



        let delay = SKAction.waitForDuration(delay, withRange:3) //The duration may vary in either direction by up to half of the value of the durationRange parameter. Which means duration can vary either plus or minus 1.5 sec



        let block = SKAction.runBlock({

            let enemy = self.createRandomEnemy()

            enemy.position = CGPoint(x: self.frame.size.width+enemy.size.width/2, y:100)

            self.addChild(enemy)

            self.enemies.addObject(enemy) // Store reference to enemy if needed

            let move = SKAction.moveTo(CGPoint(x: -enemy.size.width/2, y: 100), duration: 5)

            let moveAndRemove = SKAction.sequence([move, SKAction.runBlock({
                enemy.removeFromParent()


                self.enemies.removeObjectIdenticalTo(enemy as AnyObject)

            })]) //remove enemy when offscreen



            enemy.runAction(moveAndRemove, withKey: "moving")

        })

        let sequence = SKAction.sequence([delay,block])

        self.runAction(SKAction.repeatActionForever( sequence), withKey: "spawning")

    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

       debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)"

    }
}
导入SpriteKit
类游戏场景:SKScene{
变量:NSMutableArray=[]
var textures=[SKTexture]()
让debugLabel=SKLabelNode(fontname:“Arial BoldMT”)
覆盖func didMoveToView(视图:SKView){
/*在这里设置场景*/
debugLabel.fontColor=SKColor.purpleColor()
debugLabel.fontSize=20.0
debugLabel.position=CGPoint(x:CGRectGetMidX(self.frame),y:CGRectGetMidY(self.frame))
self.addChild(debugLabel)
让atlas=SKTextureAtlas(命名为“敌人”)
//用纹理填充阵列,以便以后使用
//IMO不需要,但适合向您展示如何从数组中选择随机元素
对于var i=1;iSKSpriteNode{
设rand=Int(arc4random_uniform(UInt32(textures.count)))
让敌人=SKSpriteNode(纹理:纹理[rand])
//在这里设置敌人的物理体
还敌
}
//此方法会在随机时间段后生成敌人。您可以通过删除操作键来停止此操作
func spawnEnemiesWithDelay(延迟:NSTimeInterval){
让delay=SKAction.waitForDuration(delay,withRange:3)//持续时间在任意方向上的变化最多为durationRange参数值的一半。这意味着持续时间可以变化正负1.5秒
let block=SKAction.runBlock({
让敌人=自己
敌方.position=CGPoint(x:self.frame.size.width+敌方.size.width/2,y:100)
自我补充儿童(敌人)
self.friends.addObject(敌人)//如果需要,存储对敌人的引用
let move=SKAction.moveTo(CGPoint(x.size.width/2,y:100),持续时间:5)
让moveAndRemove=SKAction.sequence([move,SKAction.runBlock({
敌人。从父对象中移除()
self.friends.removeObjectIdenticalTo(敌人作为任何对象)
})])//在屏幕外清除敌人
敌人。奔跑动作(移动和移动,按键:“移动”)
})
let sequence=SKAction.sequence([延迟,块])
self.runAction(SKAction.repeatActionForever(序列),带有键:“繁殖”)
}
覆盖函数更新(currentTime:CFTimeInterval){
/*在渲染每个帧之前调用*/
debugLabel.text=“敌人数:\(敌人数),节点数:\(self.children.count)”
}
}
如果您的场景和视图已正确初始化,则可以创建敌人.atla
func enemyRun() {
    for(enemy, enemyAppear) in self.enemyStatus {
    var thisPet = self.childNodeWithName(enemy)!
        if enemyAppear.shouldRun() {
            enemyAppear.waitToAppear = random()
            enemyAppear.currentInterval = 0
            enemyAppear.nowAppear = true
        }

        if enemyAppear.nowAppear {
            if thisPet.position.x > petMaxX {
                thisPet.position.x -= CGFloat(self.groundSpeed)
            }else {
                thisPet.position.x = self.originalPetPositionX
                enemyAppear.nowAppear = false
                self.score++
                self.scoreText.text = String(self.score)
            }
        }
    }
Robot.init(texture:someRandomTexture) //note that texture is a type of SKTexture, it's not a string
import SpriteKit

class GameScene: SKScene {

    var enemies: NSMutableArray = []
    var textures = [SKTexture]()

    let debugLabel = SKLabelNode(fontNamed: "Arial-BoldMT")

    override func didMoveToView(view: SKView) {

        /* Setup your scene here */

        debugLabel.fontColor = SKColor.purpleColor()
        debugLabel.fontSize = 20.0
        debugLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(debugLabel)


        let atlas = SKTextureAtlas(named: "enemies")

        //Fill the array with textures to use them later
        //Not needed IMO, but suitable to show you how to pick a random element from an array
        for var i = 1; i<=atlas.textureNames.count; i++ {

            textures.append(atlas.textureNamed( "enemy\(i)"))

        }


         debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)"

        spawnEnemiesWithDelay(3)

    }


    //This method is just for creating a sprite
    func createRandomEnemy() ->SKSpriteNode{

        let rand = Int(arc4random_uniform(UInt32(textures.count)))

        let enemy =  SKSpriteNode(texture: textures[rand])

        //setup here enemy physics body

        return enemy

    }

    //This method spawns enemies after random period of time. You can stop this by removing an action key
    func spawnEnemiesWithDelay(delay: NSTimeInterval){



        let delay = SKAction.waitForDuration(delay, withRange:3) //The duration may vary in either direction by up to half of the value of the durationRange parameter. Which means duration can vary either plus or minus 1.5 sec



        let block = SKAction.runBlock({

            let enemy = self.createRandomEnemy()

            enemy.position = CGPoint(x: self.frame.size.width+enemy.size.width/2, y:100)

            self.addChild(enemy)

            self.enemies.addObject(enemy) // Store reference to enemy if needed

            let move = SKAction.moveTo(CGPoint(x: -enemy.size.width/2, y: 100), duration: 5)

            let moveAndRemove = SKAction.sequence([move, SKAction.runBlock({
                enemy.removeFromParent()


                self.enemies.removeObjectIdenticalTo(enemy as AnyObject)

            })]) //remove enemy when offscreen



            enemy.runAction(moveAndRemove, withKey: "moving")

        })

        let sequence = SKAction.sequence([delay,block])

        self.runAction(SKAction.repeatActionForever( sequence), withKey: "spawning")

    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

       debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)"

    }
}