2014-06-01 22 views
23

Her iki saniyede bir, ekranımda bulunan bir HUD üzerinde puanı tek tek artıracak olan bir zamanlayıcıyı nasıl oluşturabilirim?SpriteKit - Bir zamanlayıcı oluşturma

@implementation MyScene 
{ 
    int counter; 
    BOOL updateLabel; 
    SKLabelNode *counterLabel; 
} 

-(id)initWithSize:(CGSize)size 
{ 
    if (self = [super initWithSize:size]) 
    { 
     counter = 0; 

     updateLabel = false; 

     counterLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; 
     counterLabel.name = @"myCounterLabel"; 
     counterLabel.text = @"0"; 
     counterLabel.fontSize = 20; 
     counterLabel.fontColor = [SKColor yellowColor]; 
     counterLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; 
     counterLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeBottom; 
     counterLabel.position = CGPointMake(50,50); // change x,y to location you want 
     counterLabel.zPosition = 900; 
     [self addChild: counterLabel]; 
    } 
} 
+0

Neden güncelleştirme (currentTime) yöntemini geçersiz kılmıyorsunuz? "sahne bir görünümde sunulduğu ve duraklatılmadığı sürece çerçeve başına tam olarak bir kez çağrılır" – OhadM

cevap

56

için continueIncrementingScore ayarlamak veya Grand Central Sevk (GCD, yani herhangi dispatch_... yöntemi) thes çünkü Zamanlama yöntemleri bir düğümün, sahnenin veya görünümün paused durumunu göz ardı eder. Üstelik oyun döngüsünde hangi noktada yürütüldüğünüzü bilmiyorsunuz, bu da kodunuzun gerçekte ne yaptığına bağlı olarak çeşitli sorunlara neden olabilir.

Sprite Kit'te zamana dayalı bir şey gerçekleştirmenin yalnızca iki yaptırım yolu, SKScene update: yöntemini kullanmak ve zaman tutmak için geçirilen currentTime parametresini kullanmaktır.

Veya daha yaygın sadece bir bekleme eylemi ile başlayan bir eylem dizisini kullanır:

[node runAction:[SKAction repeatActionForever:[SKAction sequence:@[wait, run]]]]; 

Alternatif olarak performSelector:onTarget: kullanabilirsiniz yerine:

id wait = [SKAction waitForDuration:2.5]; 
id run = [SKAction runBlock:^{ 
    // your code here ... 
}]; 
[node runAction:[SKAction sequence:@[wait, run]]]; 

Ve defalarca kod çalıştırmasına runBlock: veya SKScene update: yöntemini taklit etmeniz gerekiyorsa ve bunu iletime nasıl ileteceğinizi bilmiyorsanız veya iletimin sakıncalı olduğu durumlarda, kullanın.

Ayrıntılar için bkz. SKAction reference.


GÜNCELLEME: defalarca kod çalıştırmasına Swift

Swift 3

let wait = SKAction.wait(forDuration:2.5) 
let action = SKAction.run { 
    // your code here ... 
} 
run(SKAction.sequence([wait,action])) 

Swift 2

let wait = SKAction.waitForDuration(2.5) 
let run = SKAction.runBlock { 
    // your code here ... 
} 
runAction(SKAction.sequence([wait, run])) 

Aund kullanılarak Kod örnek:

Kullanılabilir Swift yılında
runAction(SKAction.repeatActionForever(SKAction.sequence([wait, run]))) 
+0

@ LearnCocos2D Works mükemmel bir dispatch_after olduğu için " – user3578149

+2

sabit yazım hatası, tekrar örneği eklendi – LearnCocos2D

+0

Bunu Swift'e nasıl çeviririm? –

-3

Aşağıdaki kod yeni bir iş parçacığı oluşturur ve ana iş parçacığı üzerinde bir şey yapmadan önce 2 saniye bekler: Bu benim HUD var kodudur

BOOL continueIncrementingScore = YES; 

dispatch_async(dispatch_queue_create("timer", NULL);, ^{ 
    while(continueIncrementingScore) { 
     [NSThread sleepForTimeInterval:2]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // this is performed on the main thread - increment score here 

     }); 
    } 
}); 

zaman bunu durdurmak istiyoruz - sadeceNSTimer, performSelector:afterDelay: kullanmayın Sprite Kit yılında NO

+1

hatalı örnek!" Sadece diğer kullanıcıların hatalarını önlemek için, üçüncü satırda sözdizimi hatalarını durdurmak için kapalı bir ayraç eklemenizi öneririm. – LearnCocos2D

5

: Yukarıda hızlı örneği alındı ​​ve saat için başına sıfır ilave ettik

var timescore = Int() 
var actionwait = SKAction.waitForDuration(0.5) 
      var timesecond = Int() 
      var actionrun = SKAction.runBlock({ 
        timescore++ 
        timesecond++ 
        if timesecond == 60 {timesecond = 0} 
        scoreLabel.text = "Score Time: \(timescore/60):\(timesecond)" 
       }) 
      scoreLabel.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun]))) 
5

.

func updateClock() { 
    var leadingZero = "" 
    var leadingZeroMin = "" 
    var timeMin = Int() 
    var actionwait = SKAction.waitForDuration(1.0) 
    var timesecond = Int() 
    var actionrun = SKAction.runBlock({ 
     timeMin++ 
     timesecond++ 
     if timesecond == 60 {timesecond = 0} 
     if timeMin/60 <= 9 { leadingZeroMin = "0" } else { leadingZeroMin = "" } 
     if timesecond <= 9 { leadingZero = "0" } else { leadingZero = "" } 

     self.flyTimeText.text = "Flight Time [ \(leadingZeroMin)\(timeMin/60) : \(leadingZero)\(timesecond) ]" 
    }) 
    self.flyTimeText.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun]))) 
}