2014-07-25 24 views
5

Kendime oyun devini öğretmek için küçük bir hızlı/spritekit proje yapmaya başladım. Çizmeyi başarabildiğim izometrik bir haritayla başlıyor. Ancak haritanın farklı döşemelerinde hassas bir dokunma noktası elde etme konusunda sorun yaşıyorum. Çalışıyor, ancak biraz bozuk ve tutarlı görünmüyor. Ben (test için) dokunma karo gizlemek istediğinizSwift Spritekit izometrik harita dokunma yeri

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) 
    } 
} 

Ve sonra:

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) 
} 

olarak: Burada

benim fonksiyonları

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

Ama öyle her zaman doğru döşemeyi gizlemez. Peki bununla nasıl başa çıkmalıyım? Kodum temelde yanlış mı (mümkün)? Veya konumu bir şekilde iso koordinatlarına dönüştürmem gerekiyor mu? Ya da fayanslar bitmask ile oynamak?

Her durumda yardımlarınız için teşekkürler!

cevap

6

İzometrik harita ile benzer bir sorun yaşadım.

Sorun, tıklattığınız düğümün görüntülendiğinden daha büyük olmasıdır (saydam kısımları vardır). Sorunun daha iyi bir açıklaması için my question here'a bakın. İşte

(üzgün kod Objective-C olan) ben onu çözdüm nasıl:

1.Create karo kenarlarını (tileSize doku boyutu olmak üzere) izleyen bir CGPathRef. Bu kod, altıgen değil, düzenli izometrik karolar içindir ancak fikir aynıdır.
// 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.Create belirli bir noktada CGPathRef (textureFrame) içinde olup olmadığını kontrol eden bir fonksiyonu

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

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

3.For her

Girdik textureFrame hangi kontrol düğümleri dokundu.

// 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 
    } 
} 

En iyi çözüm ise bilmiyorum ama iyi çalışıyor.

+0

Büyük kod, teşekkürler Katma Swift sürümü: Ben :) yardımcı

Düzenleme umuyoruz. Bunu yakında deneyeceğim, eğer çalışabilirsem, Swift eşdeğerini yayınlayacağım. –

+2

Bunu yayınladığımdan beri Swift'i öğrenmeye başladım. Cevabımı güncelledim;) Bunu bellekten yazdım ve şu anda test edemiyorum, bu yüzden bazı hatalar olabilir – Heyfara

İlgili konular