     }
   }
   
-  // TODO: Add code for player movement here
+  // TODO: Uncomment code for player movement here
+  func movePlayerInDirection(direction: MoveDirection) {
+    
+    switch gameState {
+    case GameState.WaitingForFirstTap:
+      
+      // Start playing
+      switchToPlaying()
+      movePlayerInDirection(direction)
+      break
+      
+    case GameState.Playing:
+      
+      // Determine if the new position is a valid position
+      var newPlayerGridCol = playerGridCol
+      var newPlayerGridRow = playerGridRow
+      
+      switch direction {
+      case .Forward:
+        newPlayerGridRow += 1
+        break;
+      case .Backward:
+        newPlayerGridRow -= 1
+        break
+      case .Left:
+        newPlayerGridCol -= 1
+        break
+      case .Right:
+        newPlayerGridCol += 1
+      }
+      
+      // Determine the type of tile at new position
+      let type = levelData.gameLevelDataTypeForGridPosition(column: newPlayerGridCol, row: newPlayerGridRow)
+      
+      if type == GameLevelDataType.Invalid || type == GameLevelDataType.Obstacle {
+        // Invalid - do not move
+        // println("Invalid move")
+        
+      } else {
+        // Valid - move
+        // println("Valid move to \(newPlayerGridCol), \(newPlayerGridRow)")
+        
+        playerGridCol = newPlayerGridCol
+        playerGridRow = newPlayerGridRow
+        
+        // Move the player to new position
+        var newPlayerPosition = levelData.coordinatesForGridPosition(column: playerGridCol, row: playerGridRow)
+        newPlayerPosition = SCNVector3(x: newPlayerPosition.x, y: 0.1, z: newPlayerPosition.z)
+        
+        // Move the player using an action
+        let moveAction = SCNAction.moveTo(newPlayerPosition, duration: 0.2)
+        let jumpUpAction = SCNAction.moveBy(SCNVector3(x: 0.0, y: 0.2, z: 0.0), duration: 0.1)
+        jumpUpAction.timingMode = SCNActionTimingMode.EaseInEaseOut
+        let jumpDownAction = SCNAction.moveBy(SCNVector3(x: 0.0, y: -0.2, z: 0.0), duration: 0.1)
+        jumpDownAction.timingMode = SCNActionTimingMode.EaseInEaseOut
+        let jumpAction = SCNAction.sequence([jumpUpAction, jumpDownAction])
+        
+        // Play the action
+        player.runAction(moveAction)
+        playerModelNode.runAction(jumpAction)
+        
+        // Play jump sound
+        if let overlay = view.overlaySKScene {
+          overlay.runAction(soundJump)
+        }
+      }
+      
+      break
+      
+    case GameState.GameOver:
+      
+      // Switch to tutorial
+      switchToRestartLevel()
+      break
+      
+    case GameState.RestartLevel:
+      
+      // Switch to new level
+      // switchToWaitingForFirstTap()
+      break
+      
+    default:
+      break
+    }
+    
+  }
   
 }
  func handleTap(gesture: UIGestureRecognizer) {
    if let tapGesture = gesture as? UITapGestureRecognizer {
      // TODO: Add code to do movement here
    }
  }
  

    self.rootNode.addChildNode(omniLight)
    
    // TODO: Add code to initialize player here
    let playerGridPosition = levelData.coordinatesForGridPosition(column: playerGridCol, row: playerGridRow)
    player = createPlayerAtPosition(position: SCNVector3(x: playerGridPosition.x, y: 0.1, z: playerGridPosition.z))
    self.rootNode.addChildNode(player)
    
    // TODO: Add code to create camera here
    camera = createCameraAtPosition(position: cameraOffsetFromPlayer)
    camera.constraints = [SCNLookAtConstraint(target: player)]
    player.addChildNode(camera)
    
    // Create nodes for level
    level = levelData.createLevelAtPosition(position: SCNVector3Zero)
    self.rootNode.addChildNode(level)
    
    // Create cars
    setupCarSpawnNodes()
    
    // Start the game
    switchToWaitingForFirstTap()
