Swift путь
Вы можете использовать didSet свойство наблюдателя, чтобы изменить скорость игры на основе текущего счета:
import SpriteKit
class GameScene: SKScene {
var score:Int = 0 {
didSet{
if score % 10 == 0 {
gameSpeed += 0.5
}
label.text = "Score : \(score), Speed : \(gameSpeed)"
}
}
var gameSpeed:Double = 1.0
var label:SKLabelNode = SKLabelNode(fontNamed: "ArialMT")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
label.text = "Score : \(score), Speed : \(gameSpeed)"
label.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidX(frame))
label.fontSize = 18
addChild(label)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
score++
}
}
из документов:
didSet вызывается сразу после сохранения нового значения.
Итак, сразу после установки новой оценки вы должны обновить переменную gameSpeed
.
Objective-C путь
В Objective-C не такая вещь, которая может обеспечить точно такое же поведение, как наблюдателей собственности didSet и willSet Свифта. Но есть еще способы, например, вы можете переопределить сеттер счётом, как и это:
#import "GameScene.h"
@interface GameScene()
@property(nonatomic, strong) SKLabelNode *label;
@property(nonatomic, assign) NSUInteger score;
@property(nonatomic, assign) double gameSpeed;
@end
@implementation GameScene
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
NSLog(@"Scene's initWithSize: called");
if(self = [super initWithCoder:aDecoder]){
/*
Instance variables in Obj-C should be used only while initialization, deallocation or when overriding accessor methods.
Otherwise, you should use accessor methods (eg. through properties).
*/
_gameSpeed = 1;
_score = 0;
NSLog(@"Variables initialized successfully");
}
return self;
}
-(void)didMoveToView:(SKView *)view {
self.label = [SKLabelNode labelNodeWithFontNamed:@"ArialMT"];
self.label.fontSize = 18;
self.label.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
self.label.text = [NSString stringWithFormat:@"Score : %lu, Speed %f", self.score, self.gameSpeed];
[self addChild:self.label];
}
//Overriding an actual setter, so when score is changed, the game speed will change accordingly
-(void)setScore:(NSUInteger)score{
/*
Make sure that you don't do assigment like this, self.score = score, but rather _score = score
because self.score = somevalue, is an actual setter call - [self setScore:score]; and it will create an infinite recursive call.
*/
_score = score;
if(_score % 10 == 0){
self.gameSpeed += 0.5;
}
// Here, it is safe to to write something like self.score, because you call the getter.
self.label.text = [NSString stringWithFormat:@"Score : %lu, Speed %f", self.score, self.gameSpeed];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.score++;
}
@end
Или, я думаю, вы можете сделать то же самое с помощью KVO, но для примера из-за простоты, вы можете просто переопределить сеттер. Или может быть, вы могли бы просто сделать пользовательский метод, который позволит увеличить разрыв в счете, обрабатывать обновления логику gameSpeed, и обновить скорость, если необходимо:
//Whenever the player scores, you will do this
[self updateScore: score];
Таким образом, вы будете иметь дополнительное определение метода, который должен быть вызван при игрок забивает, в сравнении с этим (при условии, что показатель сеттер в переопределяется):
self.score = someScore;
это действительно до вас.
Надеюсь, что это имеет смысл, и это помогает!
EDIT:
Я изменил initWithSize:
к initWithCoder
, потому что initWithSize
не вызывается, когда сцена загружается из SKS, который, вероятно, как вы делаете это, из-за того, что в Xcode 7 сцена загружается по умолчанию из файла .sks.
Можете ли вы дать мне синтаксис didSet для объектного c? – ccdev
@codev О, извините, я не заметил тег Obj-C. В Obj-C по умолчанию таких методов нет, которые обеспечивают то же поведение, что и наблюдатели свойств willSet и didSet ... Но есть и другие способы достижения подобного поведения. В ближайшее время обновит мой ответ. – Whirlwind