精灵是创建场景内容的基石,用SKSpriteNode表示。美工创建好图像,游戏内加载图像作为纹理,然后使用纹理创建精灵并添加到场景中。
本文使用的是Xcode8.0,语言是Swift3.0。
1 创建精灵
最简单的利用图片创建精灵方式:
let ship = SKSpriteNode(imageNamed: "Spaceship")
ship.position = view!.center
addChild(ship)
如下:
这种方式创建的精灵,有很多默认的行为:
- 精灵的尺寸和图片的size相同
- 精灵以图片的中心位置来渲染
- 精灵在帧缓冲区中是半透明的
- 一个SKTexture对象被创建并附加到了精灵上。
2 定制精灵
精灵从创建到呈现到界面,会经过四个阶段:定位、调整尺寸、着色、混合,这四个阶段我们都是可以通过修改精灵的属性来进行控制的。
2.1 使用锚点移动精灵的frame
精灵的anchorPoint属性决定frame的哪一点定位在精灵的位置上,锚点在单位坐标系中指定,单位坐标系如下:
设置锚点:
//使用锚点,移动ship,锚点范围0--1,默认为(0.5, 0.5)
ship.anchorPoint = CGPoint(x: 0.5, y: 1)
指定锚点后,如果对精灵进行旋转,则会围绕着锚点旋转,如下:
//旋转90度
ship.zRotation = CGFloat(M_PI_2)
2.2 调整尺寸
精灵的尺寸有它的三个属性决定的:
- size属性是精灵的基准尺寸,该值和纹理的尺寸相等。
- xScale与yScale属性,对基准尺寸进行缩放。
//使用Scale属性对精灵进行缩放
ship.xScale = 0.3
ship.yScale = 0.3
如下:
2.3 着色
纹理应用到精灵之前,可以使用color和colorBlendFactor进行着色,color决定颜色,colorBlendFactor属性是混合因子,默认为0。如下,我们给飞船添加一个红色色调:
//使用color和colorBlendFactor属性对精灵进行着色,默认混合因子colorBlendFactor为0
ship.color = SKColor.red
ship.colorBlendFactor = 0.5
如图:
添加一个颜色变化的动画:
//颜色动画
let pulseRed = SKAction.sequence([SKAction.colorize(with: SKColor.red, colorBlendFactor: 0.5, duration: 0.2),
SKAction.wait(forDuration: 0.1),
SKAction.colorize(withColorBlendFactor: 0, duration: 0.1)])
ship.run(SKAction.repeatForever(pulseRed))
2.4 混合精灵到帧缓冲区
渲染的最终阶段是把精灵的纹理混合到目标帧缓冲区,默认是使用纹理的alpha值混合纹理与目标像素,但是,当想添加其它特效到场景时,可以使用其它混合模式。可以使用BlendMode属性来控制精灵的混合行为:
//使用BlendMode属性控制精灵混合行为
ship.blendMode = .add
3 使用纹理对象
虽然我们可以用上面的方法一个一个的创建精灵,但是,假如有很多精灵共用一个图像时,使用使用图像创建出纹理,然后通过纹理创建精灵是更好的方式,使用纹理创建的好处是不用每次都去bundle加载图像,只需要加载一次到纹理中即可。
我们给场景添加一个功能,当点击某一点时,在该点生成一架飞船,再次点击时,上一次生成的飞船往下掉,知道飞出屏幕,代码如下:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
addTextureShip(touch!)
}
func addTextureShip(_ touch: UITouch) {
//使用小部分纹理,我们可以在原纹理的基础上,只使用其中的某一部分
let texture = SKTexture(rect: CGRect(x: 0, y: 0.5, width: 1.0, height: 0.5), in: shipTexture)
let ship = SKSpriteNode(texture: texture, size: CGSize(width: 40, height: 40))
ship.position = touch.location(in: self)
ship.name = "Ship"
ship.zRotation = CGFloat(M_PI)
enumerateChildNodes(withName: "Ship") { (node, _) in
let current = node as! SKSpriteNode
if current.physicsBody == nil {
current.physicsBody = SKPhysicsBody(rectangleOf: current.size)
}
}
addChild(ship)
}
override func didSimulatePhysics() {
enumerateChildNodes(withName: "Ship") { (node, _) in
if node.position.y < 0 {
node.removeFromParent()
}
}
}
最终效果:
结语
本文学习了精灵的创建,修改等操作,精灵是游戏的基石。
本文代码(game02):https://github.com/flywo/SwiftGame