Есть ли способ достичь того, что я спрашиваю? После 2,5 часов
В поисках я еще ничего не придумала. Просто найти решение
для анимационных кадров.
Кажется, вам нужна переменная, значением которой является другая переменная, чтобы вы могли перебирать набор иваров. Я могу придумать два способа сделать что-то вроде того, что вы просите.
Первый способ - использовать адрес каждой переменной, то есть указатель на каждую переменную. Поскольку сами указатели являются скалярными значениями, а не объектами, вам необходимо использовать массив в стиле C:
CCSprite *ivars[] = {&dinosaur1_c, &dinosaur2_c, &dinosaur3_c, &dinosaur4_c};
for (int i = 0; i < 4; i++) {
*(ivars[i]) = [dinoSprites objectAtIndex:i];
}
Второй способ заключается в использовании кодирования значения ключа. Создайте имя каждого ивара в виде строки, а затем используйте его в качестве ключа при вызове -setValue:forKey:
следующим образом:
NSString *name;
for (int i = 0; i < [dinoSprites count]; i++) {
name = [NSString stringWithFormat:@"dinosaur%d_c", i];
[self setValue:[dinoSprites objectAtIndex:i] forKey:name];
}
Все это говорит: Я настоятельно рекомендую вам не использовать ни один из двух предыдущих подходов к вашей проблеме. Вполне вероятно, что есть гораздо лучшие решения вашей проблемы, которые не предусматривают наличие отдельного ивара для каждого динозавра. У вас уже есть динозавры в массиве, поэтому нет необходимости создавать отдельный ivar для каждого. Как правило, если вы когда-либо создаете пронумерованные переменные, подобные этим, вам, вероятно, следует отступить и переосмыслить то, что вы делаете - нумерация ваших переменных является сильным сигналом о том, что вы должны использовать вместо этого массив.
Итак, в вашем случае я не вижу причин, по которым вы не могли бы использовать массив, который у вас уже есть, везде в вашем коде. Вместо dinosaur6_c
вы, очевидно, можете использовать [dinoSprites objectAtIndex:6]
. Но вы действительно очистите свой код, если подумаете о способах обработки всех динозавров одним и тем же кодом, так что вы никогда не будете жестко кодировать конкретные признаки в своем массиве. Например, если вам нужно установить каждый динозавр в отдельную позицию, есть как минимум два хороших способа сделать это. Одним из них является вычисление позиции, если это возможно, на основе индекса. Вы можете сделать это, если вы раскладываете динозавров обычным способом, как на сетке 3 x n:
for (int i = 0; i < [dinoSprites count]; i++) {
int row = i / DINOS_PER_ROW;
int column = i % DINOS_PER_ROW;
CGPoint position = CGPointMake(row * rowHeight, column * columnWidth);
[[dinoSprites objectAtIndex:i] setPosition:position];
}
Если позиция каждого динозавра не вычисляется по его индексу в массиве, то вы, вероятно, в настоящее время жестко программируете позиции в своем коде. Вы можете очистить это, по крайней мере, переместив позиции в массив, и, возможно, прочитав этот массив из файла данных. Это сделает ваш код намного короче, проще для понимания и проще в обслуживании:
NSArray *positions = [NSArray arrayWithContentsOfURL:someURL]; // read positions from a property list
NSAssert([positions count] >= [dinoSprites count], @"Not enough positions!");
for (int i = 0; i < [dinoSprites count]; i++) {
CGPoint position = [[positions objectAtIndex:i] pointValue];
[[dinoSprites objectAtIndex:i] setPosition: position;
}
Конечно, я просто использую положение спрайта здесь в качестве примера. Вы можете сделать то же самое с любым атрибутом, который вы хотите применить к динозавру, и вы можете сделать их все сразу. Вместо массива positions
, который вы загружаете из списка свойств, вы можете загрузить массив словарей, где каждый словарь содержит ряд атрибутов (цвет, любимая еда, скорость, уровень голода и т. Д.).