В настоящее время у меня есть игра SpriteKit с целью сбивания врагов. Я реализовал обнаружение конфликтов для него, и он работает нормально. Но мне нужно внедрить здоровье для врагов. Враги постоянно генерируются и продолжают двигаться, поэтому вы никогда не знаете, какой узел должен быть. Я попытался объявить свой пользовательский узел класса в методе didBeginContact, а затем присвоить его bodyA, а затем изменить его значение для здоровья, но это кажется бесполезным, поскольку я просто создаю новый узел (тот же показывает NSLog). Я пробовал приписывать объявление, но все равно не повезло. Некоторые исследования по этой теме, но не нашли ничего, что мне подходит. В настоящее время я не могу предоставить исходный код для того, что я сделал, но я надеюсь, что то, что я попросил, можно объяснить. Пожалуйста, подтолкните меня в правильном направлении.Доступ к объекту узла
ответ
Каждый SKSpriteNode имеет userData NSMutableDictionary, который может использоваться для хранения данных (объектов).
Вы должны сначала инициализировать словарь так:
myNode.userData = [NSMutableDictionary dictionary];
Затем вы можете назначить на него данные, как это:
float myHealth = 100.0;
NSString *myX = [NSString stringWithFormat:@"%f",myHealth];
[myNode.userData setValue:myX forKey:@"health"];
Для чтения данных вы делаете это:
float myHealth = [[myNode.userData objectForKey:@"health"] floatValue];
Я использовал float в моем примере, но вы можете использовать все, что захотите. Просто помните, что вы не можете хранить примитивы наподобие float, int, long и т. Д. Непосредственно. Они должны быть преобразованы в NSNumber, NSString и т. Д.
Это, как говорится, Стивен J прав с его предложением. Вы должны подклассифицировать SKSpriteNode для своих врагов и иметь здоровье как свойство класса. Подкласс намного проще работать в долгосрочной перспективе и дает большую гибкость по сравнению с использованием userData.
Чтобы проиллюстрировать некоторые объектно-ориентированные концепции, на которые ссылаются Стивен J и sangony, я добавил для вас некоторый код.
Подкласс SKNode
определит новый класс объектов, который наследует всю функциональность от SKNode
. Основное преимущество здесь заключается в том, что вы можете реализовать пользовательские свойства (например, здоровье) и пользовательскую логику (например, снизить это здоровье).
@interface EnemyNode : SKSpriteNode
- (void)getHit;
- (BOOL)isDead;
@property (nonatomic) CGFloat health;
@end
@implementation EnemyNode
- (instancetype)initWithColor:(UIColor *)color size:(CGSize)size {
self = [super initWithColor:color size:size];
if (self) {
self.health = 100.f;
}
}
- (void)getHit {
self.health -= 25.f;
}
- (BOOL)isDead {
return self.health <= 0;
}
@end
В вашей сцене, вы будете использовать его в качестве такового:
EnemyNode *newEnemy = [[EnemyNode alloc] initWithColor:[UIColor blueColor] size:CGSizeMake(50,50)];
[self addChild:newEnemy];
...
[newEnemy getHit];
if ([newEnemy isDead]) {
[newEnemy removeFromParent];
}
Для дополнительной иллюстрации, вы можете взглянуть на my answer to a similar question.
Подкласс спрайт, добавьте здоровье к этому классу, вместо этого используйте свой подкласс. Но что еще более важно, я бы упрочил ваше понимание некоторых концепций ОО. –