
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 运行效果