iOS SpriteKit - SKNode

關(guān)聯(lián)章節(jié)
iOS SpriteKit 文檔
iOS SpriteKit - Scene

基礎(chǔ)節(jié)點(diǎn)

為場景中顯示的所有事物提供參考咐低,觀點(diǎn)或基礎(chǔ)猾瘸。

使用基本節(jié)點(diǎn)布置SpriteKit內(nèi)容

使用非可視節(jié)點(diǎn)定義場景的布局锋叨。


總覽

SpriteKit中的每個(gè)屏幕元素都稱為一個(gè)節(jié)點(diǎn)民珍。 節(jié)點(diǎn)是視覺元素或其他節(jié)點(diǎn)的容器碘裕。 通過以分層形式在節(jié)點(diǎn)的頂部和底部添加節(jié)點(diǎn),可以設(shè)置SpriteKit場景的外觀扇商。 總的來說毒姨,此結(jié)構(gòu)稱為節(jié)點(diǎn)樹或節(jié)點(diǎn)層次結(jié)構(gòu)。

這些是SpriteKit中的基本非可視節(jié)點(diǎn):

  • SKNode是一個(gè)容器節(jié)點(diǎn)溶浴。 它不呈現(xiàn)其自身的任何內(nèi)容乍迄,而是用作其子節(jié)點(diǎn)的布局工具。
  • SKReferenceNode并未定義其自身的內(nèi)容,而是引用了其他定義的內(nèi)容或歸檔文件沾瓦。
  • SKCameraNode定義場景內(nèi)的視點(diǎn)。 它的反比例適用于層次結(jié)構(gòu)中除其子元素之外的所有節(jié)點(diǎn)疹瘦。 將SKCameraNode的子級(jí)用于應(yīng)該不受縮放級(jí)別影響的UI元素生蚁。
    有關(guān)視覺元素的列表噩翠,請(qǐng)參見Nodes that Draw,其中還包括一些使用視覺節(jié)點(diǎn)的示例邦投。

SKNode

所有SpriteKit節(jié)點(diǎn)的基類伤锚。

@interface SKNode : UIResponder

SKNode為其子類提供基本屬性,并且可以用作其他節(jié)點(diǎn)的容器或布局工具志衣。 例如屯援,您可以將一組節(jié)點(diǎn)作為子節(jié)點(diǎn)添加到一個(gè)在場景中一起移動(dòng)的SKNode上。 因?yàn)楣?jié)點(diǎn)繼承了其父節(jié)點(diǎn)的屬性念脯,所以更改父節(jié)點(diǎn)的位置也會(huì)將更改傳播到其子節(jié)點(diǎn)狞洋。

SKNode本身不會(huì)繪制任何內(nèi)容。 它的視覺對(duì)應(yīng)項(xiàng)在“Nodes that Draw”中列出绿店。

從基礎(chǔ)節(jié)點(diǎn)SKNode開始

了解為所有其他節(jié)點(diǎn)提供的基礎(chǔ)屬性

節(jié)點(diǎn)按層次結(jié)構(gòu)組織到節(jié)點(diǎn)樹中吉懊,類似于視圖和子視圖的工作方式。 最常見的是假勿,將節(jié)點(diǎn)樹定義為場景節(jié)點(diǎn)(SKScene)作為根節(jié)點(diǎn)借嗽,而其他內(nèi)容節(jié)點(diǎn)作為后代。 場景節(jié)點(diǎn)運(yùn)行一個(gè)動(dòng)畫循環(huán)转培,該循環(huán)處理節(jié)點(diǎn)上的動(dòng)作恶导,模擬物理學(xué)并渲染節(jié)點(diǎn)樹的內(nèi)容以進(jìn)行顯示。

節(jié)點(diǎn)樹中的每個(gè)節(jié)點(diǎn)都為其子節(jié)點(diǎn)提供一個(gè)坐標(biāo)系浸须。 將子級(jí)添加到節(jié)點(diǎn)樹后惨寿,可以通過設(shè)置其zPosition屬性將其放置在其父級(jí)的坐標(biāo)系內(nèi)。 可以通過更改節(jié)點(diǎn)的xScale删窒,yScalezRotation屬性來縮放和旋轉(zhuǎn)其坐標(biāo)系裂垦。 當(dāng)縮放或旋轉(zhuǎn)節(jié)點(diǎn)的坐標(biāo)系時(shí),此變換既應(yīng)用于節(jié)點(diǎn)自身的內(nèi)容肌索,也應(yīng)用于其后代的內(nèi)容缸废。

重要的屬性

