我需要为英雄制造射击延迟。因此,当用户触摸屏幕并移动他们的手指时,英雄将开始射击,但每次射击之间将持续延迟。
所以要明确:
user touches screen
timer begins
timer reached
hero fires
timer resets
timer reached hero fires
我的第一个想法是使用performSelector / dispatch。但在使用调度后,我意识到它会阻塞块调用,并在达到延迟后将其关闭。 (我是新来的派遣人员)
所以现在我的想法是创建一些计时器变量并调用" fire"到达计时器时起作用。当用户触摸屏幕时,计时器启动。
我只是在寻找最佳方法,因为使用计时器变量可能会非常混乱。你有什么想法?
答案 0 :(得分:1)
似乎可以通过有限状态机(FSM)很好地解决这个问题。您有几种状态,进入/退出它们的条件,以及明确定义的行为。
我将下面的图表放在一起,向您展示我正在考虑的模型:
注意:
一些示例代码:
typedef enum
{
IDLE,
FINGER_DOWN,
FIRING_START_DELAY,
FIRE_BULLET,
INTER_FIRE_DELAY,
} FIRING_STATE;
// Class Variables:
FIRING_STATE _firingState = IDLE;
int _ticks = 0;
bool _fingerDown = false;
const int FRAMES_PER_SECOND = 60;
const float FIRING_START_DELAY_SECONDS = 1.5f;
const float INTER_FIRE_DELAY_SECONDS = 0.5;
void EnterState(FIRING_STATE firingState);
void ExecuteState(FIRING_STATE firingState);
void ChangeState(FIRING_STATE firingState);
void EnterState(FIRING_STATE firingState)
{
switch(firingState)
{
case IDLE:
break;
case FINGER_DOWN:
break;
case FIRING_START_DELAY:
// NOTE: You may change/start an animation or
// play a sound here to give some feedback
// to the player.
_ticks = FIRING_START_DELAY_SECONDS*FRAMES_PER_SECOND;
break;
case FIRE_BULLET:
break;
case INTER_FIRE_DELAY:
_ticks = INTER_FIRE_DELAY_SECONDS*FRAMES_PER_SECOND;
break;
}
}
void ExecuteState(FIRING_STATE firingState)
{
// If the counter is running, decrement it.
if(_ticks > 0)
{
_ticks--;
}
switch(firingState)
{
case IDLE:
if(_fingerDown)
{
ChangeState(FINGER_DOWN);
}
break;
case FINGER_DOWN:
if(!_fingerDown)
{
ChangeState(IDLE);
}
else
{
ChangeState(FIRING_START_DELAY);
}
break;
case FIRING_START_DELAY:
if(_ticks == 0)
{ // Move on to next state
ChangeState(FIRE_BULLET);
}
if(!_fingerDown)
{
ChangeState(IDLE);
}
break;
case FIRE_BULLET:
if(!_fingerDown)
{
ChangeState(IDLE);
}
ChangeState(INTER_FIRE_DELAY);
break;
case INTER_FIRE_DELAY:
if(_ticks == 0)
{ // Move on to next state
ChangeState(FIRE_BULLET);
}
if(!_fingerDown)
{
ChangeState(IDLE);
}
break;
}
}
void ChangeState(FIRING_STATE firingState)
{
EnterState(firingState);
_firingState = firingState;
ExecuteState(firingState);
}