1 / 3 ループによる座標の継続更新
メインループの中で座標変数を毎フレーム更新し、画面上のキャラクターを連続して移動させます。前フレームの値を引き継ぐアニメーションの仕組みと、変数をループの外で宣言・初期化すべき理由を理解します。
メインループ内での座標加算
第02回では、青いロボットの座標 x を固定したまま、毎フレーム同じ位置に描画していました。今回は、描画する前に座標変数の値を少しずつ加算してみます。
1フレームごとの加算処理の追加
while ループの先頭(ClearDrawScreen(); の直前)に、次の1行を追加してください。
x = x + 3;
ClearDrawScreen();演算子による継続的な更新の仕組み
この1行は、算術演算子 + と代入演算子 = を組み合わせた処理です。
- 右辺の計算(算術演算子
+): 現在の変数xの値(最初は160)を取り出し、3を足して163を算出します。 - 左辺への代入(代入演算子
=): 計算結果の163を、再び変数xに上書き保存します。
この文が while ループの内部に配置されているため、1フレームごとに繰り返し実行されます。前フレームで更新された x の値を引き継いだ状態でさらに 3 が足されるため、座標は次のように推移します。
| 実行フレーム | ループ突入時のx | x = x + 3 実行後のx | 描画位置 |
|---|---|---|---|
| 1フレーム目 | 160 | 163 | (163, 120) |
| 2フレーム目 | 163 | 166 | (166, 120) |
| 3フレーム目 | 166 | 169 | (169, 120) |
| 4フレーム目 | 169 | 172 | (172, 120) |
移動の見え方と1フレームの移動量
実行すると、青いロボットが一定の速度で滑らかに右方向へ進んでいくことを確認できます。なお、現在は画面端での停止処理を書いていないため、そのまま放置すると画面の右端を突き抜けて見えなくなります。
1フレームの移動量
3 は1フレームに進むピクセル数です。1秒間に60回更新する場合は 3 × 60 = 180 ピクセル進みます。実際の更新回数が変わると、1秒間の移動距離も変わります。
デバッガーによる変数の実行時観察
画面の見た目だけでなく、プログラム実行中にメモリ上の変数 x がどのように変化しているかをデバッガーで観察してみましょう。
ブレークポイントの設定
指定した行でプログラムの実行を一時停止させる目印を ブレークポイント(breakpoint) と呼びます。
- 実行中のウィンドウをEscapeキーで閉じます。
- Visual Studioのエディタで
x = x + 3;の行をクリックし、F9 キーを押します(行の左端に赤い丸が点灯します)。 - F5 キーを押してデバッグ実行を開始します。プログラムが起動し、ブレークポイントの行を実行する直前で一時停止します。
加算前後と次のフレームの値の比較
ブレークポイントで停止した状態から、1行ずつ実行して値を確認します。
- Visual Studioの「ローカル」ウィンドウで、変数
xの値が初期値160になっていることを確認します。 - F10 キー(ステップオーバー)を1回押します。加算の行が実行され、
xが163に更新されます。 - F5 キーを押すと、次のフレームで同じ行を実行する直前に停止します。この時点の
xは、前のフレームの結果である163です。 - もう一度 F10 キーを押し、
xが166に更新されることを確認します。
確認を終えたら、ブレークポイントのある行で再度 F9 を押して赤い丸を解除し、F5 で通常の実行に戻してください。
初期化する位置と値の継続
なぜ変数の宣言と初期化(int x = 160;)は、ループの「外側」に書かなければならないのでしょうか。
ループ内で初期化する実験
検証のため、ループの外にある int x = 160; を切り取り、while ループ内の先頭(x = x + 3; の直前)へ移動させてみましょう。
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
int x = 160; // 誤ってループの中で初期化してしまう
x = x + 3;
ClearDrawScreen();
// ...このコードを実行すると、ロボットは右へ動かず、位置 163 で静止したままになります。
毎回初期化される値の確認
ループ内に int x = 160; を置くと、1周ごとに 160 から始め、3を足して 163 を描画します。前の周の結果に3を足していないため、同じ場所に止まります。
確認後は、int x = 160; をループの外、元の位置へ戻してください。再実行し、163 → 166 → 169 と前の値を引き継いで右へ進むことを確認します。
- 毎フレーム加算を行うことでアニメーションが実現する仕組みを説明できる
- デバッガーを用いてブレークポイントを設定し、変数の値の変化を1行ずつ追跡できる
- 変数の宣言・初期化をループの外に置かなければならない理由(毎周の初期化との違い)を説明できる