SKNode類不執(zhí)行其自身的任何繪制。但是驶社,許多SKNode子類呈現(xiàn)可視內(nèi)容企量,因此SKNode類理解一些可視概念:

  • frame屬性為節(jié)點(diǎn)的視覺內(nèi)容提供了邊界矩形,并通過scalerotation屬性對(duì)其進(jìn)行了修改亡电。如果節(jié)點(diǎn)的類繪制內(nèi)容届巩,則該屬性為非空。每個(gè)節(jié)點(diǎn)子類都會(huì)以不同方式確定此內(nèi)容的大小份乒。在某些子類中恕汇,節(jié)點(diǎn)內(nèi)容的大小是明確聲明的腕唧,例如在SKSpriteNode類中。在其他子類中瘾英,內(nèi)容大小由該類使用其他對(duì)象屬性隱式計(jì)算枣接。例如,SKLabelNode對(duì)象使用標(biāo)簽的消息文本和字體特征確定其內(nèi)容大小缺谴。
  • 通過調(diào)用calculateAccumulatedFrame方法檢索的節(jié)點(diǎn)的累積幀是最大的矩形但惶,其中包括節(jié)點(diǎn)的幀及其所有后代的幀。
  • 其他屬性湿蛔,例如alphahidden屬性膀曾,會(huì)影響節(jié)點(diǎn)及其后代的繪制方式。

所有節(jié)點(diǎn)都是響應(yīng)者對(duì)象阳啥,可以直接響應(yīng)用戶與屏幕上節(jié)點(diǎn)的交互添谊。請(qǐng)參閱 Controlling User Interaction on Nodes。您還可以在坐標(biāo)系之間轉(zhuǎn)換并執(zhí)行命中測試以確定點(diǎn)位于哪個(gè)節(jié)點(diǎn)察迟,并在樹中的節(jié)點(diǎn)之間執(zhí)行相交以確定它們的物理區(qū)域是否重疊斩狱。

樹中的任何節(jié)點(diǎn)都可以運(yùn)行操作,這些操作用于為節(jié)點(diǎn)的屬性設(shè)置動(dòng)畫扎瓶,添加或刪除節(jié)點(diǎn)所踊,播放聲音或執(zhí)行其他自定義任務(wù)。ActionSpriteKit中動(dòng)畫系統(tǒng)的核心栗弟。請(qǐng)參閱Getting Started with Actions

節(jié)點(diǎn)可以支持物理實(shí)體工闺,該實(shí)體是模擬對(duì)象的物理屬性的對(duì)象乍赫。當(dāng)節(jié)點(diǎn)具有物理主體時(shí),物理模擬會(huì)自動(dòng)為物理主體計(jì)算一個(gè)新位置陆蟆,然后移動(dòng)并旋轉(zhuǎn)節(jié)點(diǎn)以匹配該位置雷厂。請(qǐng)參閱Getting Started with Physics

節(jié)點(diǎn)可以提供表達(dá)與場景中其他節(jié)點(diǎn)或位置的關(guān)系的約束叠殷。這些約束在場景渲染之前由場景自動(dòng)應(yīng)用改鲫。另一組約束與執(zhí)行反向運(yùn)動(dòng)學(xué)動(dòng)畫的動(dòng)作結(jié)合使用。請(qǐng)參閱Working with Inverse Kinematics林束。

保證在主線程中訪問節(jié)點(diǎn)

SKViewDelegate像棘,SKSceneDelegateSKScene的所有SpriteKit回調(diào)都發(fā)生在主線程中,因此壶冒,這些是訪問或操作節(jié)點(diǎn)的安全位置缕题。 如果在后臺(tái)執(zhí)行其他工作,則應(yīng)采用如下方式:

class ViewController: UIViewController {
    let queue = DispatchQueue.global()
    
    var makeNodeModifications = false
    
    func backgroundComputation() {
        queue.async {
            // Perform background calculations but do not modify 
            // SpriteKit objects
            
            // Set a flag for later modification within the 
            // SKScene or SKSceneDelegate callback of your choosing
            
            self.makeNodeModifications = true
        }
    }
}
extension ViewController: SKSceneDelegate {
    func update(_ currentTime: TimeInterval, for scene: SKScene) {
        if makeNodeModifications {
            makeNodeModifications = false
            
            // Make node modifications
        }
    }
}

使用基礎(chǔ)節(jié)點(diǎn)布局場景

