シーケンスのランタイム動的長さアクションリスト
-
06-07-2019 - |
質問
Cocos2Dは、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
オブジェクトを構築するための単なるヘルパーです。 [Sequence actionOne:one_ two:two _]
への連続した呼び出しによって構築される FiniteTimeAction *
を返します。セットまたは配列をループすることで、コードでこれを自分で行うことができます。次のようになります:
FiniteTimeAction *seq = nil;
for (FiniteTimeAction *action in actions) {
if (!seq) {
seq = action;
} else {
seq = [Sequence actionOne:seq two:action];
}
}
[self runActions:seq];
他のヒント
NSInvocationの使用を検討します。基本的には、ターゲットのメソッドシグネチャを使用して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ビットは、最初の2つの引数が実際にselfと_cmdであるため、インデックス2以降のすべてを設定するためです。詳細については、NSInvocationのsetArgument:atIndex:のドキュメントを参照してください。
一度、ターゲットを使用して操作を呼び出すことができます。可変引数メソッドでこれを使用したことがないため、そこでどのように機能するかはわかりませんが、実行時に動的に呼び出しを構築することを知っている唯一の手段です。
提供されたオプションを考えると、私が望んでいたことを達成する唯一の本当の方法は、私が質問で言及したアプローチを使用することであるように見えます:
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]];