その3-2 プログラムへの実装(マップ・歩行)

キャラクターがマップ上を歩くという
考え方について理解ができたら
いよいよプログラムへの実装です




正直、考え方がしっかり理解出来ても
プログラムに組み込むのは
とても大変な作業になります


ですが実装出来た時の嬉しさは
その苦労以上のものです



「こういうゲームを作りたい!」
という願望さえあれば
プログラミングは自然と身に付くと思いますので
めげずに頑張りましょう




 マップ・キャラクター表示プログラミング 


Visual Studio
「プロジェクトの作成」
「C++コンソールアプリ」を選択しましょう


初期のプログラムは
以下のような感じだと思います


#include <iostream >

int main()
{

    std::cout < < "Hello World! ¥n “;

}


このプログラムにマップ作成と
キャラクター移動プログラムを組み込みます


まず、main関数の中は空にして下さい




マップ用の変数を用意します

整数を10個含んだ配列変数を
10個用意します

int map[10][10];




変数の中身を指定します

int map[10][10] = {
{0,0,0,0,0,0,0,0,0,0},
{0,0,2,2,2,2,2,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,1,1,1,1,2,0,0},
{0,0,2,2,1,1,2,2,0,0},
{0,0,0,0,0,0,0,0,0,0}
};


この配列変数は
マップとして見やすいものにするため
わざと改行を入れています


ちなみに指定した数字は
  平地が 
   壁が 
何も無いが 
となっています

10×10のマップを作成した
と考えてください




キャラクターの座標用変数を用意します

int x=4, y=3;


後で理由を説明しますが、
実際のキャラクターの位置は
座標に1足したものになります




汎用変数を用意します

int i, j, k;


ijはループ用
kは上下左右のキャラ移動入力用となります



#include <iostream >

int main()
{
  int map[10][10] = {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,2,2,2,2,2,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,2,1,1,2,2,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  };
  int x=4, y=3;
  int i, j, k;

}


プログラムは上のようになります


次に・・
マップを表示させるループを作成します


for(i= 0;i < 10; i++) {
  for(j= 0; j < 10; j++) {

     std::cout < < map[i][j];

  }
  std::cout < < "¥n “;
}


詳しく解説します

std::cout(シーアウト)
クラスと呼ばれるものですが
命令文と考えれば理解しやすいと思います


「変数の中の数値を表示する」
という感じで理解してもらえればOKです




map配列変数i番目のj個目の数字を
表示させているのですが
iマップの y座標
jマップの x座標
と考えると
より分かりやすいかもしれません


そしてjマップのx座標
を並べて表示させた後に
std::cout < < "¥n “;
で改行を入れて次の行に表示するようにしています





これでマップを表示させることが出来たので
次は
キャラクターの配置です



