C言語+GLUT(ブロックの山を下る)

次は下りを作ります
移動キーが入力されると、移動後のプレイヤーの位置にブロックが存在するかどうかで登り判定をしていました。

        case 'w':
                cb_player_pos[0] += 0.2 * cos((double)cb_player_direction*M_PI/1
                cb_player_pos[2] += 0.2 * sin((double)cb_player_direction*M_PI/1
                {
                        int x,y,z,block_id;
                        x = (int)cb_player_pos[0];
                        y = (int)cb_player_pos[1];
                        z = (int)cb_player_pos[2];
                        block_id=cb_get_block(x,y,z);
                        if(block_id != 0){
                                cb_player_pos[1]++;
                        }
                }
                glutPostRedisplay();
                break;

下りは足元にブロックがあるかどうかの判定にしますが、その前に、上のプログラムをリファクタリングしたいと思います。
私の場合プログラミングしていて、一番楽しいと思う時は、リファクタリングしている時です。最初からきれいに作れば、もっとスピーディにプログラミングできるのでしょうけど。

cb_player_pos[0]~[2]は、プレイヤーがいる座標が格納される配列ですが、
[0]にx座標、[1]にy座標、というように、配列である必要がありません。
これを構造体にして、x、y、zのメンバを揃えることにします。

変更前の変数定義はこのようになってます。

GLdouble cb_player_pos[3];
int cb_player_direction;
int cb_player_direction_v;

下のように変更しました。

struct cb_struct_pos
{
        GLdouble x,y,z;
	int dir,dir_v;
};
struct cb_struct_pos cb_player_pos;

ついでにプレイヤーの向き(方角)を格納しているcb_player_directionともdirという名前にして構造体メンバとしました。dir_yは上下の向きです。
ということで、変数名に合わせて、最初のプログラムも下のように修正。少しすっきりしました。

        case 'w':
                {
                        struct cb_struct_pos* p = &cb_player_pos;
                        p->x += 0.2 * cos((double)cb_player_pos.dir*M_PI/180.0);
                        p->z += 0.2 * sin((double)cb_player_pos.dir*M_PI/180.0);
                        if(cb_get_block(p->x, p->y, p->z) != 0)
                                p->y++;
                }
                glutPostRedisplay();
                break;

さらに改造。キー入力全体では、このようになりました。

void cb_callback_keyboard(unsigned char key, int x, int y)
{
        struct cb_struct_pos* p = &cb_player_pos;

        switch(key){
        case 'q': exit(0); break;
        case 'w':
                p->x += 0.2 * cos((double)cb_player_pos.dir*M_PI/180.0);
                p->z += 0.2 * sin((double)cb_player_pos.dir*M_PI/180.0);
                break;
        case 's':
                p->x -= 0.2 * cos((double)cb_player_pos.dir*M_PI/180.0);
                p->z -= 0.2 * sin((double)cb_player_pos.dir*M_PI/180.0);
                break;
        case 'a':
                cb_player_pos.dir--;
                if(cb_player_pos.dir < 0)cb_player_pos.dir=359;
                break;
        case 'd':
                cb_player_pos.dir++;
                if(cb_player_pos.dir >= 360)cb_player_pos.dir=0;
                break;
        case ' ':
                cb_wire_flag = 1 - cb_wire_flag;
                break;
        default:
                return;
        }

redisplay:
        if(cb_get_block(p->x, p->y, p->z) != 0)
                p->y++;
        if(cb_get_block(p->x, p->y-1, p->z) == 0)
                p->y--;
        glutPostRedisplay();
}

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA