2015-05-27 52 views
0

我在Spritekit中創建了一款遊戲,並且我嘗試設置我的遊戲的方式是,當玩家失去他們所有的生命時,他們必須等待30分鐘才能獲得他們的一生恢復,以便他們可以再次玩。我嘗試使用NSTimer來做到這一點,但我認爲UINotification將會更有效,因爲我希望這個計時器能夠運行,不管應用程序是否被終止,在後臺使用或不被使用。儘管如此,我仍然遇到了問題。使用UILocalNotification恢復遊戲生命

我有下面的代碼編寫迄今爲止,當用戶到達GameOverScene

-(instancetype)initWithSize:(CGSize)size { 
if (GameLives < 5) { 
alarm = [[UILocalNotification alloc] init]; 
     alarm.fireDate = [NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes]; 
     alarm.timeZone = [NSTimeZone localTimeZone]; 
     [[UIApplication sharedApplication] scheduleLocalNotification:alarm]; 
     alarm.repeatInterval = NSCalendarUnitHour; 

     NSLog(@"AlarmFireDate = %@", alarm.fireDate); 
} 
} 

的alarm.firedate顯示正確的NSLog的,當我到達GameOverScene但是當我關閉我的應用程序並重新啓動它,它在我的視圖控制器中顯示爲空,並且從不觸發。如何讓我的應用程序在通知安排後自動更新用戶的後臺,而不管用戶是否使用該應用程序?它應該在我的應用程序委託中運行嗎?

應該像下面的某種類型的NSDate比較運行的地方?

if ([[NSDate date] compare:allarm.fireDate] == NSOrderedDescending) { 
    GameLives = GameLives + 1; 
    NSLog(@"SUCCESS"); 
    NSLog(@"COUNT = %lu", (long)GameLives); 
} 
else if ([[NSDate date] compare:allarm.fireDate] == NSOrderedAscending){ 
    GameLives = GameLives + 1; 
    NSLog(@"FAILURE"); 
    NSLog(@"COUNT = %lu", (long)GameLives); 
} 
else if ([[NSDate date] compare:allarm.fireDate] == NSOrderedSame){ 
    NSLog(@"SAME"); 
    NSLog(@"COUNT = %lu", (long)GameLives); 

} 

我非常感謝任何能提供幫助的人。

編輯:響應對Answers低於

我寫的的NSTimer和當遊戲達到GAMEOVER現場的計時器開始下面的代碼。

-(void)restoreLives{ 

    thirtyNewMinutes = 60 * 30; 
    update = [NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes]; 

if ([[NSDate date] compare:update] == NSOrderedDescending) { 
    NSLog(@"date1 is later than date2"); 
    NSLog(@"SUCCESS"); 
    NSLog(@"CurrentDate: %@", [NSDate date]); 
    // LifeText = @"Restored"; 
    GameLives = GameLives + 1; 
    NSLog(@"LIVES = %ld", (long)GameLives); 
//   NSLog(@"Level 2 HighScore, %d", _Level1HighScoreNumber); 
} else if ([[NSDate date] compare:update] == NSOrderedAscending) { 
    NSLog(@"date1 is earlier than date2"); 
    NSLog(@"FAILURE"); 
    NSLog(@"CurrentDate: %@", [NSDate date]); 
    NSLog(@"LIVES = %ld", (long)GameLives); 
    //  Lives = 5; 
    //  NSLog(@"dates are the same"); 
} 

if (GameLives < 4){ 
    [LifeTimer invalidate]; 
} 

然後我創建了一個NSTimer來運行該方法。

-(void)CheckTime{ 
LifeTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(restoreLives) userInfo:nil repeats:YES]; 
} 

我將如何得到它來保存你說的目標時間?

而且,希望我不會過度這個想法,但從另一個角度來看,如果我想比較當前的NSDate和[NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes];我不需要保存[NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes]的原始日期;當它最初被調用時,如果應用程序終止並且計時器再次運行代碼,它會將其與原始代碼的調用時間進行比較,並且不會重置NSDate,並將其與用戶重新啓動應用程序時的30分鐘進行比較並且定時器再次開始。

即7:15

NSDate comparison to update = [NSDate dateWithTimeIntervalSinceNow:thirtyMinutes]; 

被調用。定時器設置爲在7點45分更新生命。

7:30用戶終止他們的應用程序並重新啓動它在7:35

當的NSTimer再次運行不會重置爲從7:35,因爲它得有30分鐘,現在30分鐘的時間?如果是這種情況,我會如何去保存原始日期?請讓我知道,請記住我仍然是初學者Objective C

+0

爲什麼要使用通知?只需跟蹤應該添加生活的時間。使用NSTimer在那個時候關閉。如果用戶關閉了應用程序並稍後重新啓動,則您可以查看保存的關閉時間,並在有剩餘時間的情況下重新設置計時器,否則您會授予新的生命。 – rmaddy

+0

感謝您的回覆,但是如何在應用終止時保存原始NSDate或目標時間?你介意提供一些示例代碼嗎? – John

+0

將它存儲在'NSUserDefaults'中。 – rmaddy

回答

1

如果您想告知用戶某些內容,並且可以使用可用於跟蹤您需要的信息,但這可能不是您做計時工作的最佳解決方案。如果用戶禁用了應用程序的通知,則會破壞您的功能。相反,當涉及到跟蹤基於時間的事件時,最好依靠日期比較和定時器。

當您的應用程序處於打開狀態時,您應該使用NSTimer觸發您需要執行的操作,我認爲您已經介紹了該操作。

當您的應用程序轉到後臺或終止時,您應該將目標時間保存在某種持久性存儲中(例如,NSUserDefaults)。當您的應用程序重新啓動或從後臺返回時,應該與該日期進行比較,然後啓動計時器或觸發您的代碼,以使計時器觸發自己。

嘗試使用此方法保存/恢復日期:

// Save the date with the key "NextFireDate" 
[[NSUserDefaults standardUserDefaults] setObject:nextFireDate forKey:@"NextFireDate"]; 
// This forces the values to be saved by the system, which normally only happens periodically 
[NSUserDefaults standardUserDefaults] synchronize]; 

... 

// Retrieve the date with the key "NextFireDate" 
NSDate *nextFireDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"NextFireDate"]; 

你會打電話來,第一,只要你去後臺/結束(也無效當前的定時器)和第二,當你完成啓動或返回從後臺(並用檢索日期開始一個新計時器)。 NSUserDefaults基本上只是一個字典(可以接受標量而不必自己裝箱),只要安裝了應用程序,該字典就會一直存在。

+0

感謝您的回覆,但您將如何去節約目標時間?你介意提供一些示例代碼嗎? – John

+0

請看下面我寫的回覆,因爲評論部分不會讓我寫出所有想寫的字符 – John

+0

那麼你會把這段代碼放在應用程序代理中嗎?每當這個方法被調用?或兩者?? – John