forループでのマップ表示中、
キャラクターが居る場所(変数x変数yの場所
とマップ表示場所が同じであればマップ表示をせず
キャラクター「*」を表示させます



for (i= 0;i < 10;i++) {
  for (j= 0; j < 10; j++) {

    //マップ表示かキャラ表示の条件分岐
    if(y==i & &x==j) {
      std::cout < < "* “;
    }
    else{
      std::cout < <map[i][j];
    }
    //ここまで

  }
  std::cout < < "¥n “;
}

実行結果



おお・・

キャラクター「*」が表示されてる!



あれ・・?
でもちょっと待って・・?


xには4
yには3
を入力してあるはず・・


でも実際は
左から5番目
上から4番目
の場所にいる・・何で???




答えは
整数は「0から始まるから」です

配列変数「10」
配列「0」~「9」までの組み合わせです

 なので、変数x=4
配列「変数x
0から4まで数えた数番目
すなわち5番目の位置にキャラが表示されるのです


単純に座標+1の位置に表示されると考えると
脳みそが破裂せずに済みます




 キャラクター移動判定 プログラミング 

さて、マップとキャラクターの表示
プログラムに実装できました




この時点で数字を記号などに変えて表示して
マップっぽくしても良いのですが
それはまた後の章で・・


ここからは
キャラクターが移動するプログラム
組んでいきましょう





キーボードからの入力を受け付けます

キーボードから入力を受け付けるには
std::cin(シーイン)
を使用します



先ほどはクラスstd::cout
<<を使用して値を渡して画面表示しましたが、
次は>>を使用して変数に値を渡します



キャラ移動用の変数として用意した
にキーボード入力した値を渡します

std::cin > >k;


この1文を入れると
変数 k
キーボードで入力した値が入ります





入力された値への条件式を作ります

次に変数の値を
上下左右として判定する
条件式を作ります



今回は
テンキーで上下左右を判定するプログラムに
してみます



 7 8 9 
4 5 6
 1 2 3 


が上、が右、のような感じです




条件式は以下のようになります

if(k==8){//上}
else if(k==4){//左}
else if(k==6){//右}
else if(k==2){//下}
else{//それ以外の入力}



上下左右とする値以外が入力された時
else{}
を実行します





キャラクター移動の条件式を作ります

上下左右の判定が出来たので
いよいよキャラクターを移動させるプログラム作成です



if(k==8){}
上が押された場合・・


if(map[y– 1][x] == 1) {y--; }



この条件式の意味は
キャラクターの居る場所から座標ー1
マップの数字が「1」ならば
です



実行命令は
y--;
y座標の値をマイナス1しろ
です




簡単に言うと
「キャラクターが上に行った時、その場所が平地なら進め」です




同様に各方向の条件式を作ると・・

if (k == 8) { if(map[y– 1][x] == 1) { y--; }
else if(k == 4) { if(map[y][x – 1] == 1) { x--; }
else if(k== 6) {if(map[y][x + 1] == 1) { x++; }
else if(k== 2) { if(map[y+ 1][x] == 1) { y++; }
else{}


これでキャラクター移動の条件式は
完成しました





マップ表示とキャラ移動をループする


キーボード入力
キャラ移動条件式は完成したのですが

これらのプログラムを
どう組み込めば
うまく動作するでしょう?



マップ表示
キーボード入力
判定・移動
(繰り返し)


という順でループすれば
最初にマップが表示され、
入力されたら条件式実行して
再びマップが表示されます





このループを実装し
プログラムを完成させてみましょう

#include <iostream >
#include <windows.h >//Beep(); 関数用ヘッダー

int main()
{
  int map[10][10] = {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,2,2,2,2,2,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,1,1,1,1,2,0,0},
  {0,0,2,2,1,1,2,2,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  };
  int x=4, y=3;
  int i, j, k;


   while(1) {//無限ループ

     std::system( “cls “);//画面クリア

    //↓マップ・キャラ表示
     for (i= 0; i < 10; i++) {
      for (j = 0; j < 10; j++) {
        if(y==i & &x==j) {
          std::cout < < "* “;
        }
        else{
          std::cout < < map[i][j];
        }
      }
      std::cout < < "¥n “;
     }

    std::cin > > k;//キーボード入力

    if(k== 8) {
      if(map[y – 1][x] == 1) { y--; Beep(830, 800);} //平地ならば上移動
      else{ Beep(440, 800); }//壁・無なら移動しない
     }
    else if (k== 4) {
      if(map[y][x – 1] == 1) { x--; Beep(830, 800); }//左移動
      else{ Beep(440, 800); }
    }
    else if(k== 6) {
      if(map[y][x + 1] == 1) { x++; Beep(830, 800);} //右移動
      else{ Beep(440, 800); }
    }
    else if(k== 2) {
       if(map[y + 1][x] == 1) { y++; Beep(830, 800); }//下移動
       else{ Beep(440, 800); } }
    else{ break; }//2,4,6,8 以外が入力されたら終了
  }
}


これでマップ表示とキャラクター移動のプログラムは
完成となります




main()関数内は
while文で無限ループとなっています

そして条件式のelse{break;}で
2,4,6,8以外が入力された時
無限ループを抜けるようになっています




マップ表示をする際、
std::system( “cls “);
を実行して画面上の文字を全て消去しています




移動できた時は高音、
移動できなかった時は低音の
Beep音を鳴らすようにしています





え・・これで完成??
ショボいんですけど・・


と思うかもしれませんが、
この基本の仕組み、プログラミングを覚えれば
いろいろと応用が出来ます


環境によっては
かなり見栄えの良いマップに化けるので
まずは「仕組みを覚えた」
と思って頂ければと思います






章末尾に
この章で解説したコンソールアプリを
ダウンロードできるようにしています




このコンテンツで使用したソースコードは
改変利用可能なオープンソースです

ご自身のソフトウェアに使用して頂いて構いません




この章の解説動画です



コンソールアプリ ダウンロード(11.5 KB)

ダウンロードが出来ない方へ