close

 ios-cocos2d游戏开发基础-预定信息-开发笔记(六)

节点可以预定信息,其实就是Objective-C里面的每隔一段时间调用一次方法。 在很多情况下,你需要节点调用指定的更新方法以处理某些情况,比如说碰撞 测试。以下是一个最简单的,可以在每一帧都被调用的更新方法:

-(void) scheduleUpdates {
[self scheduleUpdate];
} -(void) update:(ccTime)delta {
// 此方法每一帧都会被调用
}

在使用的时候你需要在初始化方法里加入[self scheduleUpdate];
在重写-(void) update:(ccTime)delta方法即可。方法里写入想调用的内容。
你会注意到我们现在的更新方法是固定的,每一帧都会调用上 述方法。delta这个参数表示的是此方法的最后一次调用到现在所经过的时间。 如果你想每一帧都调用相同的更新方法,上述做法很适用。不过有时候你需要 用到更灵活的更新方法。
如果你想运行不同的方法,或者是每秒调用10次更新方法的话,你应该使用以 下代码:

-(void) scheduleUpdates {
[self schedule:@selector(updateTenTimesPerSecond:) interval:0.1f];
} -(void) updateTenTimesPerSecond:(ccTime)delta {
// 此方法将根据时间间隔来调用,每秒10次
}

如果时间间隔(interval)为0的话,你应该使用scheduleUpdate方法。不过, 如果你想之后停止对某个指定更新方法的预定信息的话,上述代码更加合适。 因为scheduleUpdate方法没有停止预定信息的功能。
更新方法的签名和之前是一样的:delta时间是它唯一的参数。但是这次你可以 使用任何名称,而且它会每十分之一秒被调用一次。如果你不想每一帧都判断 是否达到了胜利的条件(有可能判断的过程很复杂),每秒调用10次更新方法 会比每帧都调用要好。或者,你想让代码在10分钟以后调用运行一个动作,你 可以将时间间隔(interval)设置为600。
注:@selector(…)这个语法看起来有点怪。这是Objective-C用来参照指定方
法的方式。这里很重要的一点是最后的那个冒号。它告诉Objective-C去找在此
指定的方法名,并且此方法只有一个参数。如果你忘记在最后加上冒号,程序
还是会继续编译,但是之后会崩溃。在调试控制台(Debugger Console)里,
你会看到这样的错误日志:“unrecognized selector sent to instance …”。
@selector(…)里的冒号数量必须和方法的参数数量和名称相匹配。看一下以下方法:

-(void) example:(ccTime)delta sender:(id)sender flag:(bool)aBool

相对应的@selector应该是:

@selector(example:sender:flag:)

停止节点的所有选择器,包括那些已经在scheduleUpdate里面设置 了预定的选择器:

[self unscheduleAllSelectors];

以下代码会停止某个指定的选择器(假设选择器名称是updateTenTimesPerSecond):

[self unschedule:@selector(updateTenTimesPerSecond:)];

注:此方法不会停止scheduleUpdate中设置的预定更新方法。
还有一个挺有用的设置和停止选择器预定的方法。很多时候你需要在设置好的 预定方法里面停止调用某个指定的方法,同时因为参数和方法名可能发生变化, 你又不想重复相同的方法名和参数,这时你可以用以下的方法设置(预定的控 制器只会运行一次):

-(void) scheduleUpdates {
[self schedule:@selector(tenMinutesElapsed:) interval:600];
} -(void) tenMinutesElapsed:(ccTime)delta {
// 用_cmd关键词停止当前方法的预定 [self unschedule:_cmd];
}

_cmd关键词是当前方法的缩写。上述代码只会让tenMinutesElapsed方法运行一 次。实际上你也可以用_cmd来设置方法调用的预定。假设你需要调用一个方法, 这个方法会使用不同的时间间隔来调用,每次方法被调用以后,时间间隔都会 发生变化。你的代码看起来会是像下面这样:

-(void) scheduleUpdates {
// 像之前一样预定第一次更新 [self schedule:@selector(irregularUpdate:) interval:1];
} -(void) irregularUpdate:(ccTime)delta {
}
// 首先,停止方法调用的预定 [self unschedule:_cmd];
// 这里我们用随机数来决定下次调用此方法需要经过的时间 float nextUpdate = CCRANDOM_0_1() * 10;
// 然后用_cmd来代替选择器,用新的时间间隔来重新预定方法调用 [self schedule:_cmd interval:nextUpdate];

用_cmd关键词可以让你避免预定(schedule)或者停止预定(unschedule)错误的方法。从长期来说是很有好处的。
最后一个预定方法调用的问题是安排更新方法的优先次序。请先看一下以下代 码:

// 在A节点里 
-(void) scheduleUpdates
{ }
[self scheduleUpdate];
// 在B节点里 -(void) scheduleUpdates {
[self scheduleUpdateWithPriority:1];
}
// 在C节点里 -(void) scheduleUpdates {
[self scheduleUpdateWithPriority:-1];
}

这可能需要些时间来消化。所有的节点还是在调用同样的-(void)update: (ccTime) delta方法。但是因为使用了优先级设置,C节点将会被首先运行。然 后是调用A节点,因为默认情况下优先级设定为0。B节点最后一个被调用,因为 它的优先级的数值最大。更新方法的调用次序是从最小的优先级数值到最大的 优先级数值。
你可能想知道什么时候会用到这个优先级功能。坦率地说很少会用到它。不过 按照我过去的经验,在某些极端情况下你可能需要用到这个功能,比如在进行 物理效果模拟之前或者之后,为参与模拟的对象添加力量。在宣布此项功能的 同时也提到了物理效果的更新说明了上述用处。有的时候,通常是在项目后期, 你可能发现了一个很奇怪的bug,这个bug是和时间的选择(timing)有关的, 这迫使你在完成所有的对象自我更新之后,运行玩家对象的更新方法。
直到你有一天需要用到优先级设置这个功能以解决特定的问题,现在你可以忽 略它。

 

   转载本站文章请注明出处,转载自:舵手网络--http://www.helmsmansoft.com

   本文链接地址: http://www.helmsmansoft.com/index.php/archives/592

arrow
arrow
    全站熱搜

    zer931 發表在 痞客邦 留言(0) 人氣()