【问题标题】:Run-Time Dynamic Length Actions list for Sequence序列的运行时动态长度操作列表
【发布时间】:2009-06-23 02:11:29
【问题描述】:

Cocos2D 为 Sequence 类定义了静态方法“actions”:

+(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];

这是执行此操作的“最佳方式”还是“正确”方式?他们是更好的替代品、更快的替代品吗?

【问题讨论】:

    标签: iphone cocos2d-iphone


    【解决方案1】:

    可变参数只是构建嵌套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];
    

    【讨论】:

    • 这似乎是一个完美的方法。
    【解决方案2】:

    我会考虑使用 NSInvocation - 您基本上可以使用您所针对的方法签名构建一个,然后像这样为每个对象使用 setter:

    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 位是因为前两个参数实际上是 self 和 _cmd,因此您设置了从索引 2 开始的所有内容...请阅读 NSInvocation 中的 setArgument:atIndex: 文档了解更多详细信息。

    一旦你有了它,你就可以用一个目标来调用这个操作。我从来没有将它与可变参数方法一起使用,所以我不确定它在那里工作得如何,但这是我所知道的在运行时动态构造调用的唯一方法。

    【讨论】:

      【解决方案3】:

      鉴于提供的选项,看来完成我所追求的唯一真正方法是使用我在问题中提到的方法,即:

      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];
      

      【讨论】:

        【解决方案4】:

        也许是一组预先构建的序列?

        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]];
        

        【讨论】:

        • 那仍然是设计时......而且,我的问题很清楚关于动态和“在运行时”(即;在运行时确定的东西......并且是未知的在设计时)。我的问题也提供了一个可能的解决方案,只是询问是否有更好的方法来做到这一点......
        • 为什么不将您的信息保存在 .plist 中并动态加载序列?
        猜你喜欢
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多