[原創]Swift+Sprite Kit中文教程第一篇

敲鍵盤的貓發表於2014-12-02

本教程適用於入門開發者,我將會告訴你如何最快開發出小遊戲,但所使用的未必是最佳方案。本教程將使用純swift+storyboard進行開發,所以最好有一點點這兩種技術的基礎。

新建專案:

1.左側選iOS,右側選Game
2.語言Swift,技術Spritekit。

清理乾淨

刪除GameScene.sks檔案,目前我建議使用純程式碼實現。
開啟GameViewController.swift,刪除extension SKNode擴充套件,大概十幾行,這個是用來載入sks檔案的。
然後進入viewDidLoad方法,將if let scene = ...這行改為let scene = GameScene(size:CGSizeMake(1334, 750))。我們不使用sks檔案來載入場景,而是直接用GameScene類初始化了一個場景例項。

建立精靈

進入GameScene.swift檔案,幹掉didMoveToView和touchesBegan裡的所有程式碼。註釋寫的比較清楚了,前者是一個view首次載入好並放到螢幕上的瞬間,會呼叫到的一個函式,在這裡,你可以放所有你準備展示在玩家面前的內容(載入遊戲內容)。後者是玩家點選螢幕的時候,會呼叫的一個函式(處理玩家操作)。以下簡稱load和touch
首先,在load中加入如下程式碼:

var plane = SKSpriteNode(imageNamed: "Spaceship")//可以在Assets中找到預設飛船圖片
plane.position = CGPointMake(size.width * 0.5,size.height * 0.5)//self是指當前場景,左下角為座標原點
addChild(plane) //新增精靈到場景中

可以執行一下,我們會發現螢幕中央多了一個飛機。

座標系相關內容請參考這裡

使用紋理

遊戲中會用到很多素材,如果有多個相同的精靈,可以共用一套紋理,這樣可以提高遊戲執行效率。
在load中,初始化plane之前,新增如下程式碼:
var planeTexture = SKTexture(imageNamed: "Spaceship")
var plane = SKSpriteNode(imageNamed: "Spaceship")修改為var plane = SKSpriteNode(texture: planeTexture)
很簡單吧,這樣我們就使用了紋理技術來建立一個精靈。

紋理縮放

飛機好像太大了點,我們進入到Assets圖片集裡,選擇spaceShip,將1x裡的圖拖拽到2x裡,這樣表示圖片是支援retina2x的,在遊戲中使用時長寬會被自動縮小一半,以顯示出非常好的效果。
但是,執行一下會發現,好像飛機還是有點大,下面我們說一下如何縮放(你也可以試試將圖片放在3x裡,這是6+的螢幕規格)。

plane.xScale是橫軸縮放值
plane.yScale是縱軸縮放值
plane.setScale()同時設定橫軸縱軸

下面,在addChild呼叫之前,設定:plane.setScale(0.5),好了,你會發現飛機長寬被縮小了一半。

處理操作

我們要開始控制飛機飛行了。因為支援多點觸控,所以觸控時螢幕會收到一個觸控點集合(即使只有一個點),裡面包含每個觸控點的資料。不過我們暫時只關心單點觸控,也就是隻處理集合中的第一個點的資料。
首先,在集合中取出一個點,在touch中加入:
let location:CGPoint! = touches.first?.locationInNode(self)
這就從場景節點中取出了玩家所觸控的位置座標,然後我們找出這個座標所在位置的某個node,這樣就可以判斷我們是否點選到了飛機。為了方便判斷,我們在addChild之前,設定飛機的名字為plane,給它貼上一個標籤
plane.name = "plane"
然後,回到touch方法中,繼續在下面加入:

var node = self.nodeAtPoint(location)
if node.name == "plane"{
    //you choose the plane
}

然後,我們需要兩個新的函式,touchesMove和touchesEnded,前者在觸控並移動時觸發,後者在觸控操作結束之後觸發。同時,需要在類裡新增一個成員屬性isTouched,型別是bool,然後在update函式中,實時修改飛機座標。最終程式碼如下:

class GameScene: SKScene {
    var planeTexture = SKTexture(imageNamed: "Spaceship")//可以在Images.xcassets中找到預設飛船圖片
    var plane:SKSpriteNode!
    var isTouched = false
    
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        plane = SKSpriteNode(texture: planeTexture)
        
        plane.position = CGPointMake(self.size.width * 0.5, self.size.height * 0.5)//self是指當前場景,左下角為座標原點
        plane.setScale(0.5)
        plane.name = "plane"
        self.addChild(plane)
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        /* Called when a touch begins */
        
        var location:CGPoint! = touches.anyObject()?.locationInNode(self)
        var node = self.nodeAtPoint(location)
        
        if node.name == "plane" {
            isTouched = true// 手指點選到飛機
        }
        
    }
    
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if isTouched {
            var location:CGPoint! = touches.anyObject()?.locationInNode(self)
            plane.position = CGPointMake(location.x, location.y)
        }
        
    }
    
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        isTouched = false
    }
    
    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
} 

GameViewController的viewDidLoad程式碼如下:

override func viewDidLoad() {
    super.viewDidLoad()

    let scene = GameScene(size: CGSizeMake(750, 1334))
    // Configure the view.
    let skView = self.view as! SKView
    skView.showsFPS = true
    skView.showsNodeCount = true
    
    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = true
    
    /* Set the scale mode to scale to fit the window */
    scene.scaleMode = .AspectFill
    
    skView.presentScene(scene)
}

現在,你可以在模擬器裡,四處拖拽飛機進行移動了。

下一篇

相關文章