即使SKNode對(duì)象不能直接繪制內(nèi)容胖腾,也可以使用一些有用的方法在應(yīng)用程序中使用它們烟零。這里有一些想法可以幫助您入門:

  • 您具有從多個(gè)節(jié)點(diǎn)對(duì)象(精靈或其他內(nèi)容節(jié)點(diǎn))構(gòu)建的內(nèi)容瘪松。但是,您希望將此內(nèi)容視為游戲中的單個(gè)對(duì)象锨阿,而無需將任何一個(gè)內(nèi)容節(jié)點(diǎn)提升為根宵睦。一個(gè)基本節(jié)點(diǎn)是合適的,因?yàn)槟梢栽趫鼍皹渲袨槠渲付ㄎ恢檬睿缓髮⑺衅渌?jié)點(diǎn)作為后代壳嚎。這些單獨(dú)的作品也可以相對(duì)于父母的位置進(jìn)行移動(dòng)或調(diào)整。
  • 您希望將繪制的內(nèi)容組織為一系列圖層书斜。例如诬辈,許多游戲的背景層是世界,另一層是角色荐吉,第三層是文本和其他游戲信息焙糟。其他游戲具有更多層次。將圖層創(chuàng)建為基本節(jié)點(diǎn)样屠,然后將它們按順序插入場景中穿撮。然后,根據(jù)需要痪欲,可以使各個(gè)圖層可見或不可見悦穿。
  • 您需要場景中的對(duì)象不可見,但需要執(zhí)行其他一些必要的功能业踢。例如栗柒,在探索地牢的游戲中,不可見的節(jié)點(diǎn)可能用來表示隱藏的陷阱知举。當(dāng)另一個(gè)節(jié)點(diǎn)相交時(shí)瞬沦,陷阱被觸發(fā)。再舉一個(gè)例子雇锡,您可以將一個(gè)節(jié)點(diǎn)添加為另一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)逛钻,以代表玩家視角的位置。

在樹中擁有一個(gè)節(jié)點(diǎn)來表示這些概念有很多優(yōu)點(diǎn):

  • 您可以通過添加或刪除單個(gè)節(jié)點(diǎn)來添加或刪除整個(gè)子樹锰提。這使場景管理變得高效曙痘。
  • 您可以調(diào)整樹中節(jié)點(diǎn)的屬性,并使這些屬性的影響向下傳播到該節(jié)點(diǎn)的后代立肘。例如边坤,如果基本節(jié)點(diǎn)將sprite節(jié)點(diǎn)作為其子節(jié)點(diǎn),則旋轉(zhuǎn)基本節(jié)點(diǎn)也會(huì)旋轉(zhuǎn)所有sprite內(nèi)容谅年。
  • 您可以利用動(dòng)作惩嘉,物理接觸和其他SpriteKit功能來實(shí)現(xiàn)該概念。

相關(guān)方法

- init
+ node
+ nodeWithFileNamed:
- iniWithCoder:

在場景中定位內(nèi)容

通過將場景中的內(nèi)容放置在其父級(jí)的坐標(biāo)系中來對(duì)其進(jìn)行布局踢故。

position

節(jié)點(diǎn)在其父級(jí)坐標(biāo)系中的位置文黎。

@property(nonatomic) CGPoint position;

默認(rèn)值是 (0.0,0.0)惹苗。


查詢內(nèi)容大小

在父級(jí)的坐標(biāo)空間中讀取節(jié)點(diǎn)或其子級(jí)的位置和大小。

frame

父級(jí)坐標(biāo)系中的一個(gè)矩形耸峭,其中包含節(jié)點(diǎn)的內(nèi)容桩蓉,而忽略節(jié)點(diǎn)的子級(jí)。

@property(nonatomic, readonly) CGRect frame;

考慮到節(jié)點(diǎn)的xScale劳闹,yScalezRotation屬性院究,frame是包含節(jié)點(diǎn)內(nèi)容的最小矩形。

由于SKNode不會(huì)繪制自己的內(nèi)容本涕,因此其frame大小是任意的业汰。 確實(shí)繪制的是SKNode的視覺子類,它們定義了frame的大小菩颖,并帶有有意義的值來包圍框架的視覺內(nèi)容样漆。

要獲得包圍SKNode父對(duì)象的所有子節(jié)點(diǎn)的rect,請(qǐng)使用calculateAccumulatedFrame晦闰。

- calculateAccumulatedFrame

在父級(jí)坐標(biāo)系中返回一個(gè)矩形放祟,該矩形包含其自身和所有子節(jié)點(diǎn)的位置和大小。

- (CGRect)calculateAccumulatedFrame;

