iOS游戏框架Sprite Kit技术详解
上QQ阅读APP看书,第一时间看更新

3.6 让精灵更具真实感

做一款让玩家具有身临其境感觉的游戏,是每一个游戏开发者的梦想。那么问题就来了,该如何做才可以让玩家有身临其境的感觉呢?我们可以借鉴一下3D电影的方法,3D电影会有一种让人身临其境的感觉,这是因为3D电影通过3D技术加强了对观众的感官刺激从而增强了真实感。同理对于游戏也一样,也可以通过加强对玩家感官的刺激从而提高游戏的真实感。接下来本节将讲解通过光照效果使游戏中的精灵更具真实感。

为了让精灵更具真实感,SpriteKit这次增加了SKLightNode来作为光源节点。我们可以定义光源的颜色、阴影和衰减程度。SKLightNode继承于SKNode。为了在SKSpriteNode上实现更加逼真的光照效果,SKSpriteNode新增了normalTexture属性来储存原贴图的法线贴图(Normal Map),如图3.31所示。

图3.31 原贴图和原贴图的法线贴图

其中,左侧的是原贴图,中间的是法线贴图。原贴图加上中间的法线贴图就合成出最右侧带有质感的光照纹理。normalTexture属性的语法形式如下:

var normalTexture: SKTexture?

【示例3-15】以下将为显示在场景中的精灵添加光照效果。具体的操作步骤如下:

(1)创建一个Game类型的项目,命名为3-11。

(2)将设备的方向设置为水平方向。

(3)打开GameScene.swift文件,将此文件中多余的代码删除,然后编写新的代码。此代码实现的功能是显示精灵到场景中,并为精灵添加光照。这里我们将编写的代码分为两个部分,第一部分是添加精灵到游戏中,第二部分是添加光照效果。其中,第一部分的代码如下:

import SpriteKit
class GameScene: SKScene {
    override func didMoveToView(view: SKView) {
        backgroundColor=SKColor.blackColor()
        var lily = SKSpriteNode(color: SKColor.whiteColor(), size:
        CGSizeMake(300, 300))                       //实例化精灵
        lily.position = CGPoint(x:500.0, y:400.0)
        self.addChild(lily)
    }
}

此时运行程序,会看到如图3.32所示的效果。

图3.32 运行效果

第二部分是添加光照效果,代码如下:

self.addChild(lily)
var lilyNormMap = lily.texture?.textureByGeneratingNormalMap()
lily.normalTexture = lilyNormMap
lily.lightingBitMask = 1                                            //设置被何种光照亮
lily.name = "Lily Pad"
let lightSprite = SKLightNode()                                     //实例化光源
lightSprite.position = CGPoint(x: 0, y: 0.0)                        //设置光的位置
lightSprite.name = "lightSprite"
lightSprite.categoryBitMask = 1                                     //设置光的种类
self.addChild(lightSprite)

此时运行程序,会看到如图3.33所示的效果。

图3.33 运行效果

注意:由于此时的光源很远,照射不到精灵,所以场景上是漆黑一片。重新设置光源的位置,使其可以照射到精灵上,代码如下:

lightSprite.position = CGPoint(x: 600.0, y: 400.0)

此时运行程序,会看到如图3.34所示的效果。

图3.34 运行效果

SKLightNode的常用的一些属性如表3-2所示。

表3-2 SKLightNode常用属性

【示例3-16】以下以示例3-15为基础,使用lightColor属性将光的颜色改为绿色,代码如下:

import SpriteKit
class GameScene: SKScene {
    override func didMoveToView(view: SKView) {
        backgroundColor=SKColor.blackColor()
        var lily = SKSpriteNode(color: SKColor.whiteColor(), size: 
        CGSizeMake(300, 300))
        ……
        lightSprite.categoryBitMask = 1                         //设置光的种类
        self.addChild(lightSprite)
        lightSprite.lightColor=SKColor.greenColor()         //设置光的颜色
    }
}

此时运行程序,会看到如图3.35所示的效果。

图3.35 运行效果

【示例3-17】以下将以示例3-15为基础,使用ambientColor属性,将环境色改为橘黄色。代码如下:

import SpriteKit
class GameScene: SKScene {
    override func didMoveToView(view: SKView) {
        ……
        lightSprite.position = CGPoint(x: 0.0, y: 0.0)          //设置光的位置
        lightSprite.name = "lightSprite"
        lightSprite.categoryBitMask = 1                         //设置光的种类
        self.addChild(lightSprite)
        lightSprite.ambientColor=SKColor.orangeColor()          //设置环境色
    }
}

此时运行程序,会看到如图3.36所示的效果。

图3.36 运行效果