【发布时间】:2023-03-09 13:42:01
【问题描述】:
我试图在代码中的任何地方搜索:解释文档在进入后台时会做什么,或者它是否有时会暂停,但无济于事 - 有人可以指导我按照推荐的方式去做到启用精灵套件的游戏中的背景?
我应该直接打电话给scene.paused = YES,或者我如何确认后台没有绘图,这样我就可以避免iOS 不允许我这样做?
谢谢!
【问题讨论】:
标签: background ios7 sprite-kit
我试图在代码中的任何地方搜索:解释文档在进入后台时会做什么,或者它是否有时会暂停,但无济于事 - 有人可以指导我按照推荐的方式去做到启用精灵套件的游戏中的背景?
我应该直接打电话给scene.paused = YES,或者我如何确认后台没有绘图,这样我就可以避免iOS 不允许我这样做?
谢谢!
【问题讨论】:
标签: background ios7 sprite-kit
正如here LearnCocos2D所说:
问题是当应用进入后台时 AVAudioSession 无法激活。
修复非常简单,也适用于 ObjectAL => 将 AVAudioSession 设置为在应用程序处于后台时处于非活动状态,并在应用程序进入前台时重新激活音频会话。
经过此修复的简化 AppDelegate 如下所示:
#import <AVFoundation/AVFoundation.h>
...
- (void)applicationWillResignActive:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// prevent audio crash
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// resume audio
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}
PS:此修复将包含在 Kobold Kit v7.0.3 中。
【讨论】:
对我来说,没有一个提供解决方案。我确实找到了另一种方法。
// In the AppDelegate
- (void)applicationWillResignActive:(UIApplication *)application
{
if ([self.window.rootViewController isKindOfClass:[GameViewController class]]) {
GameViewController *vc = (GameViewController*)self.window.rootViewController;
[vc pauseGame];
[vc.view addObserver:vc
forKeyPath:@"paused"
options:NSKeyValueObservingOptionNew
context:nil];
}
}
// In the GameViewController
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
SKView *skView = (SKView*)self.view;
MainGame *mainGame = (MainGame*)skView.scene;
if ([keyPath isEqualToString:@"paused"] &&
[[change objectForKey:NSKeyValueChangeNewKey] boolValue] == NO &&
[mainGame isGameInProgress]) {
[self.view removeObserver:self forKeyPath:@"paused" context:nil];
skView.paused = YES;
}
}
【讨论】:
我想知道为什么这个看似简单的解决方案会导致我在应用程序启动时崩溃,但这是因为我运行了 iAd。
所以,要记住一件事:@MassivePenguin 的回答有效,但如果你有 iAd 运行,你将不得不通过 subviews 获取 SKView,否则它(显然)会崩溃。
-(SKView*)getSKViewSubview{
for (UIView* s in self.window.rootViewController.view.subviews) {
if ([s isKindOfClass:[SKView class]]) {
return (SKView*)s;
}
}
return nil;
}
- (void)applicationWillResignActive:(UIApplication *)application {
SKView* view = [self getSKViewSubview];
if (view) {
view.paused = YES;
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
SKView* view = [self getSKViewSubview];
if (view) {
view.paused = NO;
}
}
【讨论】:
iPad 似乎可以后台运行,但 iPhone 在后台运行 sprite kit 游戏时肯定会崩溃。您必须手动执行此操作,自动魔法部分并不那么自动。
【讨论】:
SpriteKit 的文档确实还没有那么好,可能是因为它太新了,很少有开发人员实现它。 SpriteKit 应该在后台运行时暂停动画,但根据我的经验(和harrym17's),它会导致内存访问错误并完全退出应用程序而不是后台运行。
根据 Apple 开发者论坛,这似乎是 SpriteKit 中的一个已知错误(它并不总是在后台暂停动画,因为它应该)导致memory access errors as per harrym17's comment。这是一个对我有用的简短修复 - 我的应用程序在后台运行时一直崩溃,并且自从添加此代码后一切正常。
(感谢 Keith Murray 在 Apple 论坛上的代码;据我所知,他没有在 SO 上发布它)。
在AppDelegate.h,确保你导入了SpriteKit:
#import <SpriteKit/SpriteKit.h>
在AppDelegate.m 中,编辑您的applicationWillResignActive 方法:
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
// pause sprite kit
SKView *view = (SKView *)self.window.rootViewController.view;
view.paused = YES;
}
这是你的applicationDidBecomeActive 方法:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// resume sprite kit
SKView *view = (SKView *)self.window.rootViewController.view;
view.paused = NO;
}
显然,在通过AVAudioSession 播放音频时,在后台运行时会出现其他问题;提到了一种解决方法in this thread。
【讨论】:
Sprite Kit 移动到后台时会自动暂停其动画计时器 - 您无需担心您的应用会因此而被杀死。
【讨论】:
EXEC_BAD_ACCESS 错误 - 我的答案中的代码 似乎 已修复它,尽管我的应用程序目前确实没有那么复杂...