2016-02-20 15 views
1

我有一個方框,用戶可以在其中移動塊但不接觸框架。如果用戶觸摸方框,則遊戲結束。目前我遇到了一個問題,如果用戶快速滑動塊,它會在沒有任何碰撞/接觸檢測的情況下穿過框架。如果玩家緩慢移動模塊並觸摸框架,則會檢測到碰撞。我的代碼如下,我不能讓它停止通過框架。塊快速移動時出現意外的碰撞行爲 - 精靈通過

// setup play scene 
let playScreen = SKSpriteNode(color: .clearColor(), size: CGSize(width: 370, height: 370)) 
playScreen.position = CGPoint(x: frame.midX, y: frame.midY - CGFloat(yFrame)) 
// create the rectangle which will represent physics body 
let rect = CGRect(origin: CGPoint(x: -playScreen.size.width/2, y: -playScreen.size.height/2), size: playScreen.size) 
// apply physics conditions to the play scene 
playScreen.physicsBody = SKPhysicsBody(edgeLoopFromRect: rect) 
playScreen.physicsBody!.friction = 0 
// add play scene to the frame 
addChild(playScreen) 
playScreen.physicsBody!.categoryBitMask = BitMask.frame 
playScreen.physicsBody!.contactTestBitMask = BitMask.player 
playScreen.physicsBody!.collisionBitMask = BitMask.player 
playScreen.physicsBody!.usesPreciseCollisionDetection = true; 

// set up player block 
player.position = CGPoint(x:frame.size.width/2, y: frame.size.height/2 - CGFloat(yFrame)) 
player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 30, height: 30)) 
player.physicsBody!.dynamic = true 
player.physicsBody!.friction = 0 
player.physicsBody!.affectedByGravity = false 
player.physicsBody!.allowsRotation = false 
addChild(player) 
player.physicsBody!.categoryBitMask  = BitMask.player 
player.physicsBody!.contactTestBitMask = BitMask.obstacle | BitMask.frame 
player.physicsBody!.collisionBitMask = BitMask.obstacle | BitMask.frame 

我有以下的接觸檢測:

func didBeginContact(contact: SKPhysicsContact) { 
    var firstBody: SKPhysicsBody 
    var secondBody: SKPhysicsBody 

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 
    } else { 
     firstBody = contact.bodyB 
     secondBody = contact.bodyA 
    } 

    if (firstBody.categoryBitMask == BitMask.player) && ((secondBody.categoryBitMask == BitMask.obstacle) || (secondBody.categoryBitMask == BitMask.frame)) { 

     self.view?.paused = true 

     // check if this stops it 
     player.physicsBody!.velocity.dx = 0 
     player.physicsBody!.velocity.dy = 0 

     playerCollided = true 

    } 
} 

因此,這是對我的觸動開始函數的代碼。如果用戶觸摸播放器塊:

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

    if name == "player" { 

     // first touch 
     if playerFirstTouch { 
      print("New Game") 
      print("Finger is on player block") 
      isFingerOnPlayer = true 

      NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "printDuration:", userInfo: NSDate(), repeats: true) 

      playerFirstTouch = false 
      print("\(player.physicsBody!.velocity.dy)") 

     } else { 
      print("Finger is on player block after game started") 
      isFingerOnPlayer = true 
      print("\(player.physicsBody!.velocity.dy)") 
     } 
    } 
} 

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

    // check if user touched the player block 
    if isFingerOnPlayer { 
     // get touch location 
     if let touch = touches.first { 
      let prevTouchLoc = touch.previousLocationInNode(self) 
      // calculate new position along x and y 
      var newXPos = player.position.x + (touchLocation.x - prevTouchLoc.x) 
      var newYPos = player.position.y + (touchLocation.y - prevTouchLoc.y) 
      // 
      newXPos = max(newXPos, self.player.frame.size.width/2) 
      newXPos = min(newXPos, self.size.width - self.player.frame.size.width/2) 
      // 
      newYPos = max(newYPos, self.player.frame.size.height/2) 
      newYPos = min(newYPos, self.size.height - self.player.frame.size.height/2) 
      // update player block position 
      player.position = CGPointMake(newXPos, newYPos) 
     } 
    } 

} 

回答

0

讓玩家使用精確的碰撞檢測,而不是場景。玩家是移動的節點,需要將其物理計算分步驟進行。因此,像:

player.physicsBody!.usesPreciseCollisionDetection = true; 

您可以從playScene刪除精確的碰撞檢測,具有它只會拖垮的物理引擎。

編輯

我這個擴大覆蓋如何使用SKAction,而不是移動到設定位置的節點。我很確定這會起作用,但讓我知道。檢查我將要使用的the documentation for the moveBy method

,你要做的第一件事就是刪除這一行:

player.position = CGPointMake(newXPos, newYPos) 

我們還打算用這條線來替代它:

player.runAction(SKAction.moveTo(CGPointMake(newXPos, newYPos), 0.01)) 

這應玩家移動到所需真的很快(我想)。

+0

我剛試過試過你說的沒有運氣,我很害怕。 – spigen

+0

嗯。你介意包括你如何發送'player'移動?我沒有看到你的問題中存在任何明顯的錯誤,但是可能有一些代碼正在執行(例如直接設置'x'和'y'值)。 – Gliderman

+0

我已經添加了觸摸開始功能,我用它來允許用戶觸摸並移動玩家區塊aroun – spigen