frame考慮了子樹中每個(gè)節(jié)點(diǎn)的xScale呻右,yScale和`zRotation屬性的累積影響跪妥。


配置繪圖順序

了解SpriteKit如何從上到下將場景的節(jié)點(diǎn)分層。

總覽

場景渲染的標(biāo)準(zhǔn)行為遵循一對(duì)簡單的規(guī)則(如圖1所示):

  • 父級(jí)在渲染子級(jí)之前先繪制其內(nèi)容声滥。
  • 子級(jí)以它們?cè)谧蛹?jí)數(shù)組中出現(xiàn)的順序呈現(xiàn)眉撵。


    圖1

在上圖中,直升機(jī)主體及其組件都是天空節(jié)點(diǎn)的子代落塑。 因此纽疟,場景呈現(xiàn)其內(nèi)容如下:

  1. 場景進(jìn)行渲染,將其內(nèi)容清除為背景色芜赌。
  2. 場景將渲染天空節(jié)點(diǎn)仰挣。
  3. 天空節(jié)點(diǎn)按照它們作為子級(jí)添加的順序渲染其子級(jí)(直升機(jī)主體及其組件)伴逸。
相對(duì)于父節(jié)點(diǎn)的繪圖順序

維護(hù)節(jié)點(diǎn)的孩子的秩序可能是很多工作缠沈。 相反,您可以為每個(gè)節(jié)點(diǎn)指定場景中的明確高度错蝴。 您可以通過設(shè)置節(jié)點(diǎn)的zPosition屬性來執(zhí)行此操作洲愤。 zPosition是節(jié)點(diǎn)相對(duì)于其父節(jié)點(diǎn)的高度,就像節(jié)點(diǎn)的position屬性代表其相對(duì)于父節(jié)點(diǎn)位置的xy位置一樣顷锰。 因此柬赐,您可以使用zPosition將節(jié)點(diǎn)放置在父級(jí)位置的上方或下方。

考慮zPosition時(shí)官紫,以下是呈現(xiàn)節(jié)點(diǎn)樹的方式:

  1. 每個(gè)節(jié)點(diǎn)的全局zPosition是通過將其zPosition遞歸添加到其父級(jí)的zPosition來計(jì)算的肛宋。
  2. 從最小的zPosition到最大的zPosition依次繪制節(jié)點(diǎn)州藕。
    3.如果兩個(gè)節(jié)點(diǎn)共享相同的zPosition,則先呈現(xiàn)祖先酝陈,然后按照子順序呈現(xiàn)同級(jí)床玻。

同級(jí)順序性能(Sibling Order Performance)

SpriteKit使用基于高度節(jié)點(diǎn)及其在節(jié)點(diǎn)樹中的位置的確定性渲染順序。但是沉帮,由于渲染順序是確定性的锈死,因此SpriteKit可能無法應(yīng)用某些渲染優(yōu)化,而其他方面可能會(huì)應(yīng)用穆壕。例如待牵,如果SpriteKit可以收集共享相同紋理和繪制模式的所有節(jié)點(diǎn)并通過一次繪制過程繪制它們,則可能會(huì)更好喇勋。要啟用這些優(yōu)化缨该,請(qǐng)將視圖的ignoresSiblingOrder屬性設(shè)置為YES。

當(dāng)您忽略同級(jí)順序時(shí)茄蚯,SpriteKit使用圖形硬件渲染節(jié)點(diǎn)压彭,以使它們看起來按zPosition排序。它將節(jié)點(diǎn)按繪制順序排序渗常,以減少渲染場景所需的繪制調(diào)用次數(shù)壮不。但是使用這種優(yōu)化的繪制順序,您無法預(yù)測共享相同高度的節(jié)點(diǎn)的渲染順序皱碘。每次渲染新幀時(shí)询一,渲染順序可能會(huì)更改。在許多情況下癌椿,這些節(jié)點(diǎn)的繪制順序并不重要健蕊。例如,如果節(jié)點(diǎn)的高度相同但在屏幕上不重疊踢俄,則可以按任何順序繪制它們缩功。

圖2顯示了一個(gè)使用zPosition確定渲染順序的樹的示例。在此示例中都办,直升機(jī)的機(jī)體高度為100嫡锌,其子代相對(duì)于其高度進(jìn)行渲染。兩個(gè)轉(zhuǎn)子節(jié)點(diǎn)共享相同的高度琳钉,但不重疊势木。

圖2僅深度渲染可以提高性能


圖2

來自不同父母的交錯(cuò)子節(jié)點(diǎn)

由于子節(jié)點(diǎn)的zPosition已添加到其父節(jié)點(diǎn)的zPosition中,因此可以使子節(jié)點(diǎn)與其他父節(jié)點(diǎn)交錯(cuò)歌懒。 圖3顯示了創(chuàng)建兩個(gè)方形父節(jié)點(diǎn)的代碼啦桌,每個(gè)父節(jié)點(diǎn)都有一個(gè)圓形子節(jié)點(diǎn)。 第一個(gè)節(jié)點(diǎn)的zPosition為10及皂,其子節(jié)點(diǎn)的zPosition為10甫男。第二個(gè)節(jié)點(diǎn)的zPosition為15且改,其子節(jié)點(diǎn)的zPosition為10。

一旦添加到場景中板驳,第一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)的有效全局zPosition為20钾虐,第二個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)的有效全局zPosition為25,從而產(chǎn)生交織效果笋庄。

示例:交織復(fù)合節(jié)點(diǎn)

func addNodesTo(scene: SKScene,
                color: SKColor, position: CGPoint,
                parentZ: CGFloat, childZ: CGFloat) {
    
    let diameter: CGFloat = 250
    let rect = CGRect(origin: position,
                      size: CGSize(width: diameter, height: diameter))
     
    let parentNode = SKShapeNode(rect: rect)
    let childNode = SKShapeNode(ellipseIn: rect.insetBy(dx: 10, dy: 10))
  
    [(parentNode, scene, parentZ), (childNode, parentNode, childZ)].forEach {
        node, parent, zPosition in
        
        node.fillColor = color
        node.strokeColor = .white
        node.zPosition = zPosition
        
        parent.addChild(node)
    }
}

  
addNodesTo(scene: scene,
           color: .red,
           position: CGPoint(x: 300, y: 300),
           parentZ: 10,
           childZ: 10)
 
addNodesTo(scene: scene,
           color: .blue,
           position: CGPoint(x: 350, y: 250),
           parentZ: 15,
           childZ: 10)
圖3結(jié)果

由于zPosition是跨父子節(jié)點(diǎn)關(guān)系添加的效扫,因此您可以同時(shí)使用樹順序和zPositions來確定場景的渲染順序。 渲染復(fù)雜場景時(shí)直砂,應(yīng)禁用排序行為菌仁,并使用節(jié)點(diǎn)的zPositions創(chuàng)建確定性的場景順序。

重要信息
SKCropNodeSKEffectNode節(jié)點(diǎn)類可更改場景渲染行為静暂。 這些節(jié)點(diǎn)的子級(jí)被獨(dú)立渲染為單獨(dú)的節(jié)點(diǎn)樹济丘,結(jié)果被渲染到包含作物或效果節(jié)點(diǎn)的樹中。 有關(guān)更多信息洽蛀,請(qǐng)參見使用其他節(jié)點(diǎn)類型摹迷。

zPosition

默認(rèn)值為0.0。 z軸正向觀察者投影郊供,因此具有較大z位置值的節(jié)點(diǎn)更靠近觀察者峡碉。 渲染節(jié)點(diǎn)樹時(shí),將計(jì)算每個(gè)節(jié)點(diǎn)的高度(以絕對(duì)坐標(biāo)表示)驮审,然后將樹中的所有節(jié)點(diǎn)從最小的z位置值渲染到最大的z位置值鲫寄。 如果多個(gè)節(jié)點(diǎn)共享相同的z位置,則會(huì)對(duì)這些節(jié)點(diǎn)進(jìn)行排序疯淫,以便在其子級(jí)之前繪制父級(jí)節(jié)點(diǎn)地来,并按照它們?cè)谄涓讣?jí)的子級(jí)數(shù)組中出現(xiàn)的順序渲染同級(jí)。 命中測試以相反的順序進(jìn)行處理熙掺。

SKView類的ignoresSiblingOrder屬性控制是否為相同z位置的節(jié)點(diǎn)啟用節(jié)點(diǎn)排序未斑。

重要信息
效果節(jié)點(diǎn)或裁剪節(jié)點(diǎn)(Descendants of an effect node or a crop node )的不會(huì)與同一樹中的其他節(jié)點(diǎn)一起渲染。 效果節(jié)點(diǎn)(SKEffectNode)將其子級(jí)作為單獨(dú)的節(jié)點(diǎn)樹渲染到專用幀緩沖區(qū)中币绩,然后將合成圖像渲染到包含效果節(jié)點(diǎn)的樹中蜡秽。 裁剪節(jié)點(diǎn)(SKCropNode)的工作原理類似; 它分別渲染遮罩类浪,然后使用遮罩將其實(shí)際后代渲染到包含作物節(jié)點(diǎn)的樹中载城。

使用節(jié)點(diǎn)的深度添加效果

SpriteKit僅使用zPosition值來確定命中測試和繪制順序肌似。 您也可以將z位置實(shí)現(xiàn)自己的游戲效果费就。 例如,您可以使用節(jié)點(diǎn)的高度來確定其渲染方式或如何在屏幕上移動(dòng)川队。 這樣力细,您可以模擬霧或視差效果睬澡。 SpriteKit不會(huì)為您創(chuàng)建這些效果。 通常眠蚂,您可以通過在渲染場景之前立即處理場景來實(shí)現(xiàn)它們煞聪。


縮放和旋轉(zhuǎn)

zRotation
繞z軸的歐拉旋轉(zhuǎn)(以弧度為單位)。

@property(nonatomic) CGFloat zRotation;

默認(rèn)值為0.0逝慧,表示不旋轉(zhuǎn)昔脯。 正值表示逆時(shí)針旋轉(zhuǎn)。 旋轉(zhuǎn)坐標(biāo)系時(shí)笛臣,它會(huì)影響節(jié)點(diǎn)及其后代云稚。 旋轉(zhuǎn)會(huì)影響節(jié)點(diǎn)的框架屬性,命中測試沈堡,渲染和其他類似特征静陈。

- setScale:

- (void)setScale:(CGFloat)scale;

設(shè)置節(jié)點(diǎn)的xScaleyScale屬性

xScale

比例因子,乘以節(jié)點(diǎn)及其子節(jié)點(diǎn)的寬度诞丽。

@property(nonatomic) CGFloat xScale;

xScale屬性縮放節(jié)點(diǎn)及其所有子類的寬度鲸拥。 比例值會(huì)影響節(jié)點(diǎn)框架的計(jì)算方式,命中測試區(qū)域僧免,繪制方式以及其他類似特征刑赶。 默認(rèn)值為1.0。

yScale

比例因子懂衩,乘以節(jié)點(diǎn)及其子節(jié)點(diǎn)的寬度角撞。

@property(nonatomic) CGFloat yScale;

yScale屬性縮放節(jié)點(diǎn)及其所有后代的高度。 比例值會(huì)影響節(jié)點(diǎn)框架的計(jì)算方式勃痴,命中測試區(qū)域谒所,繪制方式以及其他類似特征。 默認(rèn)值為1.0沛申。


訪問相關(guān)節(jié)點(diǎn)

了解節(jié)點(diǎn)如何遵循其坐標(biāo)系劣领。

總覽

將節(jié)點(diǎn)放置在節(jié)點(diǎn)樹中時(shí),其位置屬性會(huì)將其放置在其父級(jí)提供的坐標(biāo)系內(nèi)铁材。 SpriteKitiOSmacOS上使用相同的坐標(biāo)系尖淘。

點(diǎn)作為位置單位

將節(jié)點(diǎn)放置在節(jié)點(diǎn)樹中時(shí),其位置屬性會(huì)將其放置在其父級(jí)提供的坐標(biāo)系內(nèi)著觉。 SpriteKitiOSmacOS上使用相同的坐標(biāo)系村生。 下圖顯示了SpriteKit坐標(biāo)系。 與UIKitAppKit一樣饼丘,坐標(biāo)值以點(diǎn)為單位趁桃。 必要時(shí),渲染場景時(shí)將點(diǎn)轉(zhuǎn)換為像素。 x坐標(biāo)正向右移卫病,y坐標(biāo)正向屏幕上移油啤。

SpriteKit坐標(biāo)系統(tǒng)

極坐標(biāo)旋轉(zhuǎn)(Polar Coordinate Rotation)

SpriteKit還具有標(biāo)準(zhǔn)的旋轉(zhuǎn)約定。 顯示極坐標(biāo)慣例蟀苛。 0弧度的角度指定正x軸益咬。 正角為逆時(shí)針方向。

通過將節(jié)點(diǎn)的zRotation屬性設(shè)置為所需的弧度角來旋轉(zhuǎn)節(jié)點(diǎn)帜平。 如果您更喜歡以度為單位工作幽告,則以下代碼顯示了如何編寫對(duì)CGFloat的擴(kuò)展,以在兩者之間進(jìn)行轉(zhuǎn)換裆甩。 示例將spriteNode逆時(shí)針旋轉(zhuǎn)30度评腺。

extension CGFloat {
    func degreesToRadians() -> CGFloat {
        return self * CGFloat.pi / 180
    }
}

let rabbitTexture = SKTexture(imageNamed: "rabbit.png")

let spriteNode = SKSpriteNode(texture: rabbitTexture)

spriteNode.zRotation = CGFloat(30).degreesToRadians()
相關(guān)屬性

scene
parent
children

修改和訪問節(jié)點(diǎn)樹

您可以通過在節(jié)點(diǎn)之間創(chuàng)建父子關(guān)系來創(chuàng)建節(jié)點(diǎn)樹。 每個(gè)節(jié)點(diǎn)維護(hù)一個(gè)有序的子級(jí)列表淑掌,通過讀取節(jié)點(diǎn)的children屬性來引用該列表蒿讥。 樹中子級(jí)的順序會(huì)影響場景處理的許多方面,包括命中測試和渲染抛腕,因此適當(dāng)?shù)亟M織節(jié)點(diǎn)樹很重要芋绸。

- addChild:
- insertChild:atIndex:`
- isEqualToNode:
如果該節(jié)點(diǎn)是父節(jié)點(diǎn)的后代,則為YES担敌;否則為摔敛。 否則沒有。

