Ios 如何将客户端数据添加到SKNode/SKSpriteNode?
我正在使用Ios 如何将客户端数据添加到SKNode/SKSpriteNode?,ios,model-view-controller,sprite-kit,skspritenode,sknode,Ios,Model View Controller,Sprite Kit,Skspritenode,Sknode,我正在使用IOS SpriteKit,想知道是否有办法将客户端数据添加到sprite节点 例如,我希望将特定行为附加到节点、附加属性、与其他节点的关系等 我不愿意将SKNode作为子类,因为这样会破坏模型/视图/控制器模型,其中节点只是“视图” 目前,我保留了一个单独的控制器对象层次结构,但这感觉很笨拙,而且在性能方面也不是很好 什么是最佳实践?子类化在这方面不会改变任何东西。您仍然保留了完整的功能,并且什么也没有破坏。事实上,我认为如果你正在进行一场大型比赛,这几乎是不可避免的 但如果您确实不
IOS SpriteKit
,想知道是否有办法将客户端数据添加到sprite节点
例如,我希望将特定行为附加到节点、附加属性、与其他节点的关系等
我不愿意将SKNode
作为子类,因为这样会破坏模型/视图/控制器模型,其中节点只是“视图”
目前,我保留了一个单独的控制器对象层次结构,但这感觉很笨拙,而且在性能方面也不是很好
什么是最佳实践?子类化在这方面不会改变任何东西。您仍然保留了完整的功能,并且什么也没有破坏。事实上,我认为如果你正在进行一场大型比赛,这几乎是不可避免的 但如果您确实不想使用userData:
所有SKNode类都提供了一个可用于此目的的属性 您可以编写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
中的所属节点
因此,最好提供一个初始值设定项和/或属性,将所属节点作为输入。我更喜欢只读属性和自定义初始值设定项,因为通常您不希望在对象的整个生命周期中更改所有者。非常重要:此属性必须弱
,才能不创建保留周期
@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;
虽然这里的其他答案已经提到您可以使用
userData
字典来处理任意键值,但我要补充的是,您可以对SKNode
s进行子类化,因为SpriteKit一开始就不是MVC(或者至少在UIKit的意义上不是)
SKNode
s被设计为适合常见的游戏架构(组件模式和好友),实际上可以是模型、视图或控制器<代码>SKNode例如,它不是一个可显示的对象,但可以保存有关游戏实体/状态或其他子节点的信息。我发现最好实现特定于其自身类中节点的行为。但是,如果您只想在节点中存储信息,控制器对象可以根据这些信息做出决策,那么可以使用userData属性。谢谢-这非常有用。我最终将其细分为一个快速解决方案。我在SKNode上读取时错过了用户数据!