続きです。
マウスで注視点を上下にも移動できるようにしました。
特に大きな変更はしていないのですが、画面がぐりぐり動くと、少しだけGLUT使ってる気分になって、やる気が出ます。
glut mouse2
主な変更箇所です。
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層目にランダムで芝生ブロックを設置してます。
つづく
コメント