- ベストアンサー
初心者です。 ~時間差で再描画~
まだまだ初心者ですが、フリーのBCCを使ってCプログラミングしているものです。 最近、トランプのゲームを作り始めて、時間差で再描画する必要が出たので InvalidateRect(hWnd, NULL, TRUE); Sleep(3000); InvalidateRect(hWnd, NULL, TRUE); と書いたのですが、うまく動作しません。 そこで、 InvalidateRect(hWnd, NULL, TRUE); Sleep(3000); と書いてみると、3秒間のブランクがあった後で、描き直されているようでした。 これはどういうことなのでしょうか。 そして、どうすれば正しく動作させられるのでしょうか。 出来れば、初心者でもわかりやすいような回答お待ちしています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
★Sleep 関数ってのは処理を一時停止させます。 ・よって、InvalidateRect 関数で再描画の信号を送っても Sleep 関数で 3 秒間の 停止状態なので時間差の再描画には上手くなりません。 ・時間差で再描画を行いたいのならばタイマーを使います。 下にそのサンプルです。 サンプル: SetTimer( hWnd, タイマーID, 3000, NULL ); ←再描画させる指定 WM_TIMER: InvalidateRect( hWnd, NULL, TRUE ); KillTimer( hWnd, タイマーID ); ←タイマー破棄 break; 解説: ・時間差で再描画を行う信号は、SetTimer 関数を実行します。 これで 3 秒後に WM_TIMER より、再描画の信号が発生するため、WM_PAINT で再描画 されます。 ・また、常に 3 秒おきに再描画させたい場合は、WM_TIMER で KillTimer しないで良い。 つまり、ゲームを開始したときに1回だけ SetTimer を実行して一時停止や、ゲームの 終了時に KillTimer でタイマーを破棄すればよい。 ・WM_PAINT でウェイト(Sleep)を入れるのはおかしいです。注意! ・以上。参考に。
その他の回答 (3)
- noocyte
- ベストアンサー率58% (171/291)
> InvalidateRect(hWnd, NULL, TRUE); > Sleep(3000); > InvalidateRect(hWnd, NULL, TRUE); これでは時間差で再描画されるわけがありません. なぜならば,InvalidateRect は再描画を行うのではなく, 後で再描画が行われるように「予約する」だけだからです. 実際の再描画は,メッセージループから WM_PAINT が ディスパッチされたときの処理として行われます.
お礼
成る程、↑では2回再描画を「予約」しただけですか。 何分初心者なもので、"InvalidateRect = 再描画" としか理解していなかったため、このような間違いをおかしました。 詳しい解説、ありがとうございました。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★追記。 >InvalidateRect(hWnd, NULL, TRUE); >Sleep(3000); >InvalidateRect(hWnd, NULL, TRUE); の3行はどこで実行していますか?
補足
↓でも書きましたが、ウィンドウプロシージャ内ではなく、呼び出した自作関数の中です。 説明不足ですみません。
- t_nojiri
- ベストアンサー率28% (595/2071)
http://www.geocities.jp/ky_webid/win32c/014.html なんだか、自力で描画用プロシジャ内にsleep書くのはおかしいというか、3秒経ったらWM_PAINTメッセージ発生するようにクリッピング領域書き直すと思うんですけどね?
お礼
素早い回答ありがとうございます。 こちらの説明不足でご迷惑おかけしましたが、上のコードを書いた場所は、描画用プロシジャ内ではなく、プロシジャ以外の自作関数の中です。 すみません。
お礼
成る程、そもそもSleepを使うのがおかしいということですか。 SetTimerですね。 やってみます。