2014-07-25 9 views
5

मैंने खुद को गेम देव को पढ़ाने के लिए एक छोटी तेज़/स्प्राइटकिट परियोजना शुरू कर दी है। यह एक आइसोमेट्रिक मानचित्र से शुरू होता है, जिसे मैं आकर्षित करने में कामयाब रहा। लेकिन मुझे मानचित्र के विभिन्न टाइलों पर एक सटीक स्पर्श स्थान प्राप्त करने में परेशानी हो रही है। यह काम करता है, लेकिन जगह से थोड़ी दूर है, और यह लगातार प्रतीत नहीं होता है।स्विफ्ट स्प्राइटकिट आइसोमेट्रिक मानचित्र स्पर्श स्थान

class PlayScene: SKScene { 

let map = SKNode() 
    override func didMoveToView(view: SKView) { 

     let origin = view.frame.origin 
     let mapOrigin = CGPointMake(origin.x + self.frame.width/4, origin.y - self.frame.height/4) 


     let mapConfig: Int[][] = 

     [[0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0, 0], 
     [2, 2, 2, 2, 1, 2, 2, 2], 
     [0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0, 0]] 

    drawMap(mapConfig, mapOrigin: mapOrigin) 
} 

के साथ:

यहाँ मेरी कार्य हैं

func drawMap(mapConfig:Int[][], mapOrigin:CGPoint) 
{ 
    let tileHeight:CGFloat = 25.5 
    let numColumns:Int = 8 
    let numRows:Int = 8 

    var position = mapOrigin 
    var column: Int = 0 
    var row: Int = 0 

    for column = 0; column < numColumns; column++ 
    { 
     for row = 0; row < numRows; row++ 
     { 
      position.x = mapOrigin.x + CGFloat(column) * tileHeight 
      position.y = mapOrigin.y + CGFloat(row) * tileHeight 
      let isoPosition = twoDToIso(position) 
      placeTile(isoPosition, mapConfig: mapConfig[row][column]) 
     } 
    } 
    self.addChild(map) 
} 

func placeTile(position:CGPoint, mapConfig:Int) 
{ 
switch mapConfig 
    { 
    case 0: 
     let sprite = SKSpriteNode(imageNamed:"grassTile") 
     sprite.position = position 
     sprite.setScale(0.1) 
     sprite.name = "\(position)" 
     self.map.addChild(sprite) 
    case 1: 
     let sprite = SKSpriteNode(imageNamed:"roadTile") 
     sprite.position = position 
     sprite.setScale(0.1) 
     sprite.name = "\(position)" 
     self.map.addChild(sprite) 
    default: 
     let sprite = SKSpriteNode(imageNamed:"roadTileLTR") 
     sprite.position = position 
     sprite.setScale(0.1) 
     sprite.name = "\(position)" 
     self.map.addChild(sprite) 
    } 
} 

और फिर मैं टाइल मैं (परीक्षण के लिए) स्पर्श छुपाना चाहते हैं:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) 
{ 
    for touch: AnyObject in touches 
    { 
     let locationNode = touch.locationInNode(self) 
     nodeAtPoint(locationNode).hidden = true 
    } 
} 

लेकिन यह करता है हमेशा सही टाइल छुपाएं नहीं। तो मुझे इससे कैसे निपटना चाहिए? क्या मेरा कोड मौलिक रूप से गलत है (संभव)? या क्या मुझे किसी भी तरह से आईएसओ निर्देशांक में स्थान बदलने की ज़रूरत है? या टाइल्स बिटमास्क के साथ खेलते हैं?

किसी भी मामले में आपकी मदद के लिए धन्यवाद!

उत्तर

6

मुझे आईएसओमेट्रिक मानचित्र के साथ एक ही समस्या थी।

समस्या यह है कि जिस नोड पर आप क्लिक करते हैं वह प्रदर्शित होने से बड़ा है (इसमें पारदर्शी भाग हैं)। इस मुद्दे के बेहतर स्पष्टीकरण के लिए my question here देखें।

यहाँ (खेद कोड ऑब्जेक्टिव-सी में है) मैं इसे कैसे हल किया है:

1. बनाएँ एक CGPathRef टाइल के किनारों (tileSize बनावट का आकार जा रहा है) के बाद। यह कोड नियमित आइसोमेट्रिक टाइल्स के लिए है, हेक्सागोनल नहीं बल्कि विचार समान है।

// ObjC 
-(CGPathRef)createTextureFrame:(CGSize)tileSize 
{ 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path, NULL, 0, -(self.tileSize.height/2)); 
    CGPathAddLineToPoint(path, NULL, (self.tileSize.width/2), 0); 
    CGPathAddLineToPoint(path, NULL, 0, (self.tileSize.height/2)); 
    CGPathAddLineToPoint(path, NULL, -(self.tileSize.width/2), 0); 
    CGPathCloseSubpath(path); 
    return path; 
} 

// Swift 
func createTextureFrame(tileSize:CGSize) -> CGPathRef { 
    CGMutablePathRef path = CGPathCreateMutable() 
    CGPathMoveToPoint(path, nil, 0, -(self.tileSize.height/2)) 
    CGPathAddLineToPoint(path, nil, (self.tileSize.width/2), 0) 
    CGPathAddLineToPoint(path, nil, 0, (self.tileSize.height/2)) 
    CGPathAddLineToPoint(path, nil, -(self.tileSize.width/2), 0) 
    CGPathCloseSubpath(path) 
    return path 
} 

2. एक फ़ंक्शन बनाएं जो जांचता है कि कोई दिए गए बिंदु CGPathRef (textureFrame) के अंदर है या नहीं।

// ObjC 
-(BOOL)isPointOnNode:(CGPoint)point 
{ 
    return CGPathContainsPoint(textureFrame, NULL, point, YES); 
} 

// Swift 
func isPointOnNode(point:CGPoint) -> Bool { 
    return CGPathContainsPoint(textureFrame, nil, point, YES) 
} 

3. प्रत्येक नोड्स छुआ जांच करें कि कौन textureFrame हम कर रहे हैं।

// ObjC 
UITouch *touch = [touches anyObject]; 
NSArray *nodes = [self nodesAtPoint:[touch locationInNode:self]]; 
for (SKNode *node in nodes) 
{ 
    CGPoint locationInNode = [touch locationInNode:node]; 
    if ([node isPointOnNode:locationInNode]) 
    { 
     node.hidden = YES; 
    } 
} 

// Swift 
var touch = touches.anyObject() as UITouch 
var nodes = self.nodesAtPoint(touch.locationInNode(self)) 
for node in nodes as [SKNode] { 
    var locationInNode = touch.locationInNode(node) 

    if node.isPointOnNode() { 
     node.hidden = true 
    } 
} 

मैं अगर यह सबसे अच्छा समाधान नहीं जानता लेकिन यह बहुत अच्छा काम करता है। मुझे आशा है कि यह मदद करता है :)

संपादित करें: जोड़ा स्विफ्ट कोड

+0

बढ़िया है, धन्यवाद के संस्करण। मैं इसे जल्द ही कोशिश करूंगा, और यदि मैं इसे काम कर सकता हूं, तो स्विफ्ट समकक्ष पोस्ट करेगा। –

+2

चूंकि मैंने इसे पोस्ट किया है, इसलिए मैंने स्विफ्ट सीखना शुरू कर दिया। मैंने अपना जवाब अपडेट किया;) मैंने लिखा है कि स्मृति से और मैं अभी इसका परीक्षण नहीं कर सकता, इसलिए कुछ गलतियां हो सकती हैं – Heyfara

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