- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在我使用的 SpriteKit 游戏中:
self.scene!.removeFromParent()
let skView = self.view! as SKView
skView.ignoresSiblingOrder = true
var scene: PlayScene!
scene = PlayScene(size: skView.bounds.size)
scene.scaleMode = .AspectFill
skView.presentScene(scene, transition: SKTransition.fadeWithColor(SKColor(red: 25.0/255.0, green: 55.0/255.0, blue: 12.0/255.0, alpha: 1), duration: 1.0))
从一个场景移动到另一个场景。可是怎么才能回到原来的场景呢?使用相同的代码原则总是会导致严重的崩溃。
最佳答案
我举了一个例子,其中全局结构用于跟踪关于 previousScene
的信息.它也可以通过自定义属性来完成,或者通过使用每个节点都有的 userData 来完成。逻辑是一样的。此外,我还删除了调试代码(调试标签代码等),因为它对一切正常工作并不重要。
如果我添加几个按钮,每个按钮都链接到特定场景,示例可能会更好,但我只留下一个按钮以尽可能缩短所有内容。
关于此示例您需要了解的内容(您将根据您的游戏更改此规则,但逻辑是相同的 - 在实际转换之前设置 previousScene):
-在您的 GameViewController 中,您应该将 WelcomeScene 设置为默认场景。否则,您应该稍微更改代码以处理未设置 previousScene 时发生的情况(就像我在 WelcomeScene 的 touchesBegan 中所做的那样)。
所以这些是我制定的规则,只是为了让所有这些转换更有意义......
这是代码(BaseScene.swift):
import SpriteKit
enum SceneType: Int {
case WelcomeScene = 0
case MenuScene //1
case GameScene //2
}
struct GlobalData
{
static var previousScene:SceneType?
//Other global data...
}
class BaseScene:SKScene {
let button = SKSpriteNode(color: SKColor.blackColor(), size: CGSize(width: 50, height: 50))
override func didMoveToView(view: SKView) {
setupButton()
}
private func setupButton(){
if (button.parent == nil){
//Just setup button properties like position, zPosition and name
button.name = "goToGameScene"
button.zPosition = 1
button.position = CGPoint(x: CGRectGetMidX(frame), y: 100)
addChild(button)
}
}
func goToScene(newScene: SceneType){
var sceneToLoad:SKScene?
switch newScene {
case SceneType.GameScene:
sceneToLoad = GameScene(fileNamed: "GameScene")
case SceneType.MenuScene:
sceneToLoad = MenuScene(fileNamed: "MenuScene")
case SceneType.WelcomeScene:
sceneToLoad = WelcomeScene(fileNamed:"WelcomeScene")
}
if let scene = sceneToLoad {
scene.size = size
scene.scaleMode = scaleMode
let transition = SKTransition.fadeWithDuration(3)
self.view?.presentScene(scene, transition: transition)
}
}
}
每个场景(WelcomeScene、MenuScene、GameScene)都继承自 BaseScene 类(它是 SKScene 的子类)。我想,没有必要对此进行解释,但如果有什么让您感到困惑,请随时询问。这里的重要方法(每个子类都使用)是 goToScene(scene:SceneType) 及其参数(SceneType 类型),它告诉我们方法应该加载什么类型的场景。
SceneType 只是一个包含整数的枚举...所以实际上我们在这里不使用对象,因此不用担心 strong reference cycles .
接下来还有其他场景(WelcomeScene.swift):
import SpriteKit
class WelcomeScene:BaseScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
self.backgroundColor = SKColor.darkGrayColor()
}
deinit {print ("WelcomeScene deinited")}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
if let location = touch?.locationInNode(self){
//Give a priority to a button - if button is tapped go to GameScene
let node = nodeAtPoint(location)
if node.name == "goToGameScene"{
GlobalData.previousScene = SceneType.MenuScene
goToScene(SceneType.GameScene)
}else{
//Otherwise, do a transition to the previous scene
//Get the previous scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.WelcomeScene
goToScene(previousScene)
}else{
// There is no previousScene set yet? Go to MenuScene then...
GlobalData.previousScene = SceneType.WelcomeScene
goToScene(SceneType.MenuScene)
}
}
}
}
}
为了尽可能简短,所有内容都有注释。下一个代码(MenuScene.swift):
import SpriteKit
class MenuScene: BaseScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
backgroundColor = SKColor.purpleColor()
}
deinit {
print ("MenuScene deinited") //If this method isn't called, you might have problems with strong reference cycles.
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
if let location = touch?.locationInNode(self){
//Give a priority to a button - if button is tapped go to GameScene
let node = nodeAtPoint(location)
if node.name == "goToGameScene"{
GlobalData.previousScene = SceneType.MenuScene
goToScene(SceneType.GameScene)
}else{
//Otherwise, do a transition to the previous scene
//Get the previous scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.MenuScene
goToScene(previousScene)
}
}
}
}
}
最后(GameScene.swift):
import SpriteKit
class GameScene: BaseScene{
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
self.backgroundColor = SKColor.orangeColor()
}
deinit {print ("GameScene deinited")}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//Here, we ignore black button because we don't want to transition to the same scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.GameScene
goToScene(previousScene)
}
}
}
预览:
只要从头再读一遍规则,你就会没事的(例如,在 GameScene 中黑色按钮不起作用,或者在第一次启动时 previousScene 没有设置,所以你将默认转换到 MenuScene)。
就是这样。希望这个对你有帮助。您可以复制并粘贴代码以对其进行测试并根据您的需要对其进行改进。不过,不确定您是否真的需要这个。看起来你只需要 correctly transition between scenes .
提示:这里重要的是每个场景 BaseScene、WelcomeScene... 都有自己的 .sks 文件。您从 File->New->File->Resource 创建它们并适当命名(如 BaseClass.sks、WelcomeScene.sks...)此外,您的工作是维护 GlobalData.previousScene
的状态。变量(例如,在进行转换之前设置它)。
关于swift - 使用 presentScene() 更改 SKScene,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34498982/
我正在尝试制作一个小行星类型的游戏,每次小行星与玩家碰撞时,最终场景都会加载良好,当我尝试重新启动它时,就像代码卡在循环调用最终场景的碰撞函数一样。这是碰撞函数 func didBeginContac
我的问题是,当我尝试使用 self.scene?.presentScene() 移动到下一个场景时,会弹出一条错误消息,提示“presentScene 不是 SKScene 的成员”。 import
我有一个名为 NeighborhoodViewController 的 viewController。它将场景加载到 viewController 中,称为 NeighborhoodScene.sks
在我的程序中,viewController 之间的一些转换是通过以下代码以编程方式管理的: let storyBoard: UIStoryboard = UIStoryboard(name: "Mai
在我使用的 SpriteKit 游戏中: self.scene!.removeFromParent() let skView = self.view! as SKView sk
这段代码出现了一个奇怪的错误。所以基本上我正在尝试转换场景,我已经输入了代码并多次查看了 Apple 的文档。但似乎无法弄清楚这个错误。任何帮助表示赞赏。我只是想简单地从场景 1 过渡到场景 2。我非
我是 Swift 和 SpriteKit 的新手,所以不确定我是否能正确处理不同的屏幕和场景。 在此屏幕上,您可以选择级别: class GameScene : SKScene let
我正在尝试从一个场景过渡到另一个场景,但是当我调用 presentScene 时发生崩溃!场景未存储在类中或被引用,它们直接加载到 presentScene 调用中。 Xcode 崩溃截图: 我的简单
我正在尝试切换场景,但我的应用程序崩溃并出现此错误: crash crash fatal error: unexpectedly found nil while unwrapping an Optio
我是一名优秀的程序员,十分优秀!