2016-10-17 2 views
0

현재 저는 조이스틱 앱을 작성 중이며 라이더 센서의 윤곽선을 표시하려고합니다. 스프라이트 키트를 사용하고 있지만 뒤떨어져 있습니다. 나는 각 정도는 내 스프라이트를 모두 초기화하고 (벽)스위프트를 사용하여 720 데이터 포인트를 그리는 방법

물체를 명중 곳의 거리를 나타냅니다 그것은 나 360 개 데이터 포인트에 너무 많은 메모리를

내 LIDAR 센서 반환을 차지한다고 가정하고 didMoveToView의 키트 노드가 더 좋은 방법이 있나요? 아마도 init에서? 내가 너무 많은 스프라이트 키트 노드 (720+)

을 만드는 오전 것처럼

내가 360 선을위한 것이며 360 (거리) 데이터 포인트를하기 때문에 720 개 스프라이트 키트 노드를 만드는 오전

보인다

또한 내 앱을 통해 스트리밍 비디오를 제공 할 계획입니다. Sprite Kit가 가장 좋은 방법입니까?

<code>Simulator Screen Shot</code>

import Foundation 
import UIKit 
import SpriteKit 

class GameScene: SKScene { 


    var visual = SKSpriteNode() 

    let button = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 100, height: 50), cornerRadius: 10) 

    var distances: [Int] = [2601, 2600, 33, 2608, 2601, 2594, 2625, 2633, 2637, 2651, 2656, 2666, 2683, 2690, 2705, 2712, 2712, 2739, 2752, 53, 1103, 1060, 1019, 980, 944, 911, 33, 851, 826, 801, 777, 757, 737, 718, 701, 683, 667, 654, 53, 486, 470, 457, 448, 440, 432, 424, 416, 409, 403, 396, 389, 383, 378, 372, 367, 362, 357, 353, 348, 344, 340, 336, 333, 329, 326, 323, 319, 317, 314, 311, 309, 307, 305, 303, 301, 299, 298, 297, 295, 294, 293, 292, 291, 290, 290, 290, 290, 291, 293, 295, 303, 386, 383, 53, 350, 53, 53, 53, 53, 53, 3, 364, 362, 360, 356, 358, 355, 353, 351, 350, 349, 347, 345, 53, 53, 53, 308, 3, 309, 309, 312, 313, 315, 316, 319, 321, 53, 329, 332, 335, 332, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 670, 33, 706, 728, 750, 772, 799, 825, 856, 887, 925, 755, 749, 744, 739, 734, 730, 727, 722, 719, 716, 714, 634, 709, 706, 704, 703, 701, 699, 700, 695, 697, 697, 338, 696, 697, 696, 698, 698, 700, 702, 703, 705, 707, 710, 712, 714, 718, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 53, 3412, 3397, 3384, 53, 3538, 3603, 53, 2426, 2412, 2363, 2330, 2288, 2262, 2214, 2190, 2162, 2130, 53, 53, 53, 2807, 2631, 2408, 2638, 2607, 2601, 2562, 2534, 2515, 2496, 2478, 2462, 2445, 53, 53, 53, 1751, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 2643, 2643, 53, 2660, 53, 2528, 2523, 2221, 1955, 1684, 1677, 1684, 1694, 1705, 1202, 1204, 1211, 1217, 1225, 1233, 1239, 1249, 1259, 1270, 1280, 1289, 1280, 1011, 991, 977, 968, 966, 964, 968, 975, 984, 1003, 2, 53, 1297, 53, 53, 33, 1321, 1299, 1274, 1254, 1233, 1232, 1264, 1293, 3802, 53, 53, 53, 53, 53, 53, 53, 3, 53, 2878, 2870, 2848, 2821, 2803, 2788, 2769, 2753, 2740, 2708, 2711, 2701, 2682, 2656, 2664, 2644, 2644, 2631, 2626, 2616, 2610, 2604, 2605, 2605, 2600, 2598, 2603] 

    var scalex: [Double] = [] 
    var scaley: [Double] = [] 
    var disx: [Double] = [] 
    var disy: [Double] = [] 

    var somenodes = [SKSpriteNode()] 
    var newnodes = [SKShapeNode()] 

    override init(size: CGSize) { 

     print("this is in init!") 
     super.init(size: size) 
    } 

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

    let rotateAnalogStick = AnalogJoystick(diameter: 100) 

    override func didMoveToView(view: SKView) { 
     /* Setup your scene here */ 

     visual.color = UIColor.clearColor() 
     visual.size = CGSize(width: 350, height: 350) 
     visual.position = CGPointMake(frame.midX, frame.midY + 150) 
     addChild(visual) 


     for index in 0...356 { 

      var radians = Double(index) * M_PI/180.0 
      var x = Double(distances[index]) * cos(Double(radians)) 
      var y = Double(distances[index]) * sin(Double(radians)) 

      disx.append(x) 
      disy.append(y) 
     } 


     var path = CGPathCreateMutable() 
     var xmin: Double = Double(disx.minElement()!) 
     var xmax: Double = Double(disx.maxElement()!) 
     var ymin: Double = Double(disy.minElement()!) 
     var ymax: Double = Double(disy.maxElement()!) 

     var scale = max(xmax - xmin, ymax - ymin) 

     for index in 0...356 { 

      var radians = Double(index) * M_PI/180.0 
      var x = (Double(distances[index]) * cos(Double(radians))/scale) * 350 
      var y = (Double(distances[index]) * sin(Double(radians))/scale) * 350 

      print("(\(x),\(y))") 

      var mynode = SKSpriteNode() 
      mynode.color = UIColor.redColor() 
      mynode.size = CGSize(width: 2, height: 2) 

      let circlenode = SKShapeNode() 
      let circlePath = UIBezierPath(arcCenter: CGPoint(x: 0,y: 0), radius: CGFloat(5), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true) 
      circlenode.path = circlePath.CGPath 
      //change the fill color 
      circlenode.fillColor = UIColor.blueColor() 
      //you can change the stroke color 
      circlenode.strokeColor = UIColor.redColor() 
      //you can change the line width 
      circlenode.lineWidth = 0.5 
      circlenode.zPosition = 1 
      circlenode.position = CGPointMake(CGFloat(x), CGFloat(y)) 
      newnodes.append(circlenode) 

      CGPathMoveToPoint(path, nil, 0, 0) // from 
      CGPathAddLineToPoint(path, nil, CGFloat(x), CGFloat(y)) // to 

      let shape = SKShapeNode() 
      shape.path = path 
      shape.strokeColor = UIColor.purpleColor() 
      shape.lineWidth = 1 
      visual.addChild(shape) 
      visual.addChild(newnodes[index]) 
     } 

     let newscale = SKAction.scaleTo(0.1, duration: 0.5) 
     let fadein = SKAction.fadeInWithDuration(0.5) 
     let fadeout = SKAction.fadeOutWithDuration(0.5) 
     let outsequence = SKAction.sequence([fadeout]) 
     let insequence = SKAction.sequence([fadein]) 

     for index in 0...visual.children.count { 
//   visual.children[index].runAction(insequence) 
//   visual.children[index].runAction(repeatout) 
     } 

     button.fillColor = UIColor.blueColor() 
     button.position = CGPointMake(frame.midX - 50, frame.midY - 110) 

     addChild(button) 

     var mylabel = SKLabelNode() 
     mylabel.color = UIColor.blackColor() 
     mylabel.fontSize = 12 
     mylabel.fontName = "AvenirNext-Bold" 
     mylabel.text = "Contour Display" 
     mylabel.position = CGPointMake(50, 20) 
     mylabel.zPosition = 1 
     button.addChild(mylabel) 

     backgroundColor = UIColor.whiteColor() 
     physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) 

     rotateAnalogStick.position = CGPointMake(frame.midX + 5, rotateAnalogStick.radius + 60) 
     rotateAnalogStick.stick.color = UIColor.cyanColor() 
     rotateAnalogStick.substrate.color = UIColor.blackColor() 
     addChild(rotateAnalogStick) 

     rotateAnalogStick.trackingHandler = { data in 

      // cartesian to polar 
      var r = sqrt(pow(Double(data.velocity.x), Double(2)) + pow(Double(data.velocity.y), Double(2))) 
      var power = (r - 0)/(50 - 0) * (1-0) + 0 
      var theta = atan2(Double(data.velocity.y), Double(data.velocity.x)) // atan(Double(data.velocity.y/data.velocity.x)) // 
      var degrees = theta * (180.0/M_PI) 

      var packet = "" 
      var offset = 0.0 
      var rdirection = 0.0 
      var ldirection = 0.0 
      var rpower = 0.0 
      var lpower = 0.0 

      if (degrees >= 65 && degrees <= 115) { // move forward 

       rpower = power 
       lpower = power 

       rdirection = 1 
       ldirection = 1 

      } else if (degrees <= 0 && degrees >= -65) || (degrees >= 0 && degrees <= 65) { // move right 

       offset = 90 - degrees 
       rdirection = min(degrees, offset) 
       ldirection = max(degrees, offset) 

       rpower = (rdirection - 0)/(50 - 0) * (power-0) + 0 
       lpower = abs(1-rpower) 

       rdirection = -1 
       ldirection = 1 

      } else if (degrees <= -115 && degrees >= -180) || (degrees > 115 && degrees < 180) { // move left 

       offset = 90 - degrees 
       rdirection = min(degrees, offset) 
       ldirection = max(degrees, offset) 

       rpower = abs(1-rpower) 
       lpower = (rdirection - 0)/(50 - 0) * (power-0) + 0 

       rdirection = 1 
       ldirection = -1 

      } else if (degrees <= -65 && degrees >= -115) { // move down 

       rpower = power 
       lpower = power 

       rdirection = -1 
       ldirection = -1 
      } 

      packet = "\(rdirection) \(ldirection) \(rpower) \(lpower)" 

     } 

     view.multipleTouchEnabled = true 
    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     /* Called when a touch begins */ 

     for touch: AnyObject in touches { 
      // Get the location of the touch in this scene 
      let location = touch.locationInNode(self) 
      // Check if the location of the touch is within the button's bounds 
      if button.containsPoint(location) { 
       print("button tapped!") 
      } 
     } 

    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
    } 
} 
내가 SpriteKit 720 개 스프라이트 아무 문제를 쾅 수 있다고 생각하고 싶습니다
+0

