2016-01-17 31 views
2

我正在用Sprite Kit製作2D遊戲,並且我需要添加一種方法來在每50分之後加快遊戲速度。如何在每增加50分後加速Sprite Kit遊戲

我制定了一種方法,可以根據需要添加速度,但我必須在更新方法中每複製50個點,複製,粘貼和調整if語句。

我的解決方案的另一個問題是,我必須在加速後立刻給我的積分增加一個增量,因爲如果不是這個遊戲加速完成,儘管我不知道爲什麼。

這是到目前爲止我的解決方案:

// inside the update method 
// points are added when an enemy is destroyed 
// pointSpeed is the float variable that is used to change positions 

if (points == 4) { 
    pointSpeed++; 
    points++; 
} 
if (points == 8) { 
    pointSpeed++; 
    points++; 
} 
if (points == 12) { 
    pointSpeed++; 
    points++; 
} 

我想實現這個功能,而無需被迫手動完成所有增量和沒有遊戲加速不加分的增量。

回答

1

斯威夫特方式

可以使用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; 

這真的取決於你。

希望這是有道理的,它有幫助!

編輯:

我已經改變了initWithSize:initWithCoder,因爲當場景從SKS加載,這可能是你是如何做的,由於事實上initWithSize不叫,在Xcode中7場景默認從.sks文件加載。

+0

您可以向我提供目標c的didSet語法嗎? – ccdev

+0

@codev哦,對不起,我沒有注意到Obj-C標籤。在Obj-C中,默認情況下沒有這樣的方法提供與willSet和didSet屬性觀察者完全相同的行爲......但還有其他方法可以實現類似的行爲。很快會更新我的答案。 – Whirlwind

0

如果要定期更新速度,可以使用模數運算符 - 除以間隔後的餘數 - 如果該值等於零,則採取行動。 您發現遊戲加速完全的原因是,下次通過更新功能時,它仍然處於正確的分數級別,並且它只是增加了速度 - 您可以添加另一個變量來跟蹤是否準備好增加

// as part of class declaration 
var bReadyForIncrement : Bool = true 
let pointIncrement : Int = 4 // or whatever you need 


// inside the update method 
// points are added when an enemy is destroyed 
// pointSpeed is the float variable that is used to change positions 

if (points % 4) 
{ 
    if bReadyForIncrement 
    { 
     pointSpeed++; 
     bReadyForIncrement = false // set this to true wherever you add points 
    } 
} 
+2

如果遊戲速度僅取決於分數,那麼您不需要在每秒運行60次的更新方法中檢查該值。每次分數變化時,您都應該進行檢查和更改速度。 – Whirlwind

+0

我如何檢查bReadyForIncrement?或者更好,我怎樣才能把它再次設置爲真? – ccdev

+0

每當一個敵人被摧毀,你增加分數 - 只需設置bReadyForIncrement true – Russell

相關問題