我的GameManager看起来像这样,有一个对每个场景的引用,这是静态的:
import SpriteKit class GM { static let scene2 = SecondScene() static let scene3 = ThirdScene() static let home = SKScene(fileNamed: "GameScene") }
如何以编程方式创建SKScene,没有大小信息,因为它们位于SKScene的子类中,并且不知道视图大小是什么,我不希望他们需要担心这个:
我这样做,但在方便时获得EXC_BAD_Access覆盖init()
class SecondScene: SKScene { override init(size: CGSize){ super.init(size: size) } convenience override init(){ self.init() self.backgroundColor = SKColor.red self.anchorPoint = CGPoint(x: 0.5,y: 0.5) } }
解决方法
在开始之前,让我们区分调用它
let scene = StartScene(size: ...)
还有这个
let scene = SKScene(fileNamed: "StartScene")
第一种方法,大小,是在代码中创建场景时,并且您没有使用xCode可视级别编辑器.
第二种方法是在使用Xcode级别编辑器时,因此您需要创建一个StartScene.sks文件.它在fileNamed中查找的.sks文件.
现在对于一些游戏经理的例子,让我们首先想象我们有3个SKScenes.
class StartScene: SKScene { override func didMove(to view: SKView) { ... } } class GameScene: SKScene { override func didMove(to view: SKView) { ... } } class GameOverScene: SKScene { override func didMove(to view: SKView) { ... } }
假设您想要从StartScene过渡到GameScene,您可以在StartScene中将此代码添加到正确的位置,例如按下播放按钮时.这是从SKScene本身直接从SKScene转移到下一个SKScene的最简单方法.
// Code only,no xCode level editor let gameScene = GameScene(size: CGSize(...)) let transition = SKTransition... gameScene.scaleMode = .aspectFill view?.presentScene(gameScene,transition: transition) // With xCode level editor (returns an optional so needs if let // This will need the GameScene.sks file with the correct custom class set up in the inspector // Returns optional if let gameScene = SKScene(fileNamed: "GameScene") { let transition = SKTransition... gameScene.scaleMode = .aspectFill view?.presentScene(gameScene,transition: transition) }
现在有一些GameManagers的实际例子,我相信你已经知道了其中的一些.
例1
让我们说我们想要一个场景加载管理器.使用静态方法的方法不起作用,因为当你转换为一个时,需要创建一个新的SKScene实例,否则像敌人这样的东西不会重置.使用静态方法的方法意味着每次都使用相同的实例,这是不好的.
我个人使用协议扩展.
创建一个新的.swift文件并将其称为SceneLoaderManager或其他内容并添加此代码
enum SceneIdentifier: String { case start = "StartScene" case game = "GameScene" case gameOver = "GameOverScene" } private let scenesize = CGSize(width: ...,height: ...) protocol SceneManager { } extension SceneManager where Self: SKScene { // No xCode level editor func loadScene(withIdentifier identifier: SceneIdentifier) { let scene: SKScene switch identifier { case .start: scene = StartScene(size: scenesize) case .game: scene = GameScene(size: scenesize) case .gameOver: scene = GameOverScene(size: scenesize) } let transition = SKTransition...\ scene.scaleMode = .aspectFill view?.presentScene(scene,transition: transition) } // With xCode level editor func loadScene(withIdentifier identifier: SceneIdentifier) { guard let scene = SKScene(fileNamed: identifier.rawValue) else { return } scene.scaleMode = .aspectFill let transition = SKTransition... view?.presentScene(scene,transition: transition) } }
现在在3个场景中符合协议
class StartScene: SKScene,SceneManager { ... }
并使用3个枚举案例中的1个作为场景标识符来调用这样的加载方法.
loadScene(withIdentifier: .game)
例2
让我们使用Singleton方法为游戏数据制作游戏经理课程.
class GameData { static let shared = GameData() private init() { } // Private singleton init var highscore = 0 func updateHighscore(forscore score: Int) { guard score > highscore else { return } highscore = score save() } func save() { // Some code to save the highscore property e.g UserDefaults or by archiving the whole GameData class } }
现在你可以说项目的任何地方
GameData.shared.updateHighscore(forscore: SOMEscore)
您倾向于将Singleton用于只需要1个类实例的事物. Singleton类的一个很好的用法示例是诸如Game Center的助手类,InAppPurchases,GameData等.
例3
用于存储所有场景中可能需要的某些值的通用助手.这使用类似于您尝试的静态方法方法.我喜欢将它用于诸如游戏设置之类的东西,以便将它们放在一个很好的集中位置.
class GameHelper { static let enemySpawnTime: TimeInterval = 5 static let enemyBossHealth = 5 static let playerSpeed = ... }
在场景中使用它们就像这样
... = GameHelper.playerSpeed
例4
管理SKSpriteNodes的类,例如敌人
class Enemy: SKSpriteNode { var health = 5 init(imageNamed: String) { let texture = SKTexture(imageNamed: imageNamed) super.init(texture: texture,color: SKColor.clear,size: texture.size()) } func reduceHealth(by amount: Int) { health -= amount } }
在场景中,您可以使用此助手类创建敌人并调用其上的方法和属性.通过这种方式,您可以轻松添加10个敌人并单独管理他们的健康状况等
let enemy1 = Enemy(imageNamed: "Enemy1") let enemy2 = Enemy(imageNamed: "Enemy2") enemy1.reduceHealth(by: 3) enemy2.reduceHealth(by: 1)
这是一个巨大的答案,但我希望这有帮助.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。