2015-11-01 8 views
9

के साथ एक ग्रिड बनाएं स्प्राइटकिट 2 डी गेम इंजन का उपयोग कर grid like this को आकर्षित करने का सबसे अच्छा तरीका क्या होगा? आवश्यकताएँ:SpriteKit

  • इनपुट प्रोग्राम के स्तंभों और पंक्तियों (5x5, 10x3, 3x4 आदि) की संख्या।
  • SKSpriteNode या SKShapeNode जैसे कुछ का उपयोग करके प्रोग्रामेटिक रूप से ड्रा करें, क्योंकि square like this की छवियों का उपयोग करने से मुझे बहुत प्रभावी प्रतीत नहीं होता है।
  • वर्गों का एक निश्चित आकार होना चाहिए (मान लें कि प्रत्येक 40x40 है)।
  • ग्रिड लंबवत और क्षैतिज रूप से दृश्य में केंद्रित होना चाहिए।

मैं इस ग्रिड में विभिन्न वर्गों में चलने वाले खिलाड़ी के रूप में SKSpriteNode (छवि से) का उपयोग करने की योजना बना रहा हूं।
तो, मैं प्रत्येक वर्ग के केंद्रीय बिंदु (एक्स, वाई) के 2 आयामी सरणी में सहेज दूंगा और फिर उस स्थिति में प्लेयर की वर्तमान स्थिति से आगे बढ़ जाऊंगा। यदि आपके पास इसके लिए एक बेहतर सुझाव भी है, तो मैं इसे सुनना चाहता हूं।

मैं स्विफ्ट (अधिमानतः 2.1) में एक समाधान की सराहना करता हूं, लेकिन उद्देश्य-सी भी करेगा। केवल आईफोन उपकरणों पर इसका उपयोग करने की योजना बना रहा है।
मेरा प्रश्न करीब to this one है। किसी भी मदद की सराहना की है।

+0

क्यों नहीं का उपयोग CGContext (क्वार्ट्ज) लाइनों आकर्षित करने के लिए? CGPaths को देखो। आपको केवल एक ही देखभाल करने की आवश्यकता है यह सुनिश्चित कर लें कि निर्देशांक सह-शामिल हों। आखिरकार, sprites sprites हैं ... –

+0

हे, माइकल एल! सलाह के लिये धन्यवाद। मुझे नहीं पता था कि उन CGPaths को एक कुशल तरीके से कैसे उपयोग करें, लेकिन 0x141E के उत्तर ने इसे पूरी तरह से किया। – Alex

+0

क्या ग्रिड को छेद स्क्रीन पर आवश्यकता होती है क्योंकि आपको स्क्रीन के लेंस को विभाजित करना चाहिए, जो आप चाहते हैं कि ग्रिड के लंगर को फेंक दें। – Cing

उत्तर

19

मेरा सुझाव है कि आप ग्रिड को SKSpriteNode के बनावट के रूप में कार्यान्वित करें क्योंकि स्प्राइट किट एक ड्रॉ कॉल में ग्रिड प्रस्तुत करेगा। कैसे एक ग्रिड बना सकते हैं और ग्रिड

class GameScene: SKScene { 
    override func didMove(to: SKView) { 
     if let grid = Grid(blockSize: 40.0, rows:5, cols:5) { 
      grid.position = CGPoint (x:frame.midX, y:frame.midY) 
      addChild(grid) 

      let gamePiece = SKSpriteNode(imageNamed: "Spaceship") 
      gamePiece.setScale(0.0625) 
      gamePiece.position = grid.gridPosition(row: 1, col: 0) 
      grid.addChild(gamePiece) 
     } 
    } 
} 

अद्यतन करने के लिए एक खेल टुकड़ा जोड़ने के लिए है

class Grid:SKSpriteNode { 
    var rows:Int! 
    var cols:Int! 
    var blockSize:CGFloat! 

    convenience init?(blockSize:CGFloat,rows:Int,cols:Int) { 
     guard let texture = Grid.gridTexture(blockSize: blockSize,rows: rows, cols:cols) else { 
      return nil 
     } 
     self.init(texture: texture, color:SKColor.clear, size: texture.size()) 
     self.blockSize = blockSize 
     self.rows = rows 
     self.cols = cols 
    } 

