C言語+GLUT(マウス移動で注視点を変える2)

続きです。

マウスで注視点を上下にも移動できるようにしました。
特に大きな変更はしていないのですが、画面がぐりぐり動くと、少しだけGLUT使ってる気分になって、やる気が出ます。

主な変更箇所です。

GLfloat cb_material_colors[][4] = {
        { 0.00, 0.00, 0.00, 1.00 },     // black
        { 0.40, 0.15, 0.05, 1.00 },     // brown
        { 0.00, 0.65, 0.10, 1.00 },     // green
        { 0.00, 0.45, 0.15, 1.00 },     // green
        { 0.00, 0.50, 0.13, 1.00 },     // green
        { 0.00, 0.63, 0.12, 1.00 },     // green
        { 1.00, 0.00, 0.05, 1.00 },     // red
        { 0.90, 0.50, 0.00, 1.00 },     // orange
        { 0.60, 0.60, 0.10, 1.00 },     // yellow
        { 0.00, 0.65, 0.10, 1.00 },     // green
        { 0.00, 0.20, 0.90, 1.00 },     // blue
        { 0.80, 0.00, 0.90, 1.00 },     // purple
        { 0.50, 0.50, 0.50, 1.00 },     // gray
        { 1.00, 1.00, 1.00, 1.00 },     // white
        { 0.90, 0.65, 0.10, 1.00 },     // gold
};

ただのカラーテーブルでしたが、ブロックの種類を表すテーブルにしていこうかと思ってます。greenは芝生、brownは土というように。
そのうちテクスチャに変更する予定。

void cb_look()
{
        gluLookAt(
                cb_player_pos[0],
                cb_player_pos[1],
                cb_player_pos[2],
                cb_player_pos[0] + 40 * cos((double)cb_player_direction*M_PI/180.0),
                cb_player_pos[1] + 40 * sin((double)cb_player_direction_v*M_PI/180.0),
                cb_player_pos[2] + 40 * sin((double)cb_player_direction*M_PI/180.0),
                0.0, 1.0, 0.0);
}

ここを修正して、上下に注視点を移動できるようにしました。
縦方向の角度0~359を管理するcb_player_direction_vという変数を追加して、計算に使用しています。

void cb_callback_passivemotion(int x, int y)
{
        if(cb_mouse_pos_x > x){
                cb_player_direction--;
                if(cb_player_direction < 0)cb_player_direction=359;
                glutPostRedisplay();
        }
        if(cb_mouse_pos_x < x){
                cb_player_direction++;
                if(cb_player_direction >= 360)cb_player_direction=0;
                glutPostRedisplay();
        }
        if(cb_mouse_pos_y < y){
                cb_player_direction_v--;
                if(cb_player_direction_v < 0)cb_player_direction_v=359;
                glutPostRedisplay();
        }
        if(cb_mouse_pos_y > y){
                cb_player_direction_v++;
                if(cb_player_direction_v >= 360)cb_player_direction_v=0;
                glutPostRedisplay();
        }
        cb_mouse_pos_x = x;
        cb_mouse_pos_y = y;
}

~pos_yをチェックする処理を新たに追加。マウスの移動距離に関係なく、角度が変化します。
ソースの行数が増えすぎて見にくくなりそうなので、この処理は下のように書き直しました。

void cb_callback_passivemotion(int x, int y)
{
        if(cb_mouse_pos_x != x){
                cb_player_direction = ((cb_player_direction + 360) + (x - cb_mouse_pos_x)) % 360;
                glutPostRedisplay();
                cb_mouse_pos_x = x;
        }
        if(cb_mouse_pos_y != y){
                cb_player_direction_v = ((cb_player_direction_v + 360) - (y - cb_mouse_pos_y)) % 360;
                glutPostRedisplay();
                cb_mouse_pos_y = y;
        }
}

ただ、これだとマウスがx軸y軸両方移動した時に、glutPostRedisplayを2回も呼んでしまうので無駄。フラグを使うことにしました。そしてここは大いにマジックナンバー1を使う。
こうなりました。

void cb_callback_passivemotion(int x, int y)
{
        int redisp_flag = 0;
        if(cb_mouse_pos_x != x){
                cb_player_direction = ((cb_player_direction + 360) + (x - cb_mouse_pos_x)) % 360;
                redisp_flag = 1;
                cb_mouse_pos_x = x;
        }
        if(cb_mouse_pos_y != y){
                cb_player_direction_v = ((cb_player_direction_v + 360) - (y - cb_mouse_pos_y)) % 360;
                redisp_flag = 1;
                cb_mouse_pos_y = y;
        }
        if(redisp_flag)
                glutPostRedisplay();
}

最後になんちゃってワールド生成。

void cb_world_create()
{
        int i,x,z,r;
        i=0;
        for(x=0; x<CB_WORLD_X_LIMIT; x++){
                for(z=0; z<CB_WORLD_Z_LIMIT; z++){
                        cb_world_map[i][0]=x;
                        cb_world_map[i][1]=0;
                        cb_world_map[i][2]=z;
                        cb_world_map[i][3]=1;
                        i++;
                }
        }
        for(x=0; x<CB_WORLD_X_LIMIT; x++){
                for(z=0; z<CB_WORLD_Z_LIMIT; z++){
                        r = rand()%3;
                        if(r == 0){
                                r = rand()%4+2;
                                cb_world_map[i][0]=x;
                                cb_world_map[i][1]=1;
                                cb_world_map[i][2]=z;
                                cb_world_map[i][3]=r;
                                i++;
                                if(i>=CB_WORLD_XYZ_LIMIT)goto over;
                        }
                        cb_world_map[i][0]=x;
                        cb_world_map[i][1]=0;
                        cb_world_map[i][2]=z;
                        cb_world_map[i][3]=1;
                }
        }
over:
        cb_world_size = i;
}

1層目はすべて土ブロック、2層目にランダムで芝生ブロックを設置してます。

つづく

Leave a Reply

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

CAPTCHA