0

私は非常にシンプルなiPhoneゲームに取り組んでおり、ランダム化された音声プロンプトに基づいて、適切な色のボタンを連続して何度も選択する必要があります。ボタンが1色でクリックされた場合、毎回ハードコードされた色になるように設定しています(たとえば、赤をクリックすると、常に青に変わります)。色変更方法はIBOutletで設定されています。whileループでタイマーを設定し、タイマーが終了すると、プレーヤーが正しい選択をしたかどうかを確認します。問題は、タイマーが切れるまでボタンの色の変化が起こらないことであり、これは正解をチェックするために使用される方法に問題を引き起こします。この色の変化を即座に起こさせる方法はありますか?私が検索したところ、コードが実行されるまでストーリーボードのアクションが発生しないことが関係していることがわかりましたが、私はそうしていません。タイマーを使って何かを見つけました。答えが正しければタイマーを呼び出すメソッドのセクションは次のとおりです。

BOOL rightChoice = true;
int colorNum;
NSDate *startTime;
NSTimeInterval elapsed;
colorNum = [self randomizeNum:middle];
[self setTextLabel:colorNum];
while (rightChoice){
    elapsed = 0.0;
    startTime = [NSDate date];
    while (elapsed < 2.0){
        elapsed = [startTime timeIntervalSinceNow] * -1.0;
        NSLog(@"elapsed time%f", elapsed);
    }
    rightChoice = [self correctChoice:middleStatus :colorNum];
    colorNum = [self randomizeNum:middle];
}
4

1 に答える 1

2

2つのうちの1つが際立っていました

  • while ループをタイマーとして使用しています。これを行わないでください。操作は同期的です。
  • これがメイン スレッドで実行され、コードが返されない場合、UI が更新されます。マントラは次のとおりです。「戻ってこないときは、ブロックしています。」
  • Cocoa にはNSTimer、非同期で実行されるものがあります。ここでは理想的です。

それでは、NSTimer を理解してみましょう(代わりに、GCD を使用して ivar にキューを保存することもできますが、NSTimer が正しい方法のようです)。

timer_ という ivar を作成します。

// Top of the .m file or in the .h
@interface ViewController () {
  NSTimer *timer_;
}
@end

いくつかの開始関数と停止関数を作成します。これらをどのように呼び出すかはあなた次第です。

- (void)startTimer {
  // If there's an existing timer, let's cancel it
  if (timer_)
    [timer_ invalidate];

  // Start the timer
  timer_ = [NSTimer scheduledTimerWithTimeInterval:5.0
                                            target:self
                                          selector:@selector(onTimerFinish:)
                                          userInfo:nil
                                           repeats:NO];
}

- (void)onTimerFinish:(id)sender {
  NSLog(@"Timer finished!");

  // Clean up the timer
  [timer_ invalidate];
  timer_ = nil;
}

- (void)stopTimer {
  if (!timer_)
    return;

  // Clean up the timer
  [timer_ invalidate];
  timer_ = nil;
}

そしていま

  • タイマー テスト コードを onTimerFinish 関数に入れます。
  • 現在の選択を格納する ivar を作成します。選択が行われたときにこの ivar を更新し、関連する変更を UI に加えます。停止条件が満たされた場合、stopTimer を呼び出します。
  • onTimerFinished では、必要に応じて、条件付きで呼び出して再びタイマーを開始できます。

お役に立てれば!

于 2012-04-26T14:54:08.457 に答える