Список действий динамической длины во время выполнения для последовательности

StackOverflow https://stackoverflow.com/questions/1030324

  •  06-07-2019
  •  | 
  •  

Вопрос

Cocos2D определяет статический метод 'actions' для класса Sequence следующим образом:

+(id) actions: (FiniteTimeAction *) action1, ... { /* omitted */ }

Как я могу составить список действий, которые нужно выполнить во время выполнения, возможно, прочитать из файла на диске или что-то подобное?

Я прочитал, что список аргументов переменной длины можно преобразовать в (char *) и передать таким образом ...

NSMutableArray *actions = [[NSMutableArray alloc] init];
[actions addObject: [DelayTime actionWithDuration:1]];
[actions addObject: [ScaleBy actionWithDuration:2 scale:4];

char *argList = (char *)malloc(sizeof(FiniteTimeAction *) * [actions count]);
[actions getObjects:(id *)argList];

[self runActions: actions];

Это «лучший» или «правильный» способ сделать это? Их лучшие альтернативы, более быстрые альтернативы?

Это было полезно?

Решение

vaargs - это просто помощник для создания вложенных объектов Sequence . Он возвращает FiniteTimeAction * , который создается последовательными вызовами [Sequence actionOne: one_ two: two _] . Вы можете сделать это самостоятельно в своем коде, просматривая ваш набор или массив. Это должно идти примерно так:

FiniteTimeAction *seq = nil;
for (FiniteTimeAction *action in actions) {
    if (!seq) {
        seq = action;
    } else {
        seq = [Sequence actionOne:seq two:action];
    }
}
[self runActions:seq];

Другие советы

Я бы посмотрел на использование NSInvocation - вы можете создать его, используя сигнатуру метода, на которую вы нацеливаетесь, а затем использовать установщики для каждого объекта следующим образом:

NSInvocation *invoker = setup invoker here...
for ( int i = 0; i < actions.count; i++ ) 
{
    NSObject *arg = [actions objectatIndex:i];
    [invoker setArgument:&arg atIndex:i+2];
}
[invoker setArgument:nil atIndex:i+2];

Бит i + 2 объясняется тем, что первые два аргумента действительно являются собственными и _cmd, поэтому вы устанавливаете все, начиная с индекса 2 и далее ... читайте документы по setArgument: atIndex: in NSInvocation для получения более подробной информации.

Если у вас есть это, вы можете вызвать операцию с целью. Я никогда не использовал это с переменными методами аргументов, поэтому я не уверен, насколько хорошо он там работает, но это единственный известный мне способ динамического создания вызова во время выполнения.

Учитывая предоставленные опции, кажется, что единственный реальный способ выполнить то, что я преследовал, это использовать подход, который я упомянул в вопросе, а именно:

NSMutableArray *actions = [[NSMutableArray alloc] init];
[actions addObject: [DelayTime actionWithDuration:1]];
[actions addObject: [ScaleBy actionWithDuration:2 scale:4];

char *argList = (char *)malloc(sizeof(FiniteTimeAction *) * [actions count]);
[actions getObjects:(id *)argList];

[self runActions: actions];

Возможно, набор заранее созданных последовательностей?

id move = [MoveBy actionWithDuration:3 position:ccp(350,0)];
id move_back = [move reverse];

id move_ease_in = [EaseIn actionWithAction:[[move copy] autorelease] rate:3.0f];
id move_ease_in_back = [move_ease_in reverse];

id move_ease_out = [EaseOut actionWithAction:[[move copy] autorelease] rate:3.0f];
id move_ease_out_back = [move_ease_out reverse];


id seq1 = [Sequence actions: move, move_back, nil];
id seq2 = [Sequence actions: move_ease_in, move_ease_in_back, nil];
id seq3 = [Sequence actions: move_ease_out, move_ease_out_back, nil];


[grossini runAction: [RepeatForever actionWithAction:seq1]];
[tamara runAction: [RepeatForever actionWithAction:seq2]];
[kathia runAction: [RepeatForever actionWithAction:seq3]];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top