テスト用地形ができたので、地形の上を自由に歩き回れるようにしていきます。
今回は、プレイヤーの位置にブロックが存在したら、プレイヤーのY座標を一つ上に上げるロジックを追加します。
↓
↓
これでブロックの山を登れるようになります。
まずプレイヤー座標にブロックがあるかチェックするため、各座標のブロックIDを保存する配列を作ります。
1 int cb_world_block[CB_WORLD_X_LIMIT][CB_WORLD_Y_LIMIT][CB_WORLD_Z_LIMIT];
そしてアクセスするためのAPIを作成。
1 void cb_set_block(int x, int y, int z, int block_id) 2 { 3 cb_world_block 4 [CB_WORLD_X_LIMIT/2+x] 5 [CB_WORLD_Y_LIMIT/2+y] 6 [CB_WORLD_Z_LIMIT/2+z] = block_id; 7 } 8 9 int cb_get_block(int x, int y, int z) 10 { 11 return cb_world_block 12 [CB_WORLD_X_LIMIT/2+x] 13 [CB_WORLD_Y_LIMIT/2+y] 14 [CB_WORLD_Z_LIMIT/2+z]; 15 }
設定APIと取得APIを作成しました。配列の添え字にはマイナス指定できないので、下駄(CB_WORLD_*_LIMIT/2)を履かせています。
次はキーが押された時の処理にロジック追加します。前進した時の処理なので、case ‘w’に追加します。
8~17行目に追加しました。
1 void cb_callback_keyboard(unsigned char key, int x, int y) 2 { 3 switch(key){ 4 ~省略~ 5 case 'w': 6 cb_player_pos[0] += 0.2 * cos((double)cb_player_direction*M_PI/180.0); 7 cb_player_pos[2] += 0.2 * sin((double)cb_player_direction*M_PI/180.0); 8 { 9 int x,y,z,block_id; 10 x = (int)cb_player_pos[0]; 11 y = (int)cb_player_pos[1]; 12 z = (int)cb_player_pos[2]; 13 block_id=cb_get_block(x,y,z); 14 if(block_id != 0){ 15 cb_player_pos[1]++; 16 } 17 } 18 glutPostRedisplay(); 19 break; 20 ~省略~ 21 default: 22 break; 23 } 24 } 25
次は配列にブロックIDを格納する処理です。マップ読み込み時に一緒に格納するようにしました。
配列cb_world_mapと配列cb_world_blockは、似たようなデータなので、いつか統合します。
1 void cb_world_load() 2 { 3 FILE *fp; 4 char readline[100],*p1, *p2, *p3,*p4; 5 int x,y,z,block_id; 6 7 cb_world_size = 0; 8 9 if ((fp = fopen("world_map.txt", "r")) == NULL) { 10 fprintf(stderr, "can not read world_map.txt"); 11 exit(EXIT_FAILURE); 12 } 13 14 memset(cb_world_map,0,sizeof(cb_world_map)); 15 memset(cb_world_block,0,sizeof(cb_world_block)); 16 17 while ( fgets(readline, 100, fp) != NULL ) { 18 if(strlen(readline) > 4){ 19 p1 = strtok(readline, " "); 20 p2 = strtok(NULL, " "); 21 p3 = strtok(NULL, " "); 22 p4 = strtok(NULL, " "); 23 x = atoi(p1); 24 y = atoi(p2); 25 z = atoi(p3); 26 block_id = atoi(p4); 27 cb_world_map[cb_world_size][0]= x; 28 cb_world_map[cb_world_size][1]= y; 29 cb_world_map[cb_world_size][2]= z; 30 cb_world_map[cb_world_size][3]= block_id; 31 cb_set_block(x, y, z, block_id); 32 cb_world_size++; 33 } 34 } 35 36 fclose(fp); 37 }
初期のプレイヤーの位置が中央だと山の下になってしまうので、端であるx=31、z=31にしておきます。
1 int main(int argc, char *argv[]) 2 { 3 cb_wire_flag = 0; 4 cb_world_load(); 5 6 cb_player_pos[0]=31; 7 cb_player_pos[1]=1; 8 cb_player_pos[2]=31; 9 ~省略~ 10 return 0; 11 }
コメント