精靈是創建場景內容的基石,用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