我正在Spritekit中创建一个游戏,我试图以一种方式设置我的游戏,当一个玩家失去所有生命时,他们必须等待30分钟才能恢复他们的生命,这样他们就可以再玩一次。我尝试使用NSTimer执行此操作,但我认为UINotification将更有效,因为无论应用程序是在后台终止,正在使用还是未使用,我都希望此计时器能够运行。我在设置时遇到了问题。
到目前为止,当用户到达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);
}
}
当我到达GameOverScene时,alarm.firedate在NSLog中正确显示但是当我关闭我的应用并重新启动它时,它在我的视图控制器中显示为null并且从不触发。无论用户是否使用该应用程序,如何在安排通知后让我的应用程序自动更新用户在后台的生活?它应该在我的应用代表中运行吗?
某些类型的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);
}
我非常感谢任何可以提供帮助的人。
编辑:对以下答案的回应
我为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:threeNewMinutes]进行比较,我希望我不要过分思考这个问题,而是从另一个角度来看。我不需要保存[NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes]的原始日期;当它最初被调用时,如果应用程序终止并且计时器再次运行代码,则将其与调用代码的原始时间进行比较,并且不会重置NSDate并将其与用户重新启动时的30分钟进行比较应用程序和计时器再次开始。
即。 7:15
NSDate comparison to update = [NSDate dateWithTimeIntervalSinceNow:thirtyMinutes];
被调用。计时器设置为在7:45更新生命。
7:30用户终止他们的应用并在7:35
重新启动它当NSTimer再次运行时,从现在起30分钟后,它将时间从7:35重置为30分钟?如果是这种情况,我将如何保存原始日期?请让我知道,请记住,我仍然是Objective C
的初学者答案 0 :(得分: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
基本上只是一个字典(可以接受标量而不必自己打包),只要您的应用程序已安装,它就会持续存在。