2017-09-07 65 views
0

我正在尝试使用MapKitSpriteKit在一起,但我打了一个非常主要的墙。MKMapView覆盖SKSpriteNodes

我在我的GameScene中设置了我的地图,因为我不想覆盖它的场景,但是当我尝试将SpriteNode添加到视图时,它不显示。在减少地图的alpha值后,我可以看到精灵正在地图下面呈现。 更改zPosition并没有帮助,因为我假设像MKMapView这样的视图与SpriteKit对象位于不同的图层上。

基本上我试图做的是把SpriteKit元素放在我的MKMapView(如果可能的话,没有故事板 - 我试图以编程方式做所有事情)。我花了数小时试图在互联网上找到答案,但没有成功。

这是我GameScene

import UIKit 
    import SpriteKit 
    import GameplayKit 
    import MapKit 
    import CoreLocation 

    class GameScene: SKScene, MKMapViewDelegate, CLLocationManagerDelegate { 

     let locationManager = CLLocationManager() 

     var map = MKMapView() 

     let healthBar = SKSpriteNode(imageNamed: "Square") 
     let maxHealthBar = SKSpriteNode(imageNamed: "Square") 

     var UID = String() 
     var ref = DatabaseReference() 

     static var username = String() 
     static var health = Int() 
     static var maxHealth = Int() 

     var width = CGFloat() 
     var right = CGFloat() 
     var left = CGFloat() 
     var top = CGFloat() 
     var bot = CGFloat() 
     var margin = CGFloat() 
     var middleX = CGFloat() 
     var middleY = CGFloat() 

     var maxBarWidth = CGFloat() 

     override func didMove(to view: SKView) { 

      map.frame = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) 
      map.delegate = self 
      map.showsScale = false 
      map.showsPointsOfInterest = false 
      map.showsUserLocation = true 
      map.showsBuildings = true 
      map.isZoomEnabled = false 
      map.isScrollEnabled = false 
      map.isPitchEnabled = false 
      map.isRotateEnabled = false 

      let region = MKCoordinateRegionMakeWithDistance((locationManager.location?.coordinate)!, 400, 400) 

      map.setRegion(region, animated: false) 

      print("region:", map.region) 

      locationManager.requestWhenInUseAuthorization() 

      if (CLLocationManager.locationServicesEnabled()) { 

       locationManager.delegate = self 
       locationManager.desiredAccuracy = kCLLocationAccuracyBest 
       locationManager.startUpdatingLocation() 

      } 

      view.addSubview(map) 

      width = frame.width 
      right = frame.width 
      left = frame.width - frame.width 
      top = frame.height 
      bot = frame.height - frame.height 
      margin = frame.width/75 
      middleX = frame.width/2 
      middleY = frame.height/2 

      maxBarWidth = width - margin * 2 
      let maxBarHeight = CGFloat(30) 
      let healthBarWidth = width - margin * 2 
      let barHeight = maxBarHeight * 0.75 

      maxHealthBar.anchorPoint = CGPoint(x: 0.0, y: 0.5) 
      maxHealthBar.position = CGPoint(x: middleX, y: top - margin - maxBarHeight/2) 
      maxHealthBar.size = CGSize(width: maxBarWidth, height: maxBarHeight) 
      maxHealthBar.color = UIColor.black 
      maxHealthBar.colorBlendFactor = 1.0 
      maxHealthBar.zPosition = 1.1 
      self.addChild(maxHealthBar) 

      healthBar.anchorPoint = CGPoint(x: 0.0, y: 0.5) 
      healthBar.position = CGPoint(x: middleX - healthBarWidth/2, y: maxHealthBar.position.y) 
      healthBar.size = CGSize(width: healthBarWidth, height: barHeight) 
      healthBar.color = UIColor.red 
      healthBar.colorBlendFactor = 1.0 
      healthBar.zPosition = 1000000 
      self.addChild(healthBar) 

      print("parent", healthBar.parent) 

     } 

     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
      for t in touches { 
       let location = t.location(in: self) 

       takeDamage(damage: 10) 

      } 
     } 

     func takeDamage(damage: Int) { 

      GameScene.health -= damage 

      updateHealth() 

     } 

     func updateHealth() { 

      let percentFull = CGFloat(GameScene.health/GameScene.maxHealth) 
      let healthWidth = maxBarWidth * percentFull 

      healthBar.size.width = healthWidth 

     } 

     func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { 
      map.setCenter((locationManager.location?.coordinate)!, animated: true) 
     } 

     override func update(_ currentTime: TimeInterval) { 
      // Called before each frame is rendered 
     } 
    } 

这里是我的GameViewController

import UIKit 
    import SpriteKit 
    import GameplayKit 

    class GameViewController: UIViewController { 

     override func viewDidLoad() { 
      super.viewDidLoad() 
     } 

     override func viewWillLayoutSubviews() { 
      super.viewWillLayoutSubviews() 

      if (SignInScene.signInLoaded == false) { 

       if let scene = GameScene(fileNamed: "GameScene") { 
        // Configure the view. 
        let skView = self.view as! SKView 
        skView.showsFPS = true 
        skView.showsNodeCount = true 

        /* Sprite Kit applies additional optimizations to improve rendering performance */ 
        skView.ignoresSiblingOrder = true 

        /* Set the scale mode to scale to fit the window */ 
        scene.size = skView.bounds.size 
        scene.scaleMode = .aspectFill 

        skView.presentScene(scene) 
       } 

      } 

     } 

     override var shouldAutorotate: Bool { 
      return false 
     } 

     override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 
      if UIDevice.current.userInterfaceIdiom == .phone { 
       return .portrait 
      } else { 
       return .portrait 
      } 
     } 

     override func didReceiveMemoryWarning() { 
      super.didReceiveMemoryWarning() 
      // Release any cached data, images, etc that aren't in use. 
     } 

     override var prefersStatusBarHidden: Bool { 
      return false 
     } 
    } 

我就这一个非常卡住,将不胜感激任何帮助! 在此先感谢!

+0

你真的应该试着保持设计和代码分离,如果你在你的小项目中养成了一种习惯,当你最终设计更大的应用程序时,你会发现它对你来说更容易。另外,当要求像SO这样的地方提供帮助时,它会变得更少显示代码,这意味着其他人可以更好地帮助你。 – Knight0fDragon

+0

@ Knight0fDragon我会记住这一点 –

回答

0

你的问题是在你的视图控制器的UIView的层次结构,

这里是你的项目是什么样子:

控制器
--SKView
---- SKScene
- MKMapView

您需要将您的层次结构更改为

控制器
--MKMapView
--SKView
---- SKSceneView

我建议这样做您的故事板里面,这样就可以保持设计和代码分离。

你已经改变了你的层次结构后,你需要做以下在GameScene:

view.allowsTransparency = true 
view.backgroundColor = .clear 
backgroundColor = .clear 

这会给你一个没有背景色,这意味着你的地图将下方显示的视图和场景它。

现在如果你想触摸事件打MKMapView,而不是SKView,那么你需要在你的MKMapView禁用userInteractionEnabled,或者从你的SKView通过触摸事件的地图。

+0

这可能是一个简单的问题,但我还没有使用过很多故事板......如何在故事板中获得SKView/SKSceneView? –

+0

如果您使用默认模板,则已经有一个。他们为你做的 – Knight0fDragon

+0

一个叫做视图?如果我试图按照上面建议的层次结构添加地图视图作为GameViewController的子项,它会删除其所有其他子项?我把它放在错误的地方? –