テスト用地形ができたので、地形の上を自由に歩き回れるようにしていきます。
今回は、プレイヤーの位置にブロックが存在したら、プレイヤーの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 }


コメント