악기를 사용하여 코드가 왜 느린 지 정확히 알아보십시오. 익숙한 지 확신 할 수 없지만 앱의 런타임 중 몇 퍼센트가 어떤 행에 소비되었는지 알려줄 수 있습니다. 나에게 이상한 한 가지 사실은 조이스틱 콜백에서 문자열을 보간하는 "패킷"이 자체적으로 이상하고 변수가 사용되지 않는다는 점입니다. –

+0

SKShapeNode 사용으로 인해 지연됩니다. 각 SKShapeNode에는 하나의 그리기 호출이 필요합니다. 비효율적입니다. 점에 SKSpriteNode를 사용해보십시오. 내가 무엇을 말하고 있는지 확인하려면 게임보기 컨트롤러에서 view.showsNodesCount = true로 설정하십시오. 이것이 첫 번째 최적화 일 것입니다. 다음으로 필요한 경우 풀링 (예 : 동일한 노드를 재사용하지만 앱의 기능에 따라 다름)입니다. – Whirlwind

+0

@ColinBarrett 제안에 감사드립니다. 내가 사용할 수있는 도구를 검색하면 정확히 내 응용 프로그램 속도를 늦추는 지 알 수 있습니다. – humblebeast

답변

1

. 인용 된 바와 같이 주요 문제는 SKShapeNode입니다.

당신이해야 할 일은 텍스쳐로 "도트"를 만드는 것입니다. 색상/윤곽선을 원한다면 텍스처에 넣으십시오. 또한 색이 지정된 직사각형을 사용하여 선을 만드십시오 (SKSpriteNode 일 수 있음). 원형 색이 여러 개인 경우 텍스처 아트지에 넣으십시오.

이렇게하면 SpriteKit으로 처리량을 향상시킬 수 있습니다.

didMoveToView에서이 작업을 수행하고 있습니다. 얼마나 자주 리프레시해야합니까? 데이터가 설정되고 하나의 차이가 변환 (예 : 회전, 크기 조절, 변환)하는 경우 다른 방법은 Quartz/Core Graphics를 사용하여 전체를 사전 렌더링 한 다음 렌더링을 변환하는 것입니다.

+0

감사합니다. 너의 답; 내 앱이 약 2-3 초마다 약 360 개의 데이터를 실시간으로 읽습니다. 그러나, 나는 얼마나 자주 내가 새로 고쳐야 할지를 조사 할 것이다. – humblebeast

관련 문제