这里在我的代码中我试图更新标签(SKSpriteNode),而时间倒计时使用精灵工具包,但我不想使用NSTimer,所以我找到了这个解决方案,但问题是waitForDuration方法只工作第一次更新方法运行。我想使用精灵工具包每秒运行一段代码(更新标签和变量)。任何帮助表示赞赏。
priority
答案 0 :(得分:2)
我使用类似的技术来扼杀火灾率之类的东西,它适用于支持帧更新的任何游戏引擎,您可以在其中获得增量时间(即此帧与最后一帧之间的时间) )。这几乎是我见过的所有游戏引擎除了 SpriteKit,它给你当前时间(我认为这是游戏开始以来的时间,但没关系),所以你需要计算delta时间自己。
你需要使用一个实例变量来保存当前的计时器值,并从那个时间开始递减 delta time ,当它是<= 0.0
时,就可以开始它了。如果你想重复它,那么重置倒计时。
例如:
#define TIMER_VALUE 1.0
@interface MyClass()
{
CFTimeInterval _lastFrameTime;
CFTimeInterval _timer;
}
@end
@implementation MyClass()
- (instancetype)init
{
self = [super init];
if (self) {
_lastFrameTime = 0.0;
_timer = TIMER_VALUE;
}
return self;
}
-(void)update:(CFTimeInterval)currentTime
{
if (_lastFrameTime == 0.0) // Might need < DBL_EPSILON here?
_lastFrameTime = currentTime; // First frame
CFTimeInterval deltaTime = currentTime - _lastFrameTime;
_timer -= deltaTime;
if (_timer <= 0.0) {
[self doThing];
_timer = TIMER_VALUE;
}
_lastFrameTime = currentTime;
}
@end
答案 1 :(得分:1)
使用SKActions可以做到这一点:
#import "GameScene.h"
@interface GameScene ()
@property (nonatomic, strong) SKLabelNode *label;
@property (nonatomic, assign) NSUInteger timeLeft;
@end
@implementation GameScene
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
_timeLeft = 90;
_label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
}
return self;
}
//Override timeLeft's setter in order to update label's text property after each assignment to property is made.
-(void)setTimeLeft:(NSUInteger)timeLeft {
_timeLeft = timeLeft;
_label.text = [NSString stringWithFormat:@"Current score %lu", (unsigned long)_timeLeft];
}
-(void)didMoveToView:(SKView *)view {
//How much to wait
SKAction *wait = [SKAction waitForDuration:1];
__weak typeof(self) weakSelf = self;
//What to do
SKAction *block = [SKAction runBlock:^{
weakSelf.timeLeft -= 1;
}];
//Sequence to repeat - look at this like it represents one step (wait and update what needed)
SKAction *sequence = [SKAction sequence:@[wait, block]];
self.label.text = [NSString stringWithFormat:@"Current score %lu", (unsigned long)self.timeLeft];
self.label.fontSize = 45;
self.label.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:self.label];
//Repeat the step above forever
[self runAction:[SKAction repeatActionForever:sequence] withKey:@"countdown"];
}
@end
代码非常直接(并且已经评论很多),但让我再次解释它是如何工作的:
timeLeft
变量。这会自动(通过重写的setter)更新标签的文本。 要停止此操作,您可以通过密钥访问它,然后将其删除,如下所示:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if ([self actionForKey:@"countdown"]){
[self removeActionForKey:@"countdown"];
}
}