2016-04-07 102 views
2

我找到一個similar question,但我試圖檢測和識別用戶觸摸哪個Sprite,我不知道該怎麼做。這是我的變量:我如何檢測SKSpriteNode已被觸摸

var sprites: [[SKSpriteNode]] = [[SKSpriteNode(imageNamed: "a"), SKSpriteNode(imageNamed: "b")], [SKSpriteNode(imageNamed: "c"),SKSpriteNode(imageNamed: "d")]] 

的想法是識別spriteNode,然後更換爲其他精靈或改變顏色,但我不知道如何與這個矩陣spriteNodes的做到這一點,我想第一一步它確定精靈。

我真的很感謝你的幫忙!謝謝!

+0

您好! 0.0 @rakeshbs – AnaMM

+0

首先,不要創建那樣的精靈。你必須設置他們的名字。稍後,在touchesBegan中,可以使用'nodeAtPoint'或'nodesAtPoint'來檢查哪個節點被*觸摸*並根據其名稱採取適當的操作。如果你需要一些代碼,讓我們知道...... – Whirlwind

+0

其實,rakeshbs在這個鏈接中發佈的答案就是你應該怎麼做。所以你必須創建按鈕,命名它們,將它們添加到矩陣(如果你喜歡)並使用他發佈的代碼。 – Whirlwind

回答

8

你正在嘗試做什麼(即使我沒有看到這個原因)可以使用delegation模式來完成。基本上,你會告訴你的代表(場景,或者你設定的代表),爲你做些事情,你會直接從按鈕的方法touchesBegan中做到這一點。此外,您將按鈕的名稱傳遞給一個場景。

要做到這一點,首先必須定義一個名爲ButtonDelegate的協議。該協議定義了規定,任何符合的類必須實現的方法稱爲printButtonsName(_:)要求:

protocol ButtonDelegate:class { 

    func printButtonsName(name:String?) 
} 

。這是將在GameScene類中按鈕的touchesBegan來實現,但調用的方法。此外,此方法將用於將按鈕的名稱傳遞給其委託(場景),因此您將始終知道哪個按鈕被點擊。

接下來的事情是按鈕類本身。 Button可能是這樣的:

class Button : SKSpriteNode{ 

    weak var delegate:ButtonDelegate? 

    init(name:String){ 
     super.init(texture: nil, color: .purpleColor(), size: CGSize(width: 50, height: 50)) 
     self.name = name 
     self.userInteractionEnabled = true 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 


    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

     delegate?.printButtonsName(self.name) 
    } 
} 

最重要的這裏是userInteractionEnabled = true,這意味着按鈕將接受觸摸。另一個重要的是delegate屬性。如前所述,按鈕會將場景設置爲其代表。當我們創建一些按鈕時,將場景設置爲代表按鈕...爲了讓您更容易,可以將代理看作是爲他的老闆工作的工作人員:)老闆(一個按鈕)告訴他的工作人員(一個場景)爲他做點什麼(打印他的名字)。

好吧,讓我們確保該場景符合ButtonDelegate協議...爲什麼這很重要?這很重要,因爲工人(場景)必須按照他的老闆的命令(一個按鈕)。只要符合此協議,工人正在一個合同,他的老闆在那裏證實,他知道如何做他的工作,並會按照他的命令:)

class GameScene: SKScene, ButtonDelegate { 


    override func didMoveToView(view: SKView) { 

     let play = Button(name:"play") 
     play.delegate = self 
     let stop = Button(name:"stop") 
     stop.delegate = self 

     play.position = CGPoint(x: frame.midX - 50.0, y: frame.midY) 
     stop.position = CGPoint(x: frame.midX + 50.0, y: frame.midY) 

     addChild(play) 
     addChild(stop) 
    } 

    func printButtonsName(name: String?) { 

     if let buttonName = name { 
      print("Pressed button : \(buttonName) ") 
     } 

     //Use switch here to take appropriate actions based on button's name (if you like) 
    } 
} 

就是這樣。當你點擊播放按鈕時,按鈕上的touchesBegan將被調用,然後該按鈕會告訴其委託使用場景類中定義的方法來打印其名稱。

+0

哇!謝謝!你不知道我有多麼感激你的幫助!你真了不起!謝謝! :D – AnaMM

+0

爲什麼需要在委託中調用一個函數?爲什麼按鈕不能自己完成所需的活動,一旦它意識到它被觸動了? – Confused

+0

@confused你可以,但它確實取決於按下按鈕時會發生什麼。您可能想要將節點添加/刪除到場景或進行轉場。或者從場景中刪除節點,所以在這些情況下,委託會很有用。您可以使用塊,並將一段代碼傳遞給按鈕實例,但我更喜歡這種委派責任的方式。你沒有真正定義你的確切意思,* *按鈕應該如何「做活動本身」,所以我不能真正發表評論。 – Whirlwind

0

首先,你需要另一種方式來創建精靈,這裏有一個辦法:

let spriteA = SKSpriteNode(imageNamed: "a") 
scene.addChild(spriteA) 
let spriteB = SKSPriteNode(imageNamed: "b") 
scene.addChild(spriteB) 
...and so on... 

現在我們需要爲精靈設置一個名稱,所以我們可以知道哪個節點後挖。要爲精靈添加一個名字只是這樣做:

spriteNode.name = "name of the sprite" 

把這個代碼在上面的例子會是這個樣子:

let spriteA = SKSpriteNode(imageNamed: "a") 
spriteA.name = "a" 
scene.addChild(spriteA) 
let spriteB = SKSPriteNode(imageNamed: "b") 
spriteB.name = "b" 
scene.addChild(spriteB) 
...and so on... 

爲了檢測觸摸要把它放到你的SKScene子類:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    let touch = touches.first as UITouch! 
    let touchLocation = touch.locationInNode(self) 
    let targetNode = nodeAtPoint(touchLocation) as! SKSpriteNode 
} 

targetNode是您點擊的節點。

如果你想得到精靈的名字,你可以使用targetNode.name