2013-10-21 30 views
11

SpriteKit'i öğrenirken, küçük bir macera oyunu yapmaya çalışıyorum. Bir kahraman yaratıyorum ve sahneye ekledikten sonra, daha sonra, touchesBegan: sırasında, dokunmanın kahramandan kaynaklanıp kaynaklanmadığını tespit edip, buna göre harekete geçiyorum.Özel SKSpriteNode dokunma sırasında algılanmadı

Kahramanı SKSpriteNode olarak eklerseniz, dokunmatik onu algılar. Onu SKSpriteNode'un bir alt sınıfı olarak eklerseniz dokunma yapmaz! ekleyerek farkı:

_heroNode = [SKSpriteNode spriteNodeWithImageNamed:@"hero.png"]; 

vs

_heroNode = [[ADVHeroNode alloc] init]; 

init şuna benzer:

- (id) init { 
    if (self = [super init]) { 

     self.name = @"heroNode"; 
     SKSpriteNode *image = [SKSpriteNode spriteNodeWithImageNamed:@"hero.png"]; 
     [self addChild:image]; 
    } 
    return self; 
} 

SKSpriteNode bir alt sınıf o eklenir anlamında çalıştığı için kahraman ekleme sahne, ama dokunma onu algılamaz. Benim touchesBegan: şöyle görünür: bunun bir dik SKSpriteNode değil, kendi alt sınıf eklerken

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    /* Called when a touch begins */ 

    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInNode:self]; 
    SKNode *node = [self nodeAtPoint:location]; 
    if (YES) NSLog(@"Node name where touch began: %@", node.name); 

    //if hero touched set BOOL 
    if ([node.name isEqualToString:@"heroNode"]) { 
     if (YES) NSLog(@"touch in hero"); 
     touchedHero = YES; 
    } 
} 

Frustratingly, bu kod gayet güzel çalışıyor. Baska öneri?

cevap

22

İşte

Alt sınıf bu yöntem Dokunmalarda izlemek için düğüm gerektiren bir SKNode

SKNode, dolayısıyla self.userInteractionEnabled mülkiyet Hero'nuza alt sınıfı için bazı örnek yollarıdır.

@implementation HeroSprite 

- (id) init { 
    if (self = [super init]) { 
     [self setUpHeroDetails]; 
     self.userInteractionEnabled = YES; 
    } 
    return self; 
} 

-(void) setUpHeroDetails 
{ 
    self.name = @"heroNode"; 
    SKSpriteNode *heroImage = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"]; 
    [self addChild:heroImage]; 
} 


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint locationA = [touch locationInNode:self]; 
    CGPoint locationB = [touch locationInNode:self.parent]; 
    NSLog(@"Hit at, %@ %@", NSStringFromCGPoint(locationA), NSStringFromCGPoint(locationB)); 
} 

@end 

SKSpriteNode

öteki "kolay" yolu, sadece bir SKSpriteNode alt sınıfı için istiyorum. Bu, esas olarak, kullandığınız ile aynı şekilde çalışacaktır (Kahramanınızı alt sınıflara ayırmadan önce). Yani senin dokunuşlarınBegan, senin sorunun içinde kurulacak.

@implementation HeroSprite 

- (id) init { 
    if (self = [super init]) { 
     self = [HeroSprite spriteNodeWithImageNamed:@"Spaceship"]; 
     [self setUpHeroDetails]; 

    } 
    return self; 
} 

-(void) setUpHeroDetails { 
    self.name = @"heroNode"; 
} 

@end 
+0

Genel olarak SpriteKit ve Objective-C için yeni olmama rağmen, bu sınıfların bir örneğini nasıl oluşturduğumuzu görmüyorum? – Jide

+0

Bu kodu koydum, sadece normal bir SKSprite oluşturduğunuzda yaratın, ancak HeroSprite'i kullanın. – DogCoffee

+0

Bunu yapmanın harika yolu! Awesome – Septronic

0

ADVHeroNode'unuz, görüntü içermeyen bir SkNode veya SkSpriteNode'dur. Herhangi bir uzantıya sahip olmayacak, konuşacak noktaları var. NodeAtPoint tarafından bulunamayacaklar: ancak resim çocuğu SKSpriteNode olacaktır. Düğümün adını açıkça kontrol ettiğinizden, kontrol başarısız olur.

Görüntüye bir ad verebilir ve bunu kontrol edebilir ve ardından ADVHeronode örneğini almak için ebeveyne başvurabilirsiniz. Veya sadece node.parent adını doğrudan kontrol edin.

1

Yalnızca bu hareketli grafik üzerinde yalnızca bir dokunuş algılandı.

Bir Object SKSpriteNode oluşturduğunuzda, kendini denetler. Bu, bir dokunuş başladığında, bu nesnenin SKView değil bu dokunuşu alması anlamına gelir.

Bu dokunuşu algılamak isterseniz, bu kodu SKView üzerinde olmayan bu nesneye yazmanız gerekir. SKSpriteNode'da bir dokunma olduğunda SKView'de herhangi bir şey yapmak isterseniz, bunu yapmak için temsilci kullanabilirsiniz.

Neye cevap verdiğimi anlayamıyorsanız daha fazlasını sormaya çekinmeyin.

+0

altho, OP bunu hiç sormadı, bahsettiğiniz temsilci çözümünüzün kodunu görmek isterim. SKSpriteNode alt sınıfımda touchEnded'i başarılı bir şekilde kullanıyorum ancak SKView'da touchEnded yöntemini de tetiklemek istiyorum. Bu, alt sınıfta userInteractionEnabled özelliğini etkinleştirirseniz geçerli değildir. – stvn

3

Genellikle denetlemek istediğim sınıfı bulana kadar dokunmuş düğümün ebeveyni kontrol ediyorum. İşte bir kod parçacığı.

while (touchedNode.parent) 
    { 
     if ([touchedNode isKindOfClass:[GameObject class]]) 
      break; 
     else 
      touchedNode = (SKSpriteNode*)self.touchedNode.parent; 
    } 
+0

Kapağımdaki SKLabelNode'a dokunurken bir sorunum vardı, ancak bu satırı "touchedNode = (SKSpriteNode *) self.touchBeganNode.parent;" günümü kurtar. – Beto

+0

self.touchBeganözel bir değişkeni mi? – josef

+0

Evet, bu benim kodumdaydı ama sanırım dokunmaDeğil, ben sadece cevabı güncelledim. – membersheep

9

Bunu init yönteminize eklediğinizden emin olun.

self.userInteractionEnabled = YES; 

Bazı nedenlerden dolayı, bu, alt sınıfladığınızda varsayılan olarak etkinleştirilmez. En azından benim için sadece elle etkinleştirildiğinde çalıştı.

İlgili konular