- moveToParent:
- removeFromParent
- removeAllChildren
- removeChildrenInArray:
- inParentHierarchy:

自定義節(jié)點(diǎn)

Customizing the Behavior of a Node

向子類傳播屬性(修改后會(huì)影響子節(jié)點(diǎn)的屬性)

按名稱訪問節(jié)點(diǎn)

通常組織場景樹中的節(jié)點(diǎn)來確定場景的精確渲染順序全封,而不是確定這些節(jié)點(diǎn)在場景中扮演的角色马昙。 您可能還從存檔文件加載節(jié)點(diǎn),而不是在運(yùn)行時(shí)直接實(shí)例化它們刹悴,因此您可能需要能夠在節(jié)點(diǎn)樹中找到特定的節(jié)點(diǎn)行楞。 為此,您需要為節(jié)點(diǎn)提供名稱土匀,然后搜索這些名稱子房。

節(jié)點(diǎn)名稱通常在您的應(yīng)用程序中有兩個(gè)作用:

  1. 您可以編寫自己的代碼,以根據(jù)節(jié)點(diǎn)名稱實(shí)現(xiàn)游戲邏輯就轧。 例如证杭,當(dāng)兩個(gè)物理對(duì)象碰撞時(shí),可以使用節(jié)點(diǎn)名稱來確定碰撞如何影響游戲玩法妒御。
  2. 您可以搜索具有特定名稱的節(jié)點(diǎn)解愤。 通常,第一次加載場景時(shí)乎莉,只需執(zhí)行一次送讲。
