- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对正在开发的演示游戏有疑问。我想要做的就是在游戏进入后台时暂停游戏,并在它变为事件状态时重新启动它。我已经尝试过此链接中的解决方案 https://stackoverflow.com/questions/19014012/sprite-kit-the-right-way-to-multitask
1 : SpriteKit- the right way to multitask和这个链接 SpriteKit - how to correctly pause and resume app
和其他一堆,但我没有成功。我什至在应用程序委托(delegate)中尝试了以下操作:
#import "AppDelegate.h"
#import <SpriteKit/SpriteKit.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
- (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;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (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;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
什么也没有发生。我在我的场景中暂停和取消暂停如下:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:_bgLayer];
[self moveZombieToward:touchLocation];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if (node == _pauseButton) {
[_pauseButton setTexture:[SKTexture textureWithImageNamed:@"pausebutton"]];
_pauseButtonPressed = YES;
_playButtonPressed = NO;
self.scene.paused = YES;
}
if (node == _playButton) {
[_playButton setTexture:[SKTexture textureWithImageNamed:@"playButton"]];
_playButtonPressed = YES;
_pauseButtonPressed = NO;
self.scene.paused = NO;
}
}
编辑:
- (void)moveZombieToward:(CGPoint)location
{
[self startZombieAnimation];
_lastTouchLocation = location;
CGPoint offset = CGPointSubtract(location, _zombie.position);
CGPoint direction = CGPointNormalize(offset);
_velocity = CGPointMultiplyScalar(direction, ZOMBIE_MOVE_POINTS_PER_SEC);
}
- (void)update:(NSTimeInterval)currentTime
{
if (_lastUpdateTime) {
_dt = currentTime - _lastUpdateTime;
} else {
_dt = 0;
}
_lastUpdateTime = currentTime;
if (_pauseButtonPressed) {
_lastUpdateTime = 0;
return;
}
最佳答案
收到您的代码。天哪,我讨厌僵尸康茄舞:)但这对我来说也是一个很好的学习教程。你所有的代码看起来都很好。至少我看不出有什么不妥。根据我插入的几个 NSLog,游戏可以正确暂停/取消暂停。根据 RW 的 iOS Games by Tutorials,您也以正确的方式暂停/取消暂停。第 481 页(顺便说一句,这本书绝对很棒,我强烈推荐它)。
我认为暂停功能无法正常工作的原因是游戏中的 Action 是基于时间的。例如:
_dt = currentTime - _lastUpdateTime;
在 _dt 行之后不久调用移动 Sprite
[self moveSprite:_zombie velocity:_velocity];
其中包括行
CGPoint amountToMove = CGPointMultiplyScalar(velocity, _dt);
取消暂停游戏,将导致角色 Action 被大大夸大,因为从游戏最初暂停时可能已经过去了很多时间。
您遇到的意外结果是由游戏逻辑而非您的编程技能引起的。为了补救这个特定的应用程序以通过暂停正常运行,我建议在更新方法中将移动更改为增量更新(例如 x=x+1),而不是使用基于时间的计算移动。
更新:包括非基于时间的移动代码
//
// touch anywhere on the screen to move the object to that location
//
@implementation MyScene
{
SKSpriteNode *object1;
CGPoint destinationLocation;
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
[self createObject];
destinationLocation = CGPointMake(300, 150);
}
return self;
}
-(void)createObject
{
object1 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
object1.position = CGPointMake(300, 150);
object1.zRotation = 1;
[self addChild:object1];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
destinationLocation = [touch locationInNode:self.scene];
}
-(void)update:(CFTimeInterval)currentTime
{
float x = fabs(object1.position.x - destinationLocation.x);
float y = fabs(object1.position.y - destinationLocation.y);
float divider = 0;
if(x > y)
{
divider = x;
} else
{
divider = y;
}
float xMove = (x/divider)*2; // you can change the 2 to any value you want.
float yMove = (y/divider)*2; // just make sure both x & y are multiplied by the same value
if(object1.position.x > destinationLocation.x)
object1.position = CGPointMake(object1.position.x-xMove, object1.position.y);
if(object1.position.x < destinationLocation.x)
object1.position = CGPointMake(object1.position.x+xMove, object1.position.y);
if(object1.position.y > destinationLocation.y)
object1.position = CGPointMake(object1.position.x, object1.position.y-yMove);
if(object1.position.y < destinationLocation.y)
object1.position = CGPointMake(object1.position.x, object1.position.y+yMove);
}
@end
关于ios - 如何在 sprite kit 中处理多任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22940745/
我是一名优秀的程序员,十分优秀!