2015-05-17 22 views
0

我試圖將觸摸綁定到特定的sprite。我在Objective-C中做了類似的工作,並且這種工作很好。試圖通過綁定到Sprite的觸摸來實現Swift + Spritekit中的multiTouch,但得到警告我不明白如何解決

我得到在GameScene類以下錯誤 :類「GameScene」不具有初始 在AnimalSprite類init方法:額外的參數「紋理」呼叫

我試圖谷歌這一點,但真的不能解決這個問題。有任何想法嗎? 我的ViewController是默認的SpriteKit模板之一。沒有觸及它。

class GameScene: SKScene { 

    private var draggedNode: DraggableSprite 

    override func didMoveToView(view: SKView) { 
     /* Setup your scene here */ 
     self.physicsBody = SKPhysicsBody(edgeLoopFromRect: view.frame); 
     self.backgroundColor = SKColor.greenColor() 
     self.physicsWorld.gravity.dy = 0 

     let animalSpawner = AnimalSpawner() 
     self.addChild(animalSpawner) 
     animalSpawner.startSpawning() 
    } 

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 
     /* Called when a touch begins */ 
     let touch = touches.first as! UITouch 
     let touchLocation = touch.locationInNode(self) 
     let touchedNode = self.nodeAtPoint(touchLocation) 
     if !(touchedNode is AnimalSprite){ return; } 

     // Bind touch 
     let animalNode = touchedNode as! AnimalSprite 
     animalNode.bindTouch(touch) 
     self.draggedNode = animalNode 
    } 

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) { 
     let touch = touches.first as! UITouch 
     self.draggedNode.unbindTouchIfNeeded(touch) 
    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
     self.draggedNode.drag() 
    } 

} 

class DraggableSprite: SKSpriteNode { 
    var touch: UITouch? 
    private var touchOffset = CGPoint() 
    private var isDragged: Bool? { 
     get{ 
      if self.touch != nil { 
       return true 
      } 
      return nil 
     } 
     set{ self.isDragged = newValue } 
    } 

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

    func bindTouch(touch: UITouch) { 
     self.touch = touch 
     let touchLocation = touch.locationInNode(self.parent) 
     self.touchOffset = subtractVector(touchLocation, other: self.position) 
    } 

    func unbindTouchIfNeeded(touch: UITouch){ 
     if self.touch != touch { 

     } else { 
      self.touch = nil 
     } 
    } 

    func drag(){ 
     if (self.touch == nil) { return; } 
     let touchLocation = self.touch!.locationInNode(self.parent) 
     self.position = subtractVector(touchLocation, other: self.touchOffset) 
    } 

    //MARK: Private methods 
    private func subtractVector(p1: CGPoint, other: CGPoint) -> CGPoint { 
     return CGPointMake(p1.x - other.x, p1.y - other.y) 
    } 

} 

class AnimalSprite: DraggableSprite { 

    private let animalSize = CGSizeMake(200.0, 200.0) 
    private let baseDuration: CGFloat = 10 
    private let baseAlpha: CGFloat = 1 
    var animalType = Type() 
    var isTouched = Bool() 

    // Sounds 
    .. 

    init(){ 
     super.init(texture: nil, color: nil, size: animalSize) 
     self.texture = randomAnimal() 
     self.runAction(SKAction.rotateToAngle(0.15, duration: 0.01)) 
    } 

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

    private func randomAnimal() -> SKTexture { 
     // Here random animal textture will be returned 
     let animalArray = ["cow", "pig", "chicken"] 
     let randomIndex = Int(arc4random_uniform(UInt32(animalArray.count))) 
     let animalType = animalArray[randomIndex] 
     switch (animalType){ 
      case "cow": 
       self.animalType = Type.Cow 
       audioPlayer = AVAudioPlayer(contentsOfURL: cowSound, error: nil) 
      case "chicken": 
       self.animalType = Type.Chicken 
       audioPlayer = AVAudioPlayer(contentsOfURL: chickenSound, error: nil) 
      case "pig": 
       self.animalType = Type.Pig 
       audioPlayer = AVAudioPlayer(contentsOfURL: pigSound, error: nil) 
      default: 
       self.animalType = Type() 
     } 
     audioPlayer.prepareToPlay() 
     return SKTexture(imageNamed: animalArray[randomIndex]) 
    } 

    private func wiggle() -> SKAction { 
     let rotateLeft = SKAction.rotateByAngle(-0.3, duration: 0.2) 
     let rotateRight = SKAction.rotateByAngle(0.3, duration: 0.2) 
     let wiggleSequence = SKAction.sequence([rotateLeft, rotateRight]) 
     let repeatForever = SKAction.repeatActionForever(wiggleSequence) 
     return repeatForever 
    } 

    // MARK: Actions 
    func startMove() { 
     if let gameScene = self.scene { 

      let destinationX = (self.position.x > gameScene.frame.width/2) ? -self.frame.width : gameScene.frame.width+self.frame.width //0 - CGRectGetWidth(gameScene.frame) - animalSize.width 
      let destinationY = self.position.y //CGFloat(arc4random_uniform(UInt32(gameScene.size.height))) 
      let duration = NSTimeInterval(baseDuration + CGFloat(Double(arc4random_uniform(10))/10.0)) 

      let travel = SKAction.moveTo(CGPointMake(destinationX, destinationY), duration: duration) 
      let remove = SKAction.removeFromParent() 
      let wiggle = self.wiggle() 
      let groupAction = [SKAction .group([travel, wiggle])] 
      let sequence = SKAction.sequence([groupAction, remove]) 

      println("dest x: \(destinationX) dest y: \(destinationY)") 
      self.runAction(sequence, withKey: "moving") 
     } 
    } 

    func playSound() { 
     audioPlayer.play() 
    } 
} 
+0

您會在哪些線路上看到這些錯誤? – ABakerSmith

+0

在類「GameScene」行我得到「沒有初始化程序」 和AnimalSprite類init方法:額外參數「紋理」在調用 –

回答

0

在你的GameScene類中,你缺少一個init函數。初始化功能對所有課程都是強制性的,您需要確保您也撥打super.init()

override init(size: CGSize) { 
    super.init() 
} 
0

的問題與您GameScene是你定義的屬性,draggedNode,但你有沒有給它一個缺省值或在init方法初始化它;因此Xcode正在抱怨你。如果它不爲draggedNode意義有一個值用戶按下屏幕之前,您應該draggedNode和可選的,就像這樣:

private var draggedNode: DraggableSprite? 

然後,您可以在touchesBegan和背部設置draggedNode的值到niltouchesEndedtouchesCancelled


也就是您在具有與AnimalSprite一個問題確切線?一旦知道,我可以更新我的答案。


還有一兩件事我注意到在看你的代碼:在我看來,它更有意義申報subtractVector作爲一個全球性的功能,因爲它不是針對您GameScene而這樣做將使您能夠再次使用該代碼在其他場景中。再進一步,您可以覆蓋-運營商而不是使用某個功能,例如:

func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint { 
    return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y) 
}