【发布时间】:2014-08-05 11:37:37
【问题描述】:
我用 sprite kit 创建了一个游戏,但在游戏启动的那一刻,它直接进入游戏。我如何实现不同的场景,如主菜单和游戏结束场景,并通过按屏幕上的标签或在游戏期间通过联系人在它们之间进行转换。
【问题讨论】:
-
我很快就解决了这个问题,你可以在底部找到一些代码。
标签: swift sprite-kit transition
我用 sprite kit 创建了一个游戏,但在游戏启动的那一刻,它直接进入游戏。我如何实现不同的场景,如主菜单和游戏结束场景,并通过按屏幕上的标签或在游戏期间通过联系人在它们之间进行转换。
【问题讨论】:
标签: swift sprite-kit transition
创建一个名为 MainMenu.swift 的新 swift 文件
以下代码放置在您当前的场景中将允许转换到 MainMenu.swift 中描述的场景:
var scene = MainMenu(size: self.size)
let skView = self.view! as SKView
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
在新场景中,您可以使用以下代码回到 GameScene.swift 中描述的场景:
var scene = GameScene(size: self.size)
let skView = self.view! as SKView
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
【讨论】:
我迅速解决了这个问题。
func goToGameScene(){
let gameScene:GameScene = GameScene(size: self.size) // create your new scene
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 0) // create type of transition (you can check in documentation for more transtions)
gameScene.scaleMode = SKSceneScaleMode.AspectFill
self.view!.presentScene(gameScene, transition: transition)
}
【讨论】:
创建一个名为:TestScene.Swift 的文件
在你的 GameScene.Swift 文件中声明它并像这样实现 touches 函数:
var sceneTest: TestScene!
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
// Configure the view.
let gameView = self.view as SKView!
/* Sprite Kit applies additional optimizations to improve rendering performance */
gameView.ignoresSiblingOrder = true
sceneTest = TestScene(size: gameView.bounds.size)
gameView.presentScene(sceneTest)
sceneTest.scaleMode = .AspectFill
}
这将呈现一个名为 TestScene 的新场景
【讨论】:
您似乎没有查看过 Apple 的文档。他们有一个很好的 SpriteKit 指南。此外,RayWenderlich.com 上 spriteKit 类别中的教程也非常出色。我还没有深入了解 Swift,但我的理解是 Swift 可以与 Objective-C 一起编写。话虽如此,我会给你一个起点(在 Objective-C 中)。
1) 调用初始场景:
在您的主视图控制器中,您需要将 VC 的 view 属性转换为 SKView 内的 SKView,如下所示:
SKView *spriteKitView = (SKView *)self.view;
SKView 上的一些有用的调试属性:
spriteKitView.showsFPS = YES;
spriteKitView.showsNodeCount = YES;
spriteKitView.showsPhysics = YES;
您必须单独配置每个场景(子类SKScene)。完成此操作后,将主场景导入主 VC 的类实现。呈现主要场景(仍在viewDidLoad):
MyScene *mainScene = [MyScene new];
[spriteKitView presentScene: mainScene];
2) 通过标签(或任何其他SKNode)在场景之间转换:
将相关节点设置为属性并通过以下方式呈现新场景:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
if ([self.playAgainButton containsPoint:touchLocation]) {
[self presentGamePlayScene];
} else if([self.mainMenuButton containsPoint:touchLocation]) {
[self presentMainMenu];
}
}
- (void)presentGamePlayScene {
gamePlayScene *newGamePlay = [[gamePlayScene alloc]init];
newGamePlay.scaleMode = SKSceneScaleModeAspectFill;
SKTransition *arbitraryTransition = [SKTransition crossFadeWithDuration:2.0]; //look into SKTransition for a plethora of different options.
[self.view presentScene:newGamePlay transition:arbitraryTransition];
}
3) 要通过联系人更改场景,请在任何给定的SKScene 内遵守协议SKPhysicsContactDelegate。在该场景的实现中:
- (void)didBeginContact:(SKPhysicsContact *)contact {
if(contact.bodyA.categoryBitMask == enemyCategory && contact.bodyB.categoryBitMask == arbitraryNodeCategory) {
[self presentGameOverScene];
}
}
SKPhysicsContact 有 2 个碰撞 SKPhysicsBodys 通过属性附加到它。这些冲突节点必须初始化它们的SKPhysicsBody。此外,他们必须在SKPhysicsBody 上设置contactBitMask 属性,如下所示:
@implementation SomeNode
- (instanceType)initCollidingNode {
if(self = [super init]) {
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.someSize];
self.physicsBody.contactBitMask = enemyCategory | powerUpCategory;
self.physicsBody.categoryBitMask = arbitraryNodeCategory;
self.physicsBody.dynamic = YES
}
return self;
}
【讨论】: