在子类 SKSpriteNode 中创建 SKSpriteNode 是一种好习惯吗?

is it a good practice to create an SKSpriteNode within a subclassed SKSpriteNode?

这里的代码继承了 SKSpriteNode 并初始化它接受 SKScene

import SpriteKit

class Spaceship: SKSpriteNode{

var spaceship:SKTexture
var hitpoint = 100
var thescene:SKScene

var lazer5:SKSpriteNode?
var lazer5_pathofdestruction:SKSpriteNode?

init(skScene:SKScene) {

    thescene = skScene
    self.spaceship  = SKTexture(imageNamed:"Spaceship")
    super.init(texture: spaceship, color: SKColor.clearColor(), size: spaceship.size())
    self.name = "Spaceship"
    self.setScale(0.10)
    self.position =  CGPointMake(CGRectGetMidX(skScene.frame), CGRectGetMidY(skScene.frame))

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
.......

这个Class(宇宙飞船)有一个可以发射双炮的方法:

 func firedualcanon() {

    let canonposition = [10.00 , -10.00]
    let fireSound = SKAction.playSoundFileNamed("dualcanon.wav", waitForCompletion: false)
    let targeting = SKAction.sequence([


        SKAction.runBlock{

            for position in canonposition {

                let canon = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width:4, height: 3))
                canon.name = "weapon"
                canon.position = CGPointMake(self.position.x - CGFloat(position), self.position.y)
                let projectile = SKAction.moveTo(CGPoint(x: self.position.x - CGFloat(position), y: self.thescene.frame.height + 200 ),duration: 1.50)

                GlobalReference.setPhysicsBody(canon,collidertype: GlobalVariable.ColliderType.Light)

                self.thescene.addChild(canon)
                let bulletaction = SKAction.sequence([projectile,SKAction.removeFromParent()])
                canon.runAction(bulletaction)

            }


        }


        , SKAction.waitForDuration(0.10)

        ])

    self.thescene.runAction(
        SKAction.repeatActionForever(SKAction.group([fireSound,targeting])),
        withKey: "fireweapons")



}

正如您在初始化中看到的那样,我使用了 SKTexture,但现在在 firedualcanon() 方法中,我使用 SKSpriteNode 创建了一个佳能。

这是一个很好的Swift编程实践吗?

编写基于 sprite 的游戏时,让您的游戏对象成为 sprite class 的子class(或更通用的节点),甚至在 Swift 和 SpriteKit 之前(例如 Cocos2d/Objective-C)。

一些纯粹主义者可能会争辩说您应该解耦 model(数据)、views(sprites)和 controllers (游戏逻辑)分成单独的对象,但在简单的游戏中,这可能导致拥有大量 classes,每个对象的作用很小。

在我看来,这实际上是关于偏好以及什么对您的特定应用来说方便)

如果您仍然希望朝那个方向前进,您可以让每个对象的 logic/state 由非 SpriteKit class 表示(例如,Swift root class或 NSObject 的子 class),每个对象都以某种方式链接到屏幕上代表它的精灵(引用、唯一 ID 等),细节由您决定。

然后,在每一帧上,根据它们所代表的模型对象(例如,"spaceship")的逻辑(游戏)状态更新每个精灵的视觉状态(位置等)。

希望它有意义。

我同意 NicolasMiari 的观点。这取决于您的特定游戏,但通常有一个 SKNode class 包含一个、两个或多个 SKSpriteKitNode 以正确表示它。例如,如果您的宇宙飞船可以将一个小型宇宙飞船作为卫星,并具有特定的动作、动画、碰撞等,会怎样?在这种情况下,将其作为单独的精灵更容易。