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

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

Leave a Reply

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

CAPTCHA