為節(jié)點(diǎn)起名

節(jié)點(diǎn)的名稱屬性應(yīng)為字母數(shù)字字符串奸笤,且不帶標(biāo)點(diǎn)符號(hào)。 以下代碼顯示了如何命名三個(gè)不同的節(jié)點(diǎn)以將它們彼此區(qū)分開李茫。

playerNode.name = @"player";
monsterNode1.name = @"goblin";
monsterNode2.name = @"ogre";

在樹中命名節(jié)點(diǎn)時(shí),請(qǐng)確定這些名稱是否唯一肥橙。 如果一個(gè)節(jié)點(diǎn)的名稱是唯一的魄宏,則在場景樹中不得包含多個(gè)使用該名稱的節(jié)點(diǎn)。 另一方面存筏,如果節(jié)點(diǎn)名稱在您的應(yīng)用中不是唯一的宠互,則它可能表示相關(guān)節(jié)點(diǎn)的集合。 例如椭坚,在上面的代碼中予跌,游戲中可能有多個(gè)妖精,您可能希望使用相同的名稱來識(shí)別它們善茎。 但是玩家可能是游戲中的唯一節(jié)點(diǎn)券册。

用名稱搜索節(jié)點(diǎn)

SKNode類實(shí)現(xiàn)以下用于搜索節(jié)點(diǎn)樹的方法:

  • childNodeWithName:方法搜索節(jié)點(diǎn)的子節(jié)點(diǎn),直到找到匹配的節(jié)點(diǎn)垂涯,然后停止并返回該節(jié)點(diǎn)烁焙。此方法通常用于搜索具有唯一名稱的節(jié)點(diǎn)。
  • enumerateChildNodesWithName:usingBlock:方法搜索節(jié)點(diǎn)的子節(jié)點(diǎn)耕赘,并為找到的每個(gè)匹配節(jié)點(diǎn)調(diào)用一次塊骄蝇。當(dāng)您要查找共享相同名稱的所有節(jié)點(diǎn)時(shí),可以使用此方法操骡。
  • objectForKeyedSubscript:方法返回與特定名稱匹配的節(jié)點(diǎn)數(shù)組九火。

