C言語ゲームプログラミング 第5回講座




2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を協力にサポートします。
ブロック崩しゲーム 3Dツリー クリスマスツリー
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study Cにロードする Study Cにロードし編集する Study Cにロードし実行する
Study C無料利用についての詳細は、このページを参照してください。



1.ボールの移動

前回作成したプログラムを変更してボールが画面上を移動するプログラムを作成します。 ループでgl_drawbitmap()関数などに与える値を変化させれば画面上をボールが移動するようになります。 ボールのX座標(横方向)は変数で変化させY座標(縦方向)は240で固定とします。 X座標を増加させるとボールは右方向に移動するように見えます。 X座標が画面(ウィンドウ)からはみ出した場合は、また左側に戻します。

#include <graph.h>

main()
{
        HBITMAP hbmp_ball;
        int     b_xx = 0;       //この変数がボールのX座標

        hbmp_ball = gl_loadbitmap("ball.bmp");
        if(hbmp_ball == NULL){
                printf("ビットマップファイルが見つかりません.\n");
                exit(0);
        }
        gl_openwin(-1, -1, 640, 480, 0);

        for( ; ; ){
                gl_fillrect(b_xx, 240, b_xx + 16, 240 + 16, RGB(0, 0, 0));
                b_xx++;                 //ボールのX座標を増加させる
                if(b_xx > 640-16){   //ウィンドウからはみ出したら左側に戻す
                        b_xx = 0;
                }
                gl_drawbitmap(hbmp_ball, b_xx, 240, 16, 16, 0, 0);
                gl_refresh();
        }
}

このプログラムをそれなりのスピードのPCで実行するとウィンドウ上に幾つものボールが見えると思います。 これは描画スピードが速すぎるためです。見た目に動いているようにするにはループ毎に少し待つような処理が必要です。
このプログラムは、無限に動き続けるのでF2キーなどでプログラムを中断させてください。


2.処理速度の調整

処理速度の調節にはGetTickCount()関数を使用します。 この関数は、1000分の1秒単位でカウントアップした値を返します(ただし小さい間隔では、あまり正確ではありません)。 GetTickCount関数の値が5以上経過していれば(約0.005秒)処理するようにします。
GetTickCount関数の値は一周すると0に戻るので、前回の値より小さい値になった場合も処理するようにします。

#include <graph.h>

main()
{
        HBITMAP hbmp_ball;
        int     b_xx = 0;
        unsigned long
                tick;

        hbmp_ball = gl_loadbitmap("ball.bmp");
        if(hbmp_ball == NULL){
                printf("ビットマップファイルが見つかりません.\n");
                exit(0);
        }
        gl_openwin(-1, -1, 640, 480, 0);

        tick = GetTickCount();
        for( ; ; ){
                //GetTickCount()関数の返り値が5を超えていない場合は
                //描画を行わない
                if(GetTickCount() >= tick && GetTickCount() < tick + 5)
                        continue;
                tick = GetTickCount();

                gl_fillrect(b_xx, 240, b_xx + 16, 240 + 16, RGB(0, 0, 0));
                b_xx++;
                if(b_xx > 640-16){
                        b_xx = 0;
                }
                gl_drawbitmap(hbmp_ball, b_xx, 240, 16, 16, 0, 0);
                gl_refresh();
        }
}

このプログラムならボールが動いているように見えると思います。


3.待ち時間と移動量

前回のプログラムでは、移動量が1で待ち時間も短い物でした。 一度に移動する量が少ない方が見た目にはきれいなのですが、他にもいろいろな処理を追加していくと速度が追いつかなくなる可能性があります。 そこで、一度に移動する量を1から10に変更します。こうすることで他に行う処理にさくことのできる時間を多くすることができます。

#include <graph.h>

main()
{
        HBITMAP hbmp_ball;
        int     b_xx = 0;
        unsigned long
                tick;

        hbmp_ball = gl_loadbitmap("ball.bmp");
        if(hbmp_ball == NULL){
                printf("ビットマップファイルが見つかりません.\n");
                exit(0);
        }
        gl_openwin(-1, -1, 640, 480, 0);

        tick = GetTickCount();
        for( ; ; ){
                //GetTickCount()関数の返り値が5を超えていない場合は
                //描画を行わない
                if(GetTickCount() >= tick && GetTickCount() < tick + 50)
                        continue;
                tick = GetTickCount();

                gl_fillrect(b_xx, 240, b_xx + 16, 240 + 16, RGB(0, 0, 0));
                b_xx += 10;
                if(b_xx > 640-16){
                        b_xx = 0;
                }
                gl_drawbitmap(hbmp_ball, b_xx, 240, 16, 16, 0, 0);
                gl_refresh();
        }
}

このプログラムも前のプログラムも、ほぼ同じスピードでボールが動くと思います。