( 一 ) MY_SpriteKit_创建你的第一个场景

创建你的第一个场景

Sprite Kit 内容被放置在一个窗口中,就像其他可视化内容那样。Sprite Kit 内容由 SKView 类 渲染呈现。SKView 对象渲染的内容称为一个场景,它是一个 SKScene 对象。场景参与响应链, 还有其他使它们适合于游戏的功能。
因为 Sprite Kit 内容由视图对象渲染,你可以在视图层次组合这个视图与其他视图。例如,你可 以使用标准的按钮控件,并把它们放在你的 Sprite Kit 视图上面。或者,你可以添加交互到精灵 来实现自己的按钮,选择权在你。在这个例子中,稍候你会看到如何实现场景交互。

配置视图控制器来使用Sprite Kit

  1. 打开项目的storyboard。它有一个单一的视图控制器(SpriteViewController)。选 择视图控制器的 view 对象并把它的类改成 SKView。
  2. 在视图控制器的实现文件添加一个导入行。
 #import <SpriteKit/SpriteKit.h>
  1. 实现视图控制器的viewDidLoad方法来配置视图。
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * spriteView =(SKView *)self.view;
spriteView.showsDrawCount = YES;
spriteView.showsNodeCount = YES;
spriteView.showsFPS = YES;
 
}
  1. 代码开启了 述场景如何渲染视图的诊断信息。最重要的一块信息是帧率 (spriteView.showsFPS),你希望你的游戏尽可能在一个恒定的帧率下运行。其他行 展示了在视图中显示了多少个节点,以及使用多少绘画传递来渲染内容(越少越好)的详 情。
    接下来,添加第一个场景。

创建Hello场景

  1. 创建一个名为HelloScene新类并让它作为SKScene类的子类。
  2. 在你的视图控制器导入场景的头文件。
 #import “HelloScene.h”
  1. 修改视图控制器来创建场景,并在视图中呈现场景。
- (void)viewWillAppear:(BOOL)animated
{
HelloScene *hello = [[HelloScene alloc] initWithSize:CGSizeMake(768,1024)];
SKView *spriteView =(SKView *)self.view;
[spriteView presentScene:hello];
}

现在,构建并运行项目。该应用程序应该启动并显示一个只有诊断信息的空白屏幕。

将内容添加到场景

当设计一个基于 Sprite Kit 的游戏,你要为你的游戏界面各主要大块(chuck)设计不同的场景类。 例如,你可以为主菜单创建一个场景而为游戏创建另一个单独的场景。在这里,你会遵循类似的 设计。这第一个场景显示了传统的“Hello World”文本。

大多数情况下,你可以配置一个场景在它被视图首次呈现时的内容。这跟视图控制器只在视图属 性被引用时加载他们的视图的方式是类似的。在这个例子中,代码在 didMoveToView:方法内 部,每当场景在视图中显示时该方法会被调用。

在场景中显示Hello文本

  1. 添加一个新的属性到场景的实现文件中来跟踪场景是否已创建其内容。
@interface HelloScene()
@property BOOL contentCreated;
@end

该属性跟踪并不需要向客户端公开的状态,所以,在实现文件中它一个私有接口声明里实 现。

  1. 实现场景的didMoveToView:方法。
- (void)didMoveToView:(SKView *)view {
    if (!self.contentCreated) {
        
        [self createContent];
        
        self.contentCreated = YES;
        
    }
}

每当视图呈现场景时,didMoveToView:方法都会被调用。但是,在这种情况下,场景的 内容应只在场景第一次呈现时进行配置。因此,这段代码使用先前定义的属性 (contentCreated)来跟踪场景的内容是否已经被初始化。

  1. 实现场景的createSceneContents方法。
- (void)createContent {
    
    self.backgroundColor = [SKColor blueColor];
    
    self.scaleMode = SKSceneScaleModeAspectFit;
    
    [self addChild:[self newHelloNode]];
    
}

场景在绘制它的子元素之前用背景色绘制视图的区域。注意使用 SKColor 类创建 color 对 象。事实上,SKColor 不是一个类,它是一个宏,在 iOS 上映射为 UIColor 而在 OS X 上它映射为 NSColor。它的存在是为了使创建跨平台的代码更容易。
场景的缩放(scale)模式决定如何进行缩放以适应视图。在这个例子中,代码缩放视图, 以便你可以看到场景的所有内容,如果需要使用宽屏(letterboxing)。

  1. 实现场景的newHelloNode方法。