    class func gridTexture(blockSize:CGFloat,rows:Int,cols:Int) -> SKTexture? { 
     // Add 1 to the height and width to ensure the borders are within the sprite 
     let size = CGSize(width: CGFloat(cols)*blockSize+1.0, height: CGFloat(rows)*blockSize+1.0) 
     UIGraphicsBeginImageContext(size) 

     guard let context = UIGraphicsGetCurrentContext() else { 
      return nil 
     } 
     let bezierPath = UIBezierPath() 
     let offset:CGFloat = 0.5 
     // Draw vertical lines 
     for i in 0...cols { 
      let x = CGFloat(i)*blockSize + offset 
      bezierPath.move(to: CGPoint(x: x, y: 0)) 
      bezierPath.addLine(to: CGPoint(x: x, y: size.height)) 
     } 
     // Draw horizontal lines 
     for i in 0...rows { 
      let y = CGFloat(i)*blockSize + offset 
      bezierPath.move(to: CGPoint(x: 0, y: y)) 
      bezierPath.addLine(to: CGPoint(x: size.width, y: y)) 
     } 
     SKColor.white.setStroke() 
     bezierPath.lineWidth = 1.0 
     bezierPath.stroke() 
     context.addPath(bezierPath.cgPath) 
     let image = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return SKTexture(image: image!) 
    } 

    func gridPosition(row:Int, col:Int) -> CGPoint { 
     let offset = blockSize/2.0 + 0.5 
     let x = CGFloat(col) * blockSize - (blockSize * CGFloat(cols))/2.0 + offset 
     let y = CGFloat(rows - row - 1) * blockSize - (blockSize * CGFloat(rows))/2.0 + offset 
     return CGPoint(x:x, y:y) 
    } 
} 

और यहाँ:

निर्धारित करने के लिए जो ग्रिड यहाँ कैसे ऐसा करने के लिए की एक उदाहरण है वर्ग को छुआ था, इसे init

self.isUserInteractionEnabled = true 

और इस Grid वर्ग के लिए:

override func touchesBegan(_ touches: Set<UITouch>, withEvent event: UIEvent?) { 
    for touch in touches { 
     let position = touch.location(in:self) 
     let node = atPoint(position) 
     if node != self { 
      let action = SKAction.rotate(by:CGFloat.pi*2, duration: 1) 
      node.run(action) 
     } 
     else { 
      let x = size.width/2 + position.x 
      let y = size.height/2 - position.y 
      let row = Int(floor(x/blockSize)) 
      let col = Int(floor(y/blockSize)) 
      print("\(row) \(col)") 
     } 
    } 
} 
+1

वास्तव में समाधान की सराहना करते हैं, @ 0x141E! यह वही है जो मैं खोज रहा था। वास्तव में कूल करें कि आपको एक ड्रॉ में ग्रिड प्रस्तुत करने के लिए 'स्प्राइटकिट' कैसे मिला। अतिरिक्त 'ग्रिडपोशन' फ़ंक्शन के लिए धन्यवाद, यह मेरे मन में बेहतर है। – Alex

+0

आप ग्रिड में प्रत्येक बॉक्स को कैसे अलग करेंगे? मान लें कि मैं ग्रिड क्लास के बच्चों के रूप में skspritenodes जोड़ता हूं, ग्रिड में प्रत्येक बॉक्स के लिए मैं स्पर्श का उपयोग कैसे करूं? – Boggartfly

+0

स्पर्श जोड़ना 'ग्रिड' कक्षा में बीज काम नहीं करता है। आपको इसे नोड इंस्टेंस में जोड़ना होगा जो ग्रिड में जोड़ा जाता है। मुझे संदेह है क्योंकि यह ग्रिड में बॉक्स को पूरे ग्रिड स्प्राइट के बच्चे के रूप में जोड़ रहा है।तो इसके बजाय हमें प्रत्येक बॉक्स के लिए एक अलग वर्ग में 'एसकेएसप्रेट नोड' का उत्तराधिकारी होना चाहिए और वहां 'स्पर्शों के किनारे' को ओवरराइड करना होगा। यही मेरे लिए काम किया है। मैंने इसे कठिन तरीके से समझ लिया। आपके उत्तर के लिए धन्यवाद। – Boggartfly

संबंधित मुद्दे