以下代碼顯示了如何在場景類上創(chuàng)建方法以找到播放器節(jié)點(diǎn)。您可以在代碼內(nèi)部使用類似這樣的方法來加載和準(zhǔn)備場景册招。

-(SKNode *)playerNode
{
    return [self childNodeWithName:@“ player”];
}

在場景上調(diào)用此方法時(shí)岔激,場景將在其子級(jí)(僅對(duì)其子級(jí))中搜索其name屬性與搜索字符串匹配的節(jié)點(diǎn),然后返回該節(jié)點(diǎn)是掰。指定搜索字符串時(shí)鹦倚,可以指定節(jié)點(diǎn)名稱或類名稱。例如冀惭,如果為播放器節(jié)點(diǎn)創(chuàng)建自己的子類并將其命名為PlayerSprite震叙,則可以將PlayerSprite指定為搜索字符串,而不是player散休。相同的節(jié)點(diǎn)將被返回媒楼。

使用高級(jí)搜索

表一:搜索語法選項(xiàng)

語法 作用
/ 如果將其放在搜索字符串的開頭,則表示應(yīng)該在樹的根節(jié)點(diǎn)上執(zhí)行搜索戚丸。 如果將其放置在搜索字符串開頭以外的任何位置划址,則表明搜索應(yīng)移至該節(jié)點(diǎn)的子級(jí)扔嵌。
// 當(dāng)放置在搜索字符串的開頭時(shí),這指定搜索應(yīng)從根節(jié)點(diǎn)開始夺颤,并在整個(gè)節(jié)點(diǎn)樹中遞歸執(zhí)行痢缎。 否則,它將從其當(dāng)前位置執(zhí)行遞歸搜索世澜。
. 引用當(dāng)前節(jié)點(diǎn)独旷。
.. 搜索應(yīng)上移到該節(jié)點(diǎn)的父節(jié)點(diǎn)。
* 搜索匹配零個(gè)或多個(gè)字符寥裂。
[characters delimited by commas or dashes] 搜索與括號(hào)內(nèi)包含的任何字符匹配嵌洼。
alphanumeric characters 搜索僅匹配指定的字符。