- (SKLabelNode *)newHelloNode {
    SKLabelNode * helloNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    
    helloNode.text = @"Hello world";
    
    helloNode.fontSize = 42;
    
    helloNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    
    helloNode.name = @"helloNode";
    
    return helloNode;
}

你永远不用编写显式执行绘图命令的代码,而如果你使用 OpenGL ES 或 Quartz 2D 你就 需要。在 Sprite Kit 中,你通过创建节点对象并把它们添加到场景中来添加内容。所有绘 制必须由 Sprite Kit 中 供的类来执行。你可以自定义这些类的行为来产生许多不同的图 形效果。然而,通过控制所有的绘图,Sprite Kit 可以对如何进行绘图应用许多优化。
现在构建并运行该项目。你现在应该看到一个蓝色屏幕上面有“Hello, World!”。现在,你已经 学会了绘制 Sprite Kit 内容的所有基础知识。

使用动作让场景动起来

静 态 文 本 很 友 好 ,但 如 果 文 字 可 以 动 起 来 ,它 会 更 有 趣 。大 多 数 的 时 候 ,你 通 过 执 行 动 作( a c t i o n ) 移动场景周围的东西。Sprite Kit 中的大多数动作对一个节点应用变化。创建 action 对象来 述你想要的改变,然后告诉一个节点来运行它。然后,当渲染场景时,动作被执行,在几个帧上 发生变化直到它完成。
当用户触摸场景内容,文字动起来然后淡出。

让文本动起来

  1. 添加以下代码到newHelloNode方法:
 helloName.name = @“helloNode”;

所有节点都有一个名称属性,你可以设置它来 述节点。当你想能够在稍后找到它,或当 你想构建基于节点名称的行为时,你应该命名一个节点。稍后,你可以搜索树中与名称相 匹配的节点。
在这个例子中,你给标签的一个名称以便稍后可以找到它。在实际的游戏中,你可能会得 给呈现相同类型的内容的任何节点以相同的名称。例如,如果你的游戏把每个怪物呈现为 一个节点,你可能会命名节点为 monster。

  1. 重载场景类的touchesBegan:withEvent方法。当场景接收到触摸事件,它查找名为 helloNode 的节点,并告诉它要运行一个简短的动画。
    所有节点对象都是 iOS 上 UIResponder 或 OS X 上 NSResponder 的 的子类。这意味着 你可以创建 Sprite Kit 节点类的子类来添加交互到场景中的任何一个节点。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    SKNode * helloNode = [self childNodeWithName:@"helloNode"];
    
    if (nil != helloNode) {
        
        helloNode.name = nil;
        
        // 向上移动
        SKAction * moveUp = [SKAction moveByX:0 y:100.0f duration:0.5];
        
        // 缩放比例
        SKAction * zoom = [SKAction scaleTo:2.0f duration:0.25];
        
        // 暂停
        SKAction * pause = [SKAction waitForDuration:0.5];
        
        // 渐变
        SKAction * fade = [SKAction fadeOutWithDuration:0.25];
        
        // 移除
        SKAction * remove = [SKAction removeFromParent];
        
        // 按顺序执行
        SKAction * moveSequnce = [SKAction sequence:@[moveUp, zoom, pause, fade, remove]];
        
        // 执行动画
        [helloNode runAction:moveSequnce];
        
    }
}

为了防止节点响应重复按压,代码会清除节点的名称。然后,它构建动作对象来执行各种 操 作 。最 后 ,它 组 合 这 些 动 作 创 建 一 个 动 作 序 列 ; 序 列 运 行 时 ,按 顺 序 执 行 每 个 动 作 。最 后 , 它告诉标签节点执行序列动作。
运行的应用程序。你应该看到像之前那样的文字。在屏幕的底部,节点计数应该是 1。现在,点 击视图内部。你应该看到文字动画并淡出。在它淡出后,节点计数应该变为 0,因为节点已从父 节点中移除。

推荐阅读更多精彩内容