2014-03-07 41 views
0

我正在使用IOS SpriteKit,並想知道是否有某種方式將客戶端數據添加到精靈節點?如何將客戶端數據添加到SKNode/SKSpriteNode?

例如,我想具體的行爲附加到一個節點,附加屬性,與其他節點等關係

我不願意SKNode子類,因爲這將出現打破模型/視圖/控制器模型中節點只是「視圖」。

目前我正在保持控制器對象的單獨層次結構,但這感覺很笨拙,並且它在性能方面並不是很好。

什麼是最佳實踐?

+0

我發現最好是在它自己的類中實現特定於節點的行爲。但是,如果您只想將信息存儲在控制器對象可以作出決策的基礎上,則可以使用userData屬性。 – ZeMoon

回答

0

子類化在這方面不會改變任何東西。你仍然保留完整的功能,並且什麼也不破。事實上,我認爲如果你正在製作一款大型遊戲,這幾乎是不可避免的。

但如果你真的不想再使用用戶數據: SKNode -> userData

0

所有SKNode類提供了userData屬性,它可以用來出於這樣的目的。

您可以編寫一個Objective-C類別,通過它可以添加其他屬性而不需要子類。下面是一個成熟的模式

接口:

#import "YourCustomObject.h" 

@interface SKNode (customObject) 
@property (nonatomic) YourCustomObject* yourCustomObject; 
@end 

實現:

static NSString* YourCustomObjectUserDataKey = @"YourCustomObjectUserDataKey"; 

@implementation SKNode (customObject) 
-(NSMutableDictionary*) internal_getOrCreateUserData 
{ 
    NSMutableDictionary* userData = self.userData; 
    if (userData == nil) 
    { 
     userData = [NSMutableDictionary dictionary]; 
     self.userData = userData; 
    } 

    return userData; 
} 

-(void) setYourCustomObject:(YourCustomObject*)customObject 
{ 
    NSMutableDictionary* userData = [self internal_getOrCreateUserData]; 
    [userData setObject: customObject forKey:YourCustomObjectUserDataKey]; 
} 

-(YourCustomObject*) yourCustomObject 
{ 
    NSMutableDictionary* userData = [self internal_getOrCreateUserData]; 
    return (YourCustomObject*)[userData objectForKey:YourCustomObjectUserDataKey]; 
} 
@end 

替換YourCustomObject與您的實際類名。

該類別可以擴展爲託管多個屬性,當然,您不必爲每個屬性編寫單獨的類別。該類別不一定要在SKNode上,如果你需要一個額外的屬性,但只在SKSpriteNode上,你可以將它作爲SKSpriteNode上的一個類別。

很多時候您需要訪問YourCustomObject中的擁有節點。

由於這個原因,提供一個初始化方法和/或屬性將擁有節點作爲輸入是個好主意。我更喜歡只讀屬性和自定義初始值設定項,因爲通常您不希望所有者在整個對象的整個生命週期中都進行更改。非常重要:此屬性必須爲weak才能創建保留週期。

@interface YourCustomObject 
@property (weak, readonly) SKNode* owningNode; 
+(instancetype) customObjectWithOwningNode:(SKNode*)owningNode; 
@end 

@implementation YourCustomObject 
+(instancetype) customObjectWithOwningNode:(SKNode*)owningNode 
{ 
    return [[self alloc] initWithOwningNode:owningNode]; 
} 
-(id) initWithOwningNode:(SKNode*)owningNode 
{ 
    self = [super init]; 
    if (self) 
    { 
     _owningNode = owningNode; 
    } 
    return self; 
} 
@end 

然後,您可以創建和節點類中指定您的自定義對象:

YourCustomObject* customObject = [YourCustomObject customObjectWithOwningNode:self]; 
self.yourCustomObject = customObject; 
+0

謝謝 - 這非常有幫助。我已經結束了分類作爲一個快速解決方案。在SKNode上閱讀時我錯過了userData! – RikMaxSpeed

0

雖然這裏的其他答案已經提到,您可以使用userData字典任意鍵值,讓我補充說你很好地繼承了SKNode,因爲SpriteKit首先不是MVC(或者至少不是UIKit的方式)。

SKNode小號設計適合普通遊戲架構(零部件陣列和朋友),而且實際上是對自己的模型,視圖或控制器。例如,SKNode不是可顯示對象,但可以保存關於遊戲實體/狀態或其他子節點的信息。

相關問題