官方示例:


更改節(jié)點(diǎn)可見性

alpha

hidden

Running Actions

在Sprite上創(chuàng)建封恰、配置和運(yùn)行Actions

總覽

當(dāng)您要為場景的內(nèi)容設(shè)置動(dòng)畫時(shí)麻养,您告訴節(jié)點(diǎn)運(yùn)行SKAction的實(shí)例。 當(dāng)場景處理動(dòng)畫幀時(shí)诺舔,將執(zhí)行actions鳖昌。 一些actions在動(dòng)畫的單個(gè)幀中完成,而其他actions則在完成之前將更改應(yīng)用于動(dòng)畫的多個(gè)幀低飒。 操作最常見的用途是為節(jié)點(diǎn)的屬性設(shè)置動(dòng)畫遗遵。 例如,您可以創(chuàng)建移動(dòng)節(jié)點(diǎn)逸嘀,縮放或旋轉(zhuǎn)節(jié)點(diǎn)或淡化其透明度的actions车要。 但是,actions也可以更改節(jié)點(diǎn)樹崭倘,播放聲音甚至執(zhí)行自定義代碼翼岁。

未完。司光。待續(xù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琅坡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子残家,更是在濱河造成了極大的恐慌榆俺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坞淮,死亡現(xiàn)場離奇詭異茴晋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)回窘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門诺擅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人啡直,你說我怎么就攤上這事烁涌〔缘” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵撮执,是天一觀的道長微峰。 經(jīng)常有香客問我,道長抒钱,這世上最難降的妖魔是什么蜓肆? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮继效,結(jié)果婚禮上症杏,老公的妹妹穿的比我還像新娘装获。我一直安慰自己瑞信,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布穴豫。 她就那樣靜靜地躺著凡简,像睡著了一般。 火紅的嫁衣襯著肌膚如雪精肃。 梳的紋絲不亂的頭發(fā)上秤涩,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音司抱,去河邊找鬼筐眷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛习柠,可吹牛的內(nèi)容都是我干的匀谣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼资溃,長吁一口氣:“原來是場噩夢啊……” “哼武翎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溶锭,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤宝恶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后趴捅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垫毙,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年拱绑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了露久。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡欺栗,死狀恐怖毫痕,靈堂內(nèi)的尸體忽然破棺而出征峦,到底是詐尸還是另有隱情,我是刑警寧澤消请,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布栏笆,位于F島的核電站,受9級(jí)特大地震影響臊泰,放射性物質(zhì)發(fā)生泄漏蛉加。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一缸逃、第九天 我趴在偏房一處隱蔽的房頂上張望针饥。 院中可真熱鬧,春花似錦需频、人聲如沸丁眼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苞七。三九已至,卻和暖如春挪丢,著一層夾襖步出監(jiān)牢的瞬間蹂风,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工乾蓬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惠啄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓任内,卻偏偏與公主長得像撵渡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子族奢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容