我正在尝试制作一款cocos2D游戏,在这款游戏中,每当玩家触摸屏幕时,背景就会向左滚动,从而模拟向前移动。
"背景"由两个非常长的矩形面板组成,称为pane1和pane2,以链的形式连接在一起。当触摸屏幕时,我使用CCActionMoveTo将两个窗格向左移动,当一个窗格完全离开屏幕时,我将其移回另一侧以创建无限循环。
问题是背景滚动动画需要0.2秒,如果玩家只是频繁地捣碎屏幕,它就会把一切都搞砸。而且,有时这两个窗格会经历不同程度的延迟,以便它们设计同步。
如何设置函数的延迟,使其在指定的时间段内只能被调用一次?换句话说,我想在处理玩家触摸的功能中添加一个"冷却时间"。
每次触摸场景时调用该函数:
- (void)playerMove {
CCActionMoveTo * actionMove1 = [CCActionEaseOut actionWithAction:
[CCActionMoveTo actionWithDuration:.2
position:ccp(pane1.position.x - 150, 0)]
rate: 1.5];
CCActionMoveTo * actionMove2 = [CCActionEaseOut actionWithAction:
[CCActionMoveTo actionWithDuration:.2
position:ccp(pane2.position.x - 150, 0)]
rate: 1.5];
CCActionCallFunc * actionCallGenerateTerrain = [CCActionCallFunc actionWithTarget: self selector:@selector(generateTerrain)];
counter++;
if(pane1InUse){
[pane1 runAction: [CCActionSequence actionWithArray:@[actionMove1, actionCallGenerateTerrain]]];
[pane2 runAction: actionMove2];
}
else
{
[pane1 runAction: actionMove1];
[pane2 runAction: [CCActionSequence actionWithArray:@[actionMove2, actionCallGenerateTerrain]]];
}
}
-(void) generateTerrain {
if (counter%8 == 0){
pane1InUse ^= YES;
CCLOG(@"%@", pane1InUse ? @"YES" : @"NO");
if (pane1InUse){
CCLOG(@"Generating Terrain 2 ...");
pane2.position = ccp(pane1.position.x+pane1.boundingBox.size.width, 0);
}
else{
CCLOG(@"Generating Terrain 1 ...");
pane1.position = ccp(pane2.position.x+pane2.boundingBox.size.width, 0);
}
}
}
你也可能已经注意到我使用这个奇怪的代码块,因为理想情况下,我希望actionMove1和actionMove2同时执行,一旦他们都完成,然后执行actionCallGenerateTerrain,但我不知道如何实现:
if(pane1InUse){
[pane1 runAction: [CCActionSequence actionWithArray:@[actionMove1, actionCallGenerateTerrain]]];
[pane2 runAction: actionMove2];
}
else
{
[pane1 runAction: actionMove1];
[pane2 runAction: [CCActionSequence actionWithArray:@[actionMove2, actionCallGenerateTerrain]]];
}
}
您可能希望将pane1和pane2放在ccNode中,将其称为combinedPanes(这将使pane1和pane2始终同步移动)。然后对combinedPane执行一个操作。同时添加一个布尔状态属性,命名为moveEnabled;
id movePane = [CCActionMoveTo ... ]; // whatever you have for pane1 or pane2
id moveComplete = [CCActionBlock actionWithBlock:^{
[self generateTerrain];
self.moveEnabled = YES;
}];
self.moveEnabled = NO;
[movePane runAction:[CCActionSequence actions:movePane,moveComplete,nil]];
并使用moveEnabled来允许/拒绝检测到触摸并触发此移动代码的触摸处理。在移动过程中,这将减少触摸,并有效地阻止你的歇斯底里的用户像坚果一样敲打。
-(void) playerMove {
if (self.moveEnabled){
//
// the rest of your logic
// ...
}
}
和init(或者如果你已经检测到这个条件,把它放在那里)。
self.moveEnabled = YES;
防止函数在一段时间内被调用两次的一个简单方法是将其包装在if语句中,如:
if ([[NSDate date] timeIntervalSinceDate:lastUpdated] > minDelay)
{
// call function here
lastUpdated = [NSDate date];
}
,其中lastUpdated
使用[NSDate date]
初始化,minDelay为所需的最小延迟(以秒为单位)。