ゲームプログラミング/RPG

本ページ『ゲームプログラミング/RPG』では原則、あまり(あるいは「まったく」)、いわゆるドラクエ的な意味での「RPG」の難易度デザインやそのためのパラメータ調整などのゲームデザインに関する話題は扱いません。
なぜなら、本書『ゲームプログラミング』は、題名にもあるとおりプログラミングの教科書だからです。つまり本書は、RPGのゲームデザイン論の教科書ではないです。
難易度デザインについては、RPG限定ではないですが本wikiでは別途、『ゲームプログラミング/バランス調整』という難易度デザインに特化した目的のページが切り離されて存在しているので、そちらをご利用ください。
同様に、ゲームシナリオやイラスト素材や音楽素材などの制作など自前のRPG制作に必要なその他の知識も説明しません。もしかしたら必要に応じて「ドットエディタ」などのキャラチップ制作ツールの存在や最低限のIT的な説明はするかもしれませんが、しかしデッサン的な話題は一切しません。
市販のゲームクリエイター教育書には、一切、RPGのプログラミング解説書はありません。
一応、アクションゲームについては書籍『ゲームプログラマになる前に覚えておきたい技術』や『ゲームプログラミングC++ 』などがありますが、その書籍は別にRPGには限定しておらず、どちらかというとアクションゲーム寄りの内容かもしれません(たとえば『ゲームプログラミングC++』では「衝突検知」などの話題がある)。
そういった出版事情もあり、本ページでは、出典のないRPGゲームプログラミング技法を多く紹介しています。
出典がなくても、プログラミングについては実際に Visual Studio などのコンパイラでその技法を確認してみれば真偽の確認ができますので、読者ご自身で真偽をご確認ください。
本ページに限らず『C言語』や『JavaScript』などの本wikiのプログラミング言語の教科書も同様に、プログラミング技法については特に出典はないスタイルです(出典があるのは、主に用語や歴史などの説明に関する出典だったりする)。
想定読者として、そういう御自身でコンパイラでコードをビルドして確認できるレベルの人を本ページでは想定していますので、もし読者がそれに到達していないなら、このページからは決して学ばないでください。
実際のゲームプログラミングでは、たとえ無音声の2Dゲームですら、計算処理の他にグラフィックやキーボード入力など多くの機能が連動するので、コードはかなり長くなります。無音2Dのシンプルな超短編ゲームですら、初心者でもコードが何千行やあるいは1万行以上にもなります。
そのため、本wikiでは動作ソースコードの全部は到底、紹介できないです。だから本wikiで紹介されているコードをコピーペーストしても、それだけでは動かないのが普通です。
本ページにあるC言語のコードは、プログラミングでRPGを作る際に、「たぶん多くの人はこういった点が気になって悩むと思うから、こういうふうにコード記述すれば解決できると思います」といった方針だけを提供するものに過ぎません。
あるいは、もし本書で紹介したコードで動作したとしても、そのコードの結果はコマンドプロンプト(DOSプロンプト)のような真っ黒い画面で、RPG的な計算内容による計算結果だけを表示するプログラムだったりするので、そのままでは他人に遊んでもらえるような実際のゲームではないので、したがって実際のゲームプログラミング時には映像の表示などのためのコード追加がかなり多く必要になります。
本ページのRPGは、ターン制の戦闘システムを採用したRPG(Turn-based RPG)を中心にとり扱う。アクションRPGやシミュレーションRPG、アクティブバトルなどを語る場合には、注記する。
以下のものは取り扱わない。
なお、本ページでは説明のためにC言語を用いている。C言語の理解を前提としている箇所が存在するため、もし読者が知識をお持ちでない場合は、適切な媒体で調べながら読み進めていただきたい。 本ページではC言語を説明のために用いているが、開発環境がそれ以外の言語である場合は、適宜読み替えていただきたい。


一応、ターン制RPGは関数や配列を知らなくても、作り始めることはできます。
最低限必要な知識として、変数と、キーボード入出力の関数と、if文、タイマー関連、画面出力、あとはせいぜい乱数などがあれば、ゲームを作り始めることができます。
これはRPGにかぎらず、よくプログラミング入門書にあるジャンケンゲームなども同様でしょう。ジャンケンゲームならタイマーすら不要でしょう。
しかし、「関数を知らないプログラミング」とは、たとえば、zボタン(決定ボタンとする)を押したときのプログラム記述で、DXライブラリでの開発なら、マップ画面モードでも戦闘コマンド画面モードでもタイマーをカウント開始すると思いますが、そのタイマーの開始命令と関連する処置を各画面ごとに1行ずつ書いていく方式です。
だからもし、バグなどがあってコード修正する際、すべての画面モードのzボタンを命令を一個ずつ直さなければなりません。RPGはモードが多いので、そのような修正は、なかなか面倒です。
だから、別に作り始めの時点で関数を知らなくてもいいのですが、しかし作っている途中に「バグの訂正で似た部分の繰り返しが多くて面倒だなあ・・・」という気分になったら関数も勉強していくのが望ましいでしょう。
そして、いつごろが関数を学ぶタイミングなのかを知るには、事前に自分がある程度は「関数というものがあって、コードの使いまわしに便利なものらしい」という知識が必要です。
配列も同様です。配列を知らなくても、パーテイ1人目のHPを変数名「p1HP」、パーティ2人目のHPを変数名「p2HP」のような方式でRPGを作れます。
しかし、これを敵15体も登録されているRPGで「m1HP」から「m15HP」とやるのは、少し面倒です。
なにより一番の問題は、配列を知らないと、ドラクエ1的なマップ画面すら作るのが、かなり困難になることです。
よくプログラミング教本などにある例では、マップを二次元配列で実装しています。
たとえば、書籍『12歳から始めるゼロからのC言語 ゲームプログラミング教室』がそうです。
たとえば、
みたいな感じで、0番が草原、1番が森、2番が岩山、のような感じです。
横10×縦5のマップはそれほど広くないですが、
たったこれだけのマップでも、もし配列を知らなければ変数が50個必要です。
「配列を知らなくてもRPGを作れる」というのは、たしかにノンフィールドRPGなどは作れますし、
あるいはフィールドがあっても「マップはすべて草原、あるいはマップの99%くらいが草原(草原でないところだけ変数指定する方式)」のようなゲームなら作れますが、
しかしそれは、多くのRPGプログラミング入門者が考えているような、ファミコン~スーファミ水準のドラクエ・ファイファン的なイメージのRPGとは異なります。
初心者に「配列を知らなくてもいい」というのは無責任です。
配列を知らなくてもゲームプログラミングは開始できますが、もしも配列が必要になった時点で(変数を一個ずつ宣言するのが面倒なモジュールを作るとき)、 配列を学び始めるのが良いでしょう。

別に市販のC言語の入門書の基礎文法すべてに精通してからゲームプログラミングを開始する必要はありません。
おおよその機能だけを市販のC言語入門書に目を通して知っておいて、プログラミングでは変数などの初歩的な知識だけを用いて作り始め、足りない知識は必要になったらそのたびに、市販の入門書などで学べばいいのです、
また、その市販のC言語入門書を読む時間も、通学中・通勤中で電車のイスに座ってる時に読むとか、あるいはトイレでウンコしている時に読むとか、そういう時に読めば、プログラミングの時間を減らさずに時間を有効活用できます(ただし睡眠時間や食事の時間などは減らさないようにしましょう)。
さて、セーブやロードなどの機能は、当分は不要です。そもそも、セーブが必要なほどの長さのシナリオなんて作るのは当分は後です。もしお作りのゲームが1分でクリアできるようなゲームなら、セーブなんて不要でしょう。
だから、C言語のファイル入出力の機能などは、当分は不要です。
つまり「学んでから作る」ではなく「作っているうちに気になった点を調べる」のがコツでしょう。
おそらく「関数を知らなくてもRPG作れる」といっているプログラマーはたぶんそういう事を言いたかった口ベタな人なのでしょう。
なお、配列や関数などは、自分が直接は使わなくても、他人が使います。
たとえば、マップの実装で、もしかしたら二次元配列を使わなくても、原理的には一次元配列を何十個も並べて実装する方法もあるかもしれませんが、しかし他人がそういう一次元配列を何十個も並べてマップ実装したコードなんて読みたくないし、教育者も面倒なのでそういうコードを教えてくれません。
なお、構造体は別に知らなくてもRPGは作れます。列挙体 enum なども同様です。単に構造体の配列を知っていると、(装備品やモンスターなどの)データベースを第三者がより読みやすい形で作りやすくなるだけです。列挙体を知っていると、モードの切り替え(マップ画面モードからメニュー画面モードへの切り替え等)をしやすくなります。
正直、市販の「ゲームプログラマー向け」をうたったプログラミング教本の中には、少なくともゲームプログラマー初心者の時点では不要な高度な知識も多く紹介されています。しかしそういう本でも、出版社などの宣伝の都合からか、「プログラマーになる前に読んでおきたい」みたいな宣伝文句が付けられたりしているかもしれません。そういう高度な知識もあとで仕事で必要になる場合がありうるので、ゲームプログラマー向けとして出版する事自体は正しいのですが、しかし初心者や入門書に進めるような宣伝文句をつけるべきかというと疑問となる内容の市販本もあります。

よく、「ポインタによる処理で速度の向上!」みたいな事が、ゲーム好きのプログラマーに言われます。
しかしポインタによるコーディングは、プログラムのメンテナンス性を悪くします。なぜならもしポインタ使用個所の周辺でバグが発生した場合に、ポインタがあると原因が特定しづらくなるからです。
一般のグローバル変数やローカル変数と比べてポインタ変数は仕組みが単純ではないことや、配列や構造体にポインタなどを用いる場合はもしその配列・構造体にバグがあると同じ配列内・構造体の別の部分にまでバグが波及するなどするので(コードによっては、もしかしたら、下手したら周辺の別の配列や構造体に波及する場合もありうるかも)、ポインタで実装されたモジュールがあるとバグ発生時に原因の絞込みが難しくなるのです。
もし仮にポインタ処理化を実装した直後では正常に動いていても、しかしあとで、今まで未実装だった部分が実装された場合に、なんらかの不整合によるバグが発生するようなことも良くあり、ポインタ処理はその際、バグ原因の特定を難しくします。
だから仮にどうしてもポインタを使わないといけない場合でも、RPG製作なら、なるべくポインタを実装するのは後回しにして、当分は一般の変数で実装したままにしておくほうが良いかもしれません。
あるいは、もし機能の実験や勉強を兼ねてポインタ処理の実験と実装をしたのなら、現状ではポインタ変数で実装してある箇所でも、あとでデバッグなどの際に一般の変数に戻す可能性も考慮することになります。
RPGの場合、デバッグに時間を多くとられますし、変数がとても多いので、メンテナンス性も考慮せざるを得ません。

ポインタによって高速化のメリットが得られる場合とは、C言語教科書などの理論では、大量の要素の構造体を(関数の引数などとして利用する際に)コピーする場合ぐらいです。
だからもし構造体を使う場合であっても、そもそも自作で用いる構造体変数がグローバル変数であればコピーの必要自体がないので、ポインタの必要もありません。
ゲーム内の武器データベースやモンスターデータベースなどが構造体で実装されると思いますが、初心者なら普通はそれらの構造体変数はグローバル変数として実装することになるでしょうし、グローバル変数として実装しても何も困りませんし、実際それでもRPGを作れますし、正常な速度で動きます。
例外的な事例を考えるなら、たとえばマップイベントのデータベースなど、特定のモードでしか使う機会のないデータベースなら、理論的にはグローバル変数でなくポインタによる取り扱いによって処理速度の向上の可能性はありえますが、しかし正直メンテナンス性が悪いし、難しい割にはポインタ化してもしなくても初心者ゲームのレベルでは速度は変わりません。せいぜい勉強になるだけです。
こういう風に、市販のC言語教科書にある知識の一つ覚えは、通用しません。
ターン制RPGは、身体障害などでアクションゲームなど反射神経を要するゲームの苦手な人もプレイします。なので、それを意識した設計にしましょう。シミュレーションゲームも同様です。もっとも、さすがに腕のないプレイヤーにまでは配慮できないので、程度問題ですが。
ともかく、だから、もしどうしても制作中のターン制RPGにアクション要素のあるイベントを入れる場合、たとえば工夫として、
事前にそういうアクションイベントのあることをプレイヤーに作品紹介文などで紹介しておくとか、
あるいはそのアクションイベントをもしクリアできなくてもプレイヤーがゲームクリアできるように設計するなどの配慮が望ましいでしょう。
もしくは、充分にアクション要素の難易度を下げておく必要があるかもしれません。

もしもC言語でゼロからゲームを作るなら、UI(ユーザーインターフェース)をゼロからDirectXなどで作ることになります。 シナリオどうこうより、まずUIを作るのが真っ先になります。
結論から言うと、需要のあるUIの種類はそんなに多くなく、よって最終的には既存の有名ゲームのUIを真似することになります。(練習として新規のUIを色々と制作してみるのは構いませんが、しかし実用的なものを新規に発明するのは困難かと。)
RPGなどで選択肢で『はい』か『いいえ』がよく出ることがあります。
この場合、必ずしも順番どおりに
とするのが良いとは限りません。
なぜなら、プレイヤーがセリフ送りなどでボタンを連打している場合に、あやまって選択肢も連打してしまうことがあるからです。
文献『ゲームプランとデザインの教科書』によると、選択肢の順序についての設計テクニックとして、現状を維持するほうの選択項目を先に表示したりとか、あるいはマウス操作式のゲームなら現状維持や安全なほうの選択肢にカーソルを事前に合わせておくなどの工夫が、定石とされています。

例えば、コマンド選択などのカーソルの方式には、
など幾つかあります。
カーソル点滅させる場合、実はこれはほとんど、カーソル点滅色は白系の色にせざるを得ません。
なぜなら健康上の理由があり、もし青色ウィンドウなのに、たとえばカーソル色を赤(または緑にして)、赤カーソルを点滅させると、「光過敏性てんかん」のような症状を引き起こします。このため、点滅カーソルの背景色は、事実上は、ほぼ白色に決まります。
一応、白でなくても、たとえば青ウィンドウなら水色などの背景色でも可能ですが、手間が増えますし、ほかのウィンドウ色(たとえばウィンドウを赤に変更した場合)では応用が利きません。
ゲームによっては設定カスタマイズなどでウィンドウ色を変えられたりしますが、プログラマー的に分析するコツとしては、カスタマイズできない部分(たとえばカーソル色はカスタマイズできない等)にも注目すると良いでしょう。
なお、色弱(しきじゃく)/色盲(しきもう)という病気があり、緑色と赤色の区別がつきづらい人が、世間には居ます(赤緑色盲)。例外の人もいて、青など他の色が見えない人もいますが、しかし色弱患者で統計的に割合がもっとも多いのは赤緑色盲です。
赤緑色盲の人には、赤も緑も、ともに茶色に見えます。なので赤緑色盲の人にあ、赤と緑を区別できないのです。
よって事実上、ウィンドウ色は原則的に青色になります。ファイナルファンタジーや昔のツクールなどが、ウィンドウ色に青色を標準的に採用しているのは、決して偶然ではなく、いろいろな事情があるのです。
どうしても同一画面に赤と緑を表示しなければならない場合、色の濃さを変えるなどして、たとえば濃い緑と、うすい赤、などのように濃度差をつけるなどする必要があります。(この濃度差の手法は、役所などの出す、色覚障碍者向けのガイドラインなどにも書いてある、典型的なアドバイスです。 ) そもそも、色盲でなく健常者でも、濃度の同じくらいの赤色と緑色の組み合わせは、やや見えづらいです。 学校の「黒板」という緑色の板に、赤チョークで書かれた文字が、見づらかった記憶をもつ人も多いでしょう。
なお、赤緑色盲の人でも、黄色は、茶色とは区別して見えます。
なのでウィンドウに、黄色っぽい色と黒を組み合わせて使うのも手です。
あるいは、うすい茶色に、黒い文字という組み合わせもあります。
たとえばロマサガ1は、うすい茶色のウィンドウに、黒い文字です。うすい茶色と黒との組み合わせは、明度も大きく異なっているので、良い組み合わせでしょう。
スーファミ版の三国志4のウィンドウ色と文字色も、似たような組み合わせです。ただし三国志4の場合、文字に白い文字を使う場合もあります。数値などは白い文字です。このため、ウィンドウの茶色部分にはザラザラした模様をつけて白い文字を際立たせる工夫をしたりなど、工夫をしています。
ゲームに限らず、たとえば子供むけの歴史教材や小中学校の歴史教科書などでも、よくコラム欄などで、黄色い背景に黒い文字の組み合わせは使われます。古文書のような古い紙は黄ばんでいるので、歴史教材のコラムではそういう雰囲気に近づける目的で、コラムの枠を古文書の一ページのように描いているものもあります。
ゲームでもロマサガ1のメニューウィンドウは、古文書のように紙の下側の一部が書けていたり、まるで巻物の読み方のように左右が曲げられていたりして、ウィンドウに紙っぽさを出すデザインをしています。
例外的に、商業ゲームでもプレステ作品『俺の屍を越えてゆけ』のようにウィンドウがエンジ色(赤色っぽい色)の作品もあります。このようなUIの差異、当然ですが緑色の文字は使用不可能です。
光の点滅以外にも、調整を誤るとプレイヤーに体調不良を及ぼす現象はあります。 、 たとえばキャラの移動速度の加速・減速は、なるべく滑らかに変化しなければなりません。
「車酔い」を思い出してください。もし急加速と急ブレーキを繰り返す車に乗車していれば、多くの乗客は酔います。
なので、たとえばRPGなどで、「マップの1マス移動後にいったん停止」というのは、避けたほうが安全です。
実際、ドラクエは決してそうなってはいません。行き止まりに当たらない限り、カーソルの左ボタンを押していれば、同じ速度で左に進み続けます。(右キーの場合も同様。)
ドラクエの移動速度が等速度であることには、合理的な理由があるのです。

自作ゲームでテストした際、マップ移動中に右キーを押し続けたときに普段は等速で移動するのに時々カタつく場合があるかもしれません。その場合の対処法を後述で説明します。(2Dゲームのマップ機能の原理については、セクション『ゲームプログラミング/RPG#2Dマップ』で後述してある。)
なお、普段から等速ですら移動しない場合は、単にバグですので、直してください。
このセクションでは、とりあえず普段は右キーを押し続けたら等速で移動するのに時々カタつく場合にだけ、よくある原因そのと対処法を説明します。
時々テストプレイ中に動作がカタつくことがあり、「バグか?」と不安になることがありますが、しかし必ずしもバグが原因でのカタつきとは限りません。
もしかしたら、Visual Studio コンパイラがメモリ圧迫またはCPU占有などをしていて、単に実行アプリの処理速度が低下しているだけかもしれません。プログラミングに熱中していると盲点ですが、Visual Studio はメモリやCPUの多くを占有することを思い出しましょう。
原因がそれか否かを確かめる簡単な方法は、まったくほかのアプリを起動していないときに、実行ファイルを起動してテストプレイしてみることです。
ただし、状況によってはその「実行ファイル」をビルドするためにVisual Studio を立ち上げないといけない場合もあり、なかなか面倒な作業でもあります(VSは終了や起動に時間が掛かるので面倒)。
1度に確認しようとすると面倒ですので、複数日に分けて確認しましょう。たとえば、このカタツキ問題が気になったときの睡眠前の晩にでも、事前に実行ファイルをビルドしておいてから Visual Studio を終了してから寝ましょう。そして翌日にでもwindows起動したときに、Visual Studio を起動せずに前日にビルドしておいた実行ファイルだけを起動してテストしてみましょう。
そのほか、この問題の検証方法として、どうしても Visual Studio 起動中に、メモリやCPUの圧迫によってカタついているか否かを判定したいなら、簡易的な方法ですが、
最近のRPGツクール製のゲームまたはウディタのサンプルゲームを起動してみて、カタつくかどうかを確かめてみる方法もあります。
もしVisual Studio によるメモリ圧迫やCPU占有がカタつきの原因なら、ツクール製ゲームやウディタサンプルゲームでもカタつくことがあります。いわゆる対照実験です(中学高校の理科(おもに生物分野)で習うアレです)。
上述の方法すべてを試してもカタつきの問題を判明できない場合、残念ですが当ページには原因がもはや分からないのが現状です。(もしお作りのRPGでのカタツキの原因が分かられて、他のプログラマーも遭遇しそうな原因でありましたら、情報提供のため編集に協力していただければ当wikiとしては幸い(さいわい)かもしれません。)

前セクションの工夫でカタつきが解決すれば、下記の方法は不要です。また、ヘタにいじってバグの原因になると危険ですので、前セクションで解決したなら、そのままにするのをお勧めします。このセクションでは、参考のため、下記のような方法の検討を照会します。
動作をより滑らかにする工夫の一例として、たとえば、キーボードの十字キーの入力判定は、必ず1マス歩行のアニメーションの移動終了の少し前までに、判定を終わらせる工夫などが、考えられます。たとえば、1マス歩行のアニメーションが1.0秒かかるなら、入力判定は0.9秒目に行う、というような感じになります。
しかし、これはけっこう、シビアな条件であり、0.1秒単位でのタイミング調整を行わなければなりません。
歩行で1.0秒間というのは、割とゆっくりです。
一方、もしダッシュ機能とかあってダッシュ速度が1マスあたり0.5秒間だと、すこしタイミング調整が難しくなるでしょう。
もっと早いダッシュの場合は、Windowsだと少し難しいかもしれません。なぜなら、WindowsAPIのタイマー機能がそもそも、そんなに正確ではありません。0.05~0.10秒くらいの間隔になると、タイマーに誤差が出てきます。 DirectXのタイマーも、それに準じた性能だろうと思われます。なので、あまりに早すぎるダッシュでは、歩行のように「直前に入力判定」というのが、難しいかもしれません。
あるいは、もしかしたら、現代のコンピュータは処理速度が速いので、1.0秒のアニメーション終了後に入力判定を行っても、プレイヤーには気づかれないのかもしれません。
しかし、ハードウェアのメモリ容量などの事情によっては、もしかしたらアニメーション終了後の方式だと、動きにカクツキが出てくるかもしれません。ともかく、このように、速度ひとつとっても色々と考えなければならないことがあります。
こういうふうに、歩行アニメーション処理は、こりだすと、検討事項や調整事項が意外とあるので、初心者にはやや難しいです。
だから初心者には、歩行アニメーション抜きの方式がラクであり、いきなりキャラチップが移動先の隣マスに移動する方式(ファミコン時代の『信長の野望 武将風雲録』の戦闘の武将キャラチップみたいなの)のほうが、簡単でしょう。
同じ理由で、カメラの位置や向きなども、むやみに移動しないか、等速で移動しつづけるように注意する必要があります。
もし、「リアリティを出そう」としてカメラをキャラ歩行のたびに左右に振ると。プレイヤーが酔って気分が悪くなりかねません。よほど上手く調整しないかぎり、プレイヤーの体調的な気分を悪くしかねません。
だからカメラアングルで目指すべきは、2Dゲームなら結局、スーファミあたりのドラクエ的あるいはスーパーマリオ的な古典的なカメラ視点であるべきす。あるいは、もしポリゴンゲームなら、結局、カメラアングルで目指すべきは、プレステ1やサターンの時代のころのゲームのカメラアングルなどになるでしょうか。
あるいは、ファミコン時代にどうしても歩行アニメーションを停止しなければならなかった例として、ファミコン時代のウィザードリィや女神転生の3Dダンジョンのように、ポリゴン描写が無理などの理由で、どうしても停止しなければならない場合もあるでしょう。このような場合は、おそらくですが、停止中の1枚絵の表示時間の長さと、進行中の中割り(なかわり)の1枚絵の表示時間の長さが、同じぐらいの長さになるようにしないと、マズイでしょう(未確認)。
UIにおいて、アナログをデジタルで完全に実装するのは、大概困難ですが、アナログの「エミュレート」の実装は、それほど困難ではありません。
これはゲーム制作でも同様です。
たとえば、RPGの作中の武器屋や道具屋などでの買い物のシステムは、現実のスーパーマーケットやコンビニでの買い物とは異なり、まとめ買いはサポートされていないことが有ります。
ゲーム以外の話だと、たとえば通販サイトでの買い物の際、ユーザーレベルの目線では、サーバー側で異なるアイテムを連続して買う行動が一連のトランザクションとして処理されていたとしても、同様のことがありえます。
さて、ゲームでは、プレイヤーにとっては操作がやや面倒でも、デバッグの都合やメンテナンス等の都合で、あえてデジタル的な操作をしているゲームもあります。
たとえば昔のドラクエ3では、酒場で仲間をパーティに加入させる際、1人ずつ逐次的にコマンド入力をして加入させる必要がありました。(「3人まとめて加入」とかしたくでも、できない仕様。)ウィザードリィなどでも同様で、仲間のパーティ加入の編成などは、一人ずつ逐次的に操作する必要がありました。
このような、「まとめて〇〇を編集・編成」みたいな処理は、その分状態(取り得るケース)が増えるため、それに比例してデバッグにかかるコストが増える場合が有ります。

DXライブラリは、標準的な映像モニタでは、1秒間に60回のループ更新をします。
これは、一般的な映像モニターの画像の更新回数が60Hz、つまり映像モニタでは1秒間あたり60回の更新があるので、 プログラム側の更新回数もそれにあわせたものです。(これらのことを「60 FPS」などという。)
このような、映像の更新の早さの度合いのことをフレームレートといいます。
さて、人間の計算速度と比べたら「1秒間に60回」は速いですが、しかしゲームとしては、必ずしも速くありませんので、そのギャップに気づかないとプログラマーは不安に「パソコンが処理落ちしてるのか?」と悩んでしまいます。
たとえば、アニメーションの表現などとして、キャタクター立ち絵が1ピクセル(1px)ずつ1回の画像更新で移動したとしましょう。
すると、1秒たっても60pxしか移動しません。RPGツクールの標準の画面サイズは横816px、縦624pxなので、つまり60pxの移動では、画面の10%にすら到達していません。なので、もっと早い速度で立ち絵を移動させたい場合、1回の更新で3pxや5pxあるいはそれ以上のピッチ間隔で画像を移動させる必要があります。
このことに気づかないと、立ち絵の高速移動のつもりで1pxずつ動かしても、画面の横幅の10%すら動いてないので、「まるで処理落ちでもしているのか」と錯覚しがちで不安になりますが、しかし1pxずつ動かした際に意外と遅く見えるのは正常な動作です。そういう速度計算での命令文だからです。
具体的にはどう悩むかと言うと、RPG制作の場合ならばマップチップの枚数が多いので「もしかしてマップチップの読み込み方が間違っていて処理落ちしているのか?」とか、あるいは「キャラ画像の周囲の透明処理による負担が重いのか?」とか色々と不安を思ってしまいますが、まったくの無関係です。
1更新あたりに1pxのピッチ速度とは、それだけ遅いのです。なので、1秒後に画面内でチョコっとしか動かなくても、1秒後に動き終わっていれば正常です。
さて、ついでの話題ですが、もしアクションゲームやシューティングゲームなどで、1更新あたり5pxや10pxといったピッチで攻撃対象の敵などが動いている場合を考えて見ましょう。
たとえば、もし移動中画面で、現在の瞬間の描画位置 から 次の瞬間の描画位置とのあいだの中間位置、つまりピッチの中間の場所に自キャラの放った攻撃などが当たったときの例を考えてみると、なかなか悩ましい問題でもあります。つまり、画面上ではピッチの中間の場所には映像が書かれていないのに、なのに、その場所に攻撃を食らう「当たり判定」が存在するからです。
実際、アクションゲームなどで、高速で動く敵の軌道上に攻撃を放ってみると、画面上にいない位置なのに、攻撃があたる場合もあります。
だからファミコン時代あるいはそれ以前のゲームセンター時代といった黎明期のシューティングゲームですら、高速で動く弾丸チップや機体チップなどの表現には、とても工夫しているのでしょう。
このように、キャラチップなどの画像を高速で動かすのは、思いのほか、調整事項が多くて大変です。なのでRPG制作の初心者は、あまり高速な描画表現には手を出さないほうが無難です(まずプログラミングの全体像を作る必要あるので)。

少なくとも2D-RPGのゲームシステムやその実装に関する限り、処理が早くて操作性も良くてメンテナンスもしやすくて・・・のような究極万全なシステムやアルゴリズムは一切ありません。
たとえば操作性の分かりやすいアルゴリズムなら、おそらくはプレイヤーのさまざまな発想に対応するためにif文の分岐増えたり、あるいはグラフィカルに説明するために画像の制御が追加で多く必要になったりするなどして、そのぶん他の特性が悪化しますし、説明用グラフィックが増えれば処理速度の負担にもなります。
しかし現在のパソコンではファミコン時代よりも桁違いに多くのメモリ容量を扱えるようになり、CPU性能も桁違いに向上しました。よってゲームプログラミングでは基本、処理落ちをしない程度にまで処理速度に負担を掛けて犠牲にして、そのぶん操作性やグラフィック性やゲーム性やメンテナンス性などを向上させることになるでしょう。
だから実はファミコン風のドラクエ1のような簡素なプログラムでも、あれはあれで処理速度とメンテナンス性をもし最優先に目指すなら現在でも合理的な一形態なのです。
また、ドラクエ1的なアルゴリズムはメンテナンス性がよいので開発もしやすいし、開発時のデバッグもしやすいです。なので、私たちがRPGを手元でプログラミングして作る場合も、まず2D-RPGならドラクエ1~3のようなUIをまねたゲームを作ることになるでしょう。
ただし、真似るのはあくまでUIのみです。パスワードシステムのような、セーブ機能の発達した現在では不要なシステムを真似る必要はありません。「話す」コマンドとか「とびら」コマンドみたいに、現代では不要になったコマンドも不要でしょう。また、ドラクエのウィンドウ色は黒色ですが、しかし私たちにはデバッグの都合のためファイナルファンタジーや昔のツクールのような青色を基調としたウィンドウのほうがデバッグしやすいかもしれません。
だから初心者は、昔のRPGツクールっぽくアレンジしたドラクエ風UIを作ることになるでしょう。(ドラクエの難易度デザインやストーリー性などはプログラミングではないので、本ページでは言及しません。)
本ページでは説明の都合上、RPGをモジュールごとに分割して説明しています。
たとえば、マップ関連のモジュール、戦闘関連のモジュール、装備関連のモジュール、のようにです、
しかし、実際のゲーム製作での開発順序は、少なくともRPGをVisual C++でゼロから作る場合においては、けっして、「マップモジュ-ルを完成させてから戦闘モジュール」のような順序にはなりません。
そうではなく、まず自分が興味をもったモジュール(仮にマップモジュールとする)の初歩を作り始めたあと、とりあえず操作できて満足できるところまで作ったら、
次に関連する別モジュール(たとえば戦闘モジュール)を作る、というような順序です。
たとえば、すでにマップモジュールがあるなら、戦闘モジュールを作り始める際に、まずマップ画面上に固定敵を配置することで、
戦闘モジュールのテストをしやすくなります。
このように、すでに作ったモジュールの初歩を土台にして、別のモジュールの初歩を同様に作り始めます。
そして、まずRPGの基本システムを満足するところまで作ります。(シナリオ作成などは後回しになるでしょう。)
マップシステム、戦闘システム、装備システム、道具システム、買い物システム、酒場システム、会話システム、・・・
など色々あるので、まず一通り、好きなシステムから順に、キリのいいところまで作りこんで、どんどんと次に作りたいシステムの開発に移行していき、
とりあえずゲーム全体の基本システムを構築していくことになるでしょう。
そして、一通り、満足するまで基本システムを作るのを1周したら、
次に2周目として、また、たとえばマップのシステムを作り始めます。
1周目のマップシステム製作では放置してた部分、たとえばキャラチップの歩行グラフィックなど絵が必要で放置してた部分の製作に取り掛かるとか(たとえば1周目では矢印の画像でゴマかしていたとする)、
そのように2周目では、1週目で放置していた部分の製作にとりかかるのです。たとえば、歩行グラフィックで前足を上げているポーズと、前足を着地させるポーズの切り替えプログラムとか、そういう1周目では面倒で放置していた部分に、2周目では取り掛かったりします。

このように、RPGの製作は、まるでラセン階段を昇るかのように、周回的に開発していくことになるでしょう。

企業などで作る場合はどうか知りませんが、少なくともVisual C++でゼロからRPGを作る場合はラセン階段でしょう。
RPGはモジュールがとても多いし、また相互に関連するモジュールも幾多もあるので、一度に各モジュールを作りきるのは不可能です。
だから、ラセン階段のように、開発を昇っていくことになります。
なお、IY業界ではこういうラセン的に徐々に機能を追加していく開発手法を、スパイラル型の開発と言います。
スパイラル spiral とは、単に、らせん状の渦巻きのこと を英語にしたものです。なお、
なお、銀行などのシステム開発はこれとは違い、銀行のシステム開発はふつうはウォーターフォール型の開発です。ウォーターフォールとは、事前に仕様を細かく決めるのに長い時間をかけて、実装時にはほとんど仕様を変えない手法です。
ほか、プロトタイプ型の開発もあり、これは大まかに動く試作品を短期間で作り、あとから仕様を修正していく方式です。
ゲームに関した話題ではないですが、スマートフォンのアプリの開発などでは、プロトタイプ型やスパイラル型の開発がよく利用されるようになってきています。

RPGではシステム中にマップ画面モード、メニュー画面モード、戦闘画面モード、・・・など様々なモードがありますが、
DXライブラリを使っている場合にどのモードでも必ず使うことになる機能があり、それは自作タイマーのカウントアップです。
まず、DXライブラリでは1秒間に60ループするので、それを利用して1秒間に60回カウントアップする機能を作ります。
そして、そのカウンターを活用することで、たとえば、「zボタンを押してから40フレーム間(環境によっては約0.8秒くらい)は次のzボタンの入力を受けつけなくする」等のボタンをしばらく入力させなくする機能を作ります。
そうしないと、プレイヤーは1回だけzボタンを押したつもりでも、システム的には何十回もzボタンを連打したことになり、プレイヤーがうまくコマンド操作などを行えません。
また、コマンド操作などの他にも、マップ画面中でキャラクターがマップ1マスぶん動くスライドのアニメーションでも、カウンターが必要になります。
マップ画面の歩行グラフィックで「歩行カウンター」みたいな変数が必要になるでしょう。もしくは、歩行のキー入力に使った矢印キー用のカウンターを流用するなどの処置になるでしょう。
ともかく、このようなカウンター機能が必要なので、whileループ中での個別モードに分かれる前の共通部分のところに、カウントアップのコードを書くことになります。
「共通部分のところ」とはどこか具体的に言うと
のように、whileの開始のテンプレ文の直後に書き始めることになるでしょう。
なお、DXライブラリでよく書くことになる開始時のテンプレ文については 『ゲームプログラミング/画面出力#DXライブラリのコード初期設定』 で説明してある。
カウントアップではなくカウントダウンでも構いません。
イメージ的には、下記コードのような感じになります。ただし、下記のモジュールだけでは動きません。
あらかじめ、各モード側でzボタンを押した時などにカウンター値の設定などを行う必要があります。たとえばzボタンを押したときに
などをセットしておきます。また、zキー入力可能かどうかを判定するフラグ変数、下記コードでは変数 keyEnableZ となっていますが、そのようなフラグ変数をあらかじめ用意しておき、もし値が1なら入力可能、0なら入力不可能として、
zボタンに対応する処理を1回実行してからz=0;に設定して、zが0のときにカウンタが動くようにする必要があります。(ツクールなどではマップ画面からメニュー画面を開くのはx(エックス)ボタンだが、読者のバツボタンとの混同を防ぐため、上記の文ではzボタンを例に説明した。)

このコード例のように、共通カウンタ部では単にカウントするだけでなく、さらにカウンタが目標値(カウントダウン方式なら0が目標値)に到達したときの処理(フラグの設定など)も行います。
いきなり上記のような機能を作るのは、かなり難しいです。なぜなら、カウンタだけでなく、マップ画面やメニュー画面側のzボタン押し時やxボタン押し時の命令も記述しないといけないからです。
だからまずは、マップ画面とメニュー画面の入り口画面(まだメニュー画面の各コマンドは作らなくていい)だけでいいので、でキーのカウント処理をうまく行えるようにしましょう。
なお、メニュー画面に移ったらキャンセルボタンで戻せるように、あらかじめメニュー画面にキャンセル機能を実装しておきましょう。
新しい画面を作るときに最初に必要なボタン機能は、実はキャンセル機能です。キャンセル機能が無いと操作不能になって、いちいちアプリ再起動の手間が生じます。

いきなりマップ画面やメニュー画面を作るのは難しいので、ひとつの手として、RPGを作る前に、簡易的なアクションゲームのような操作性のプログラム、または簡易シューティングゲームの操作性のようなプログラムを作るのも手です。
たとえば、スーパーマリオやスト2のようなアクションゲームなら、ジャンプボタンは1回入力したら着地までは再入力の受付が禁止なので、上記のようなカウンタ処理による再入力可否の制御が実験できます。
べつに、本格的にアクションゲームやシューティングゲームを作る必要はないです。後述のように、異なるジャンルのゲームをひとつのアプリに同梱するのは、管理の手間が増えますので(不可能ではないですが)、面倒が生じます。
これには準備として、マリオ(キャラ名)やスト2リュウに相当する自キャラ表示のため、あらかじめキャラチップの絵が必要です。別にアクションゲームを作るわけではないので、マウスでいいので何かキャラの全身絵を3分くらいで雑に書いてください。そして、キャラの周囲の空白部を、ドットエディタなどを使って透過させてください。(あるいはinkscapeを使ってキャラ絵を書いて、PNGエクスポートする、などの手法もあります。)
ジャンプさえ出来る絵であればいいので、すでに手元にゲーム用キャラチップっぽい大きさの生き物の絵があるなら、別に人物の絵である必要もなく、動物の絵でもモンスター画でも何でも構いません。
さて、なんとかジャンプの実験に成功したら、ついつい次の目標で「右歩行中にジャンプして右斜め上に飛ぶ」機能とかを実装したくなりますが、本ページはRPGの教科書なので、アクション機能については説明を省略します。

ミニゲームとしてターン制RPG以外のジャンルのゲームを同梱するなら(たとえばシューティングなど。ファミコン『さんまの名探偵』では推理ゲーム中、シューティングゲームのミニゲームがあった)、別途、そのミニゲーム用の各モード前の共通部分に、ミニゲーム用のカウンタが必要になるかもしれません。
ターン制RPGとアクショゲーム・シューティングゲームは、カウンターに要求される待機時間が違ってくることと(ターン制RPGの操作はゆっくりめでいいので待機時間を多目にとれるが、しかしアクションは機敏な動作に対応するため待機時間が短い)、カウンタが目標値に到達したときの処理がRPGとアクションとで違うので(たとえばRPGなら決定ボタンを押したままの状態なら目標値の直後に受け付けしてもいいが、アクションゲームでは決定ボタンがジャンプやパンチに対応していることから、プレイヤーにパンチ連打などのためにボタン連打させたい場合は目標値直後の処理を変える必要があることなどから)、RPGとアクションを混在させるのは(可能ではあるが)難しいことが予想できます。
だから、もしあるゲーム中に別ジャンルのミニゲームを同梱するなら、メインとなるホスト側のジャンルを決めて、そのメインジャンルのカウンタだけをwhileループの冒頭でカウントアップすると安全かと思います。たとえば本ページはRPGなので、メインのジャンルはRPGなのでwhileループの序盤ではRPG用のカウンタだけをカウントアップ、という事になるでしょう。シューティングについては、while冒頭ではカウントアップしないか、あるいはRPG用のカウンタの流用で済ますかどのちらかです。
もしwhileループの冒頭でシューティング用のカウンタまで記述してしまうと、コードの管理が複雑になってしまうので、避けたほうが安全でしょう。
普段は使わないミニゲームのカウンタのせいで、普段から使うメインジャンル(本ページではRPG)のカウンタの可読性が下がるのは避けたいです。
RPG用のカウンタをシューティングに流用するのは、シューティング用にコードが最適化されてないので軽量性が若干は下がりアプリが重くなりますが、しかしゲーム制作ツールのRPGツクールやウディタなどで製作されたアクションゲームやシューティングゲームなどは、こういった流用の一種でしょう。
アイテム表示における、上詰めの自動化などを解説しています。
ともかく、ゲーム全体を先に作るのが先決です。ニュアンスは違いますがアトラス社いわく(ゲーム開発では)「ゲーム全体に全体に値を回すのが先」という格言があります。
プレイヤーが見たいのは、ゲーム全体のストーリーやテンポといったゲームの全体像です。カーソルの動きとかウィンドウの動きとかは、あくまで補助的であり、そういったUIに対するプレイヤーの興味も、あくまでオマケの範囲でしかないのです。

世の中には、残念ながら時々、他人の理解しやすさを無視して、やたらと短いコードを書く、独りよがりな人がいます。
しかし、たとえ仕事としての集団作業であっても、要求されるのは、同僚や後輩などが読んだときの分かりやすさです(「可読性」と言います)。
なので、少しぐらいコードが長くなってもいいので、分かり易いコードを書きましょう。
具体的には、できるだけ、どこの入門書にもあるような基本的な機能を使ってコードするのが安全です。具体的には、できるだけ、せいぜい構造体(およびC++ならクラスの構造体的な使い方)や配列や関数あたりまで、の機能どまりです。
また、「どうしても」と言った必要性のない限り、その分野の一般の入門書に書かれてない機能(たとえばメモリ管理の組込み関数など)や、解説の極端に乏しい機能は(入門書なっても巻末の機能一覧にだけしか記載のないような機能)、利用を控えましょう。
そもそも、一般入門書に書かれてない機能は、取扱いが難しかったりして、設定などの確認不足で使うとむしろバグの原因になりやすかったりとか、学習コストの高さなどの難しさがあるから、入門書から除外されているのです。なのに、そういう難解な機能を多用するのは、あまりよくプログラミングの仕事が分かってない自称プロかと思われても仕方ありません。
関数や配列をつくるときは、なるべく、ゲーム用語で説明できる関数および配列だけを作りましょう。たとえば「戦闘コマンド選択関数」や「モンスターデータベース配列」のような感じです。
けっして、そういうゲーム用語とは無関係に、単に抽象的に関数を呼び出す関数を呼び出すような関数を呼び出す関数、とか、配列を読む込む配列を読む込むような配列、のような高階層的な機能は、たとえそれでコードが短くなっても、同僚や後輩などが管理をしづらくなるので、避けましょう。
書籍『Game Programing Patterns』にも、Amazonのweb立ち読みのP13に
とあります。その結果、
と書籍『Game Programing Patterns』にあります。
実際にゲームを作った事がある人ならばこの問題に気づきますが、世間には知ったかぶりで逆の事を言う人がいます。オブジェクト指向だのポインタだの何だの理屈をこねて、抽象化のレイヤを増やそうとする人です。ダマされないようにしましょう。
もちろん、関数から関数を呼び出してもいい場合もあり、たとえば「RPGで戦闘モードの関数から、攻撃コマンド関数を呼び出す関数から、さらに攻撃対象の選択をする関数を記述する」といったようなゲーム仕様に直接的に結びついた関数ならば、普通のゲーマーなら理解できるので、書いても平気でしょう。ですが、それはゲームとしての実態に対応する共通化です。けっして、ゲームの実態に無関係の共通化ではありません。

IT業界だけなく法律業界でも、むやみに高階層的な法令を設計するとその法令の構造が複雑になる現象は知られていますDaniel Martin Katz, Corinna Coupette, Janis Beckedorf & Dirk Hartung "Complex societies and the growth of the law" , nature.com, Published: 30 October 2020 。近年、世界各国でIT的な考え方を使って法律の設計論を研究しようという学問分野があり、その学問でそう指摘されています。これらのIT的な法学では、法律中の単語数、階層数、法律間の相互引用数が多ければ多いほど、その法律の構造は複雑になると考えられています。ご参考に。

また、ゲーム中で、仕様ではあまり類似性のない処理は、たとえ偶然的にコードの実装が似ていても、むやみに共通化して同じ関数にしたり配列にしたりするのは避けましょう。なぜなら他人(後輩など)が管理しづらいからです。
もちろん、共通化してもいい場合もあり、たとえば「回復アイテムによる回復対象を選ぶ関数」などは、
が、ともに仕様が「回復アイテムを選んだ時の使用対象の味方を選ぶ」と似ているので、場合によっては共通化するのも良いかもしれません(職場によるだろう。共通化しないほうが良い場合もある。たとえば戦闘モードでは敵にも回復アイテムを使えるゲームも存在する一方、マップメニュー画面では味方にしか回復アイテムを使えないので細部が異なるから)。
しかし、仕様自体すらも似ていない部分を共通化するのは、ダメでしょう。
たとえば、もしたまたま、「戦闘モードでのコマンド選択時の関数」(まだ道具コマンドを入力する前なので、どのアイテムを使うからすら選んでいない段階)と、「マップメニュー画面モードで道具コマンドのあとに使用対象キャラを選ぶときの関数」が、もし偶然にコードが似ていたとしても、そういう仕様的にあまり関連性の無いコードは共通化されても管理しづらくなるので、共通化するのをやめましょう。
ほかの例では、たとえばHPとMPの表示は「戦闘画面」にも「メニュー画面」にもあるでしょうが、だからといって両画面で使いまわせる「HpMp共通表示関数」みたいなのを作るのは危険です。
具体的になぜ危険かと言うと、その共通表示関数にはif文章が増えますので(戦闘画面とメニュー画面とで表示位置などが微妙に違うため)、デバッグの手間として「どんな場合の戦闘画面とメニュー画面でも、はたして本当にif文が正しく機能しているか」という手間が増えます。
一方、ベタ書きで直接的に戦闘モードにHP表示とMP表示、一方で同様にベタ書きでメニュー画面モードにもHP表示とMP表示を書けば、こういう余計なデバッグの手間は増えません。
HP表示とMP表示のたった2行ていどのコードを「HpMp共通関数」で1行にしても、何箇所かで呼び出すからそのぶん減少量は倍増しますが(たとえば4箇所で呼び出したとすれば 1×4=4で4行ほど減る)、しかし関数を新たに作るので差し引きで、うまく減らせても結局は1~2行くらいしか減らせません。
コード量を簡単なコードの1~2行しか減らせないのにデバッグの手間を大幅に増やし、まったく割に合いません。
また、共通関数の側に呼び出し先の戦闘画面やメニュー画面の情報があるので、共通関数を使ってしまった場合にはデバッグをする際に戦闘画面のコードなども調べなければなりません。こういう事情も加えて、デバッグの手間がさらに増えやすいという問題があります。
教訓として今回の初心者プログラマーにありがちな失敗例を一般化するなら、もし「リファクタリング」のつもりで共通化してif文が増える場合、もしかしたらデバッグの手間が増えてしまっている傾向があるので、上述のような間違った共通化している可能性があります。
wikisource s:プログラマが知るべき97のこと/共有は慎重に にも似たような話題があります。
(引用)
順番は前後しますが、参照先ウィキソースに、下記のようにコンテキスト(文脈)の話があります。
(引用)
高校や大学など学校では、コードの再利用を重要だと教えるかもしれませんし、たしかにそれも重要なのですが、しかしだからといってコンテキストの異なるも のまでむやみに共通化してはいけません。
(引用) ※ そして上述の「たとえシステム内に同様の処理を行う部分が2つあったとしても」に続きます。 この情報を見るかぎり、どうも日本の学校だけでなく海外の学校教育でも、コンテキストの都合を考えずにむやみにコードをライブラリ的に共通化して短縮ばかりを考える教育をされる傾向が2010年頃まではあったようです。
ゲームでは上述の説明では暗黙の前提として何となく戦闘システムやメニューシステムなどの基本システムを想定して説明しましたが、なにも基本システムに限らず(RPGなどの)特殊イベントなどでも同様のことが考えられます。
ゲーム中のストーリー進行に関わる特殊イベントでたまたま似たようなイベントがあったからといって、むやみにシステムを共通化してはいけないのです。もし、仕様変更などの要望が上司などから加わった場合、むやみに共通化してしまっていたら、あとから修正するのが大変になってしまいます。
他の書籍でもそうです。洋ゲー「ゴーストオブツシマ」の開発者の一人による書籍『ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール』( 2023/8/28、Chris Zimmerman (著), 久富木 隆一 (翻訳))でも、著者が新人によくする指導法として「問題の例が三つ集まるまで一般性のある解法を書くことを許さない」というのがあります(amazon見本を参照)。このChrisの会社でも、大学を出たばかりの新人は、新人が1つの問題をみつけると、他の問題も解ける一般的なプログラミングを書こうとするのですが、Chrisは「そういうでかい問題は解かなくていい」と指導して、目の前の問題だけをまず解くことに集中させるように指導しています。そういうでかい問題を解こうとするプログラムは、往々にして、バグを潜みやすかたり、理解のための学習コストが高くなりがちなので、ゲーム開発では避けるべきだということを Chris はこの著書で述べています。 ともかく、目の前に無い、でかい問題を一般化して解こうとすると、メンテ性の悪いプログラムイが出来上がりやすいのです。
予備知識のない新人はこういうミスをしがちです。気をつけましょう。
ソフトウェア工学では「DRY原則」(Don't Repeat Your Self、 「繰り返しを避ける」の意味)という考えかたがあり、同じコードの繰り返しを悪とする考え方がありますが、しかし実務は上記のように、必ずしも「DRY原則」のとおりとは言い切れません。もしくは、世間一般の「DRY原則」の解釈のなかにはコンテキストの考え方を見落とした、まちがった解釈が流布している場合もあるので注意が必要、ということかもしれません。
よほど長いコードの繰り返しやら10回や20回以上とかの繰り返しなら実務上の都合からコードの重複を避けたほうが良い場合や必要もあるかもしれませんが、しかし、そうでない場合でたった数行ていどの少々のコードやらそれらの2回程度の繰り返しならばコンテキストの都合からは似たようなコードをあえて共通化しないほうが安全な場合もあります。
初心者プログラマーはこういった事をいっぺんには体得できないでしょうから、一見すると、本来なら合理的なコードが、初心者の目には少し汚く見え、「少しだけ可読性が悪い」ように感じがちです。つまり、初心者目線で少しだけ可読性が悪いぐらいのコードこそが、実は本当は可読しやすいコードです。

まず、それらの機能の共通点を探します。次に、その共通点を抽象化します。抽象化のコストと、それを再テストするコストの合計が、そのままにしておくコストよりも高く付くと考えられるならば、抽象化は後回しにしても構いません。
戦闘モードとか、マップ画面モードとか、メニューモードとか、そういうののハナシです。とりあえず「モード」と言いましたが、ゲーム業界で何と言うのか知りません。もしかしたら、モードではなく「戦闘シーン」とか「戦闘パート」とか言うのかもしれません。ただし、書籍『ゲームプランとデザインの教科書』が、架空のスマホゲーム企画書で「モード」という言葉を使っています。「移動先指定モード」とか。


方針だけ述べる。具体的なコードは、上手い人のコードを参考にしよう(コードがけっこう長くなり、紹介がメンドウくさい)。
2Dマップがあると、俄然、RPGっぽく見えるようになって、ヤル気が出るので、さあ作ろう。
マップのデータは、ふつう、2次元配列で書く。
まず、グローバル領域で、たとえば
のように、とりあえず配列を確保しよう。

ここで重要なのは、 確保した配列のタテとヨコは、ヨコの並びをx方向として、タテの並びをy方向としたとき、
maptable[y][x]
のように確保されていることに注意する。
さて、各配列に「0」を入れても、はたして0番が何を意味するか、まだ何も決めていない。
ゲームにもよるが、とりあえず、何もマップチップを上書きしない領域だと定義しよう。
背景色と同じ色のベタ塗りのマップチップを作っておけば、それで上書きすれば、あたかも何も上書きしてないように見える。
いちいちif文などで、何も上書きしないように場合わけをするのもメンドウであるので、どっちの方式にするか、決めておこう。

さて、マップ用の配列は、作成したいマップで最低限必要なマス目よりも、やや大きめの領域を確保しておく必要がある。
たとえば、5×5のマップを作りたいなら、配列ではもっと大目に、たとえば 8×7 とか確保しておく必要がある。
もし、なんらかのバグで確保されていない領域を呼び出してしまうと、プログラムがエラーで異常停止してしまう。

たとえば、一番左端をもしx=0とした場合、もしこの場所に主人公がいると、さらにプレイヤーが「左端に行こう」と考えて、左ボタンを押したときに、エラーで異常停止してしまう。
こういう停止はメンドウくさいので、だったら念のため、最初から、マップを移動可能な場所よりも何マスか大目に確保しておくと安全である。
さて、まだ配列を確保しただけなので、「0」が何かとか、「1」が何かとか、まったく定義していない。
とりあえず、
としよう。 だと思ってればイイ。
たとえば、もし配列 maptable の宣言が、
のような宣言だったら、このマップでは真ん中のほうに4マス×5マスの移動可能な地帯がある。 その周囲は移動不可能になっている。
ともかく、このように、プログラマーは、まず、何番のマップチップが何を現すかということを、脳内で設計しておく必要がある。

配列の範囲外の読み込みエラー防止のためも兼ねて、0番は、すべてのゲームキャラが進入禁止としておくのは安全だろう。
あとはもう、win32 API などの機能を使って、マップチップの画像を配列にもとづいて各マスごとに表示すればいい。

前提として、まずマップチップ画像の読み込みを行う必要がある。あるいは、画像をあらかじめ実行ファイルに組み込んでおく必要がある。
画像の実行ファイルへの組み込みは、Visual C++ にそういう機能があるので、それを使えばいい。
画像を読み込みたいなら、ゲーム起動時にでも読み込んでおけばいい。

イメージ的にコードの雰囲気(ふんいき)を書くと、たとえば case WM_PAINT: の節に、下記のように for文などを使って画像ハンドらに画像を代入するコードを裏画面に書いていき、最後にまとめて本画面に描画することになる。(「裏画面」とか「ダブルバッファリング」と言われるテクニックを使います。詳しくはネット検索して調べてください。)


SelectObject や BitBlt は、Win32 API の専用の関数なので、分からなければ読者で調べてください。
なお、マップチップ画像そのものの作成は、単にWindowsアクセサリ『ペイント』などの画像作成アプリでビットマップ画像を用意すればいい。
ツクールやウディタなどだと、いくつかのマップチップをまとめた「タイルセット」などを取り扱うが、実はプログラミング的には、わざわざタイルセットを作らなくても、マップチップ1個ずつを読みとりすることも可能である(単にwin32APIのビットマップ画像の読みとりの機能を使えばいい)。
(win32 API の初期設定のままではビットマップしか表示できないハズ。PNGなどを使いたいなら、GDI+の設定を行うこと。GDI+については説明を省略。)。
なお、マップチップのサイズの規格は、よくある規格は16ピクセルの倍数で、「px」をピクセル単位の意味として16px×16pxまたは32px×32pxまたは64px×64pxのマップチップ規格がよくある(ツクールやウディタのマップチップのサイズ規格も、この系統)。
とりあえず、私たちにとって作るのがラクなのは、小さいほうが作成がラクなので、とりあえず16×16のマップチップを作ろう。

プログラム技術としてはマップ表示は単なる二次元配列なので難しいことは無い。しかし、その他の準備が忙しく、たとえばマップチップ用のビットマップを用意したりとか、あるいはキーボード操作のプログラムを作ったりとか、そういう準備が難しい。
これだけだと、まだマップを表示しただけなので、さらに主人公キャラのキャラチップとか、主人公がx=何マス目、y=何マス目にいるかの変数とかも宣言する必要がある。
主人公チップを移動させる際、ドラクエ1みたいに1ピクセルずつ動かしたいと思うだろうが(実際は何ピクセルかしらないが)、しかしそれは難しい。まずは、十字ボタンを押したら、その方向にいきなり隣のマスに動く仕組みをつくろう。
しかし、これすら、また難しい。
win32APIなら、ボタンを押して話す動作で1回の入力と判断してくれる。 なので、win32APIで隣マス移動の仕組みを作るのは、比較的にラクである。
しかしDXライブラリの場合、1瞬だけボタンを押しただけでも、何十回も入力があると判断され、 いっきに壁際のマスまで動いてしまう。
なのでDXライブラリのマップ移動の作成の場合、まずはタイマー系の関数を利用し、一定時間のボタンの押し続けがあって初めて「入力された」と判定すうプログラムが追加になる。
なお、win32APIでも別のシーン(たとえば戦闘モードでのコマンド決定後の自動処理など)でタイマー自作が必要になるので、どちらにせよラクではない。
最終的には、21世紀的な一般的なゲームを作りたいなら、(win32APIではなく)DXライブラリで作るのがラクである。 (ただし本セクションでは説明のしやすさの都合から、win32APIで説明した。)
もし、ドラクエ風に1ピクセル(ないし数ピクセル)ずつアニメーション的に動かしたいなら、DXライブラリがほぼ必須であり(原理的にはwindowsAPIでも出来るが、しかしwindowAPIでのアニメーション表現はとても手間が多く難しく、強く薦めない。)、DXライブラリで開発しているRPGコードに、タイマー計算するコードと組み合わせて、下記イメージのようになる。
// nyuuryokumati は「入力待ち」時間の意味
上記コードの仕組みは割とひどく、マップ移動中の特定の左右方向用のタイマーを、今後の戦闘モードなど他のすべてのタイマーと流用するという、ひどいコードである。
ナナメ移動にも対応したりを考える場合、左右(LR)方向と上下(UpDown)方向のキーボード入力を別々の変数として処理する必要があったりと、割と面倒くさい。
移動先が移動可能でないカベや川なのに移動できたらおかしいので(ドラクエだと川は移動不能。『信長の野望』での渡河とか野暮にツッコまないこと。)、
事前にそういう移動可能判定を色々とクリアしたら、移動中モードとしてmovingが1になるようにしているコードである(長くなるので上記コードでは省略した)。
キーボード入力の判定は、事前のmoving側の判定計算ですでに行っているので、上記コードでは省かれている。実際にはさらに、下記コードのようなキーボード入力判定プログラムが、上記コードの直前あたりに付け足される必要がある。
いったん移動し終わったら、もはや移動中ではないので、再度movingをゼロに戻し、また移動可能判定を調べなおす、という手間になる。
マップ移動だけでも、こんな手間になる。
だから、市販の『中学生でも分かるゲームプログラミング』的な題名の本でこういう手間が無いのは、 それはその市販本の著者が、初心者が苦手感を抱かないように独自のライブラリなどで上記のような手間をライブラリ側に隠蔽する工夫などをしてるだけにすぎない。
ネットに出回るデマの、「RPG風のUIをつくるのは簡単」というのは、つくづくウソである。ドラクエ1風のUIですら、なかなか面倒である。 (『中学生でも分かるゲームプログラミング』的な本の手間だけでドラクエ1風UIが作れると思ってる、本を読んだだけの知ったかぶりが、ゲームプログラミング経験者ヅラしているということであろう。)

ゲームにおけるキャラチップの歩行アニメーションの作画の定石は、テレビアニメの歩行の作画の定石とは、まったく違います。
説明の単純化のため、右向きの歩行を例に説明します。
まず、ツクール水準の2D-RPGの歩行グラフィックではなんと、歩き始めの作画の立ちポーズのドット絵と、横向き時にプレイヤーから見てキャラ歩行中における右足と左足とが重なっているドット絵(便宜上「中ポーズ」と呼ぶとする)が、なんと同じドット絵です(テレビアニメ作画の常識とは大きく異なる)。
つまり2Dゲームのドット絵では、歩き始めと歩き中の中ポースとに、区別がないのです。
これは、実際にキャラチップのタイルと、キャラのゲーム中での歩行動画を録画して見比べると分かります。

テレビアニメ産業では、歩きお よび 走りの作画は、基本的になるべく滑らかに見せるために、6枚の絵を使います。 だからアニメ業界では「6枚歩き」とか「6枚走り」とか言います。
しかしゲームは違います。上記の言い方に習うなら、ゲームは「3枚歩き」です。「3枚歩き」というのは別にゲーム業界の用語ではなく、テレビアニメ業界での数え方をそのままゲーム業界に置き換えただけの本wikiでの独自的な呼び方です。
しかもゲームのドット絵では、走りと歩きの区別がありません。つまり、歩きのドット絵を、走りのドット絵でも使いまわします。
つまりゲームではドット絵だけなら 「3枚歩き」=「3枚走り」 でもあります。
ドット絵のゲームにおける走りと歩きの区別は単に、キャラチップのスライドさせる早さを切り替えることで区別しているだけです。
なお、テレビアニメ産業などでは、正面向きかつ走りシーン(ゲームにおける下キー入力時に相当)なら例外的に(6枚ではなく)4枚作画でも走りを描けることが知られています。なぜこれが通用するかというと、よく分析で言われるのは、6枚でなく4枚だと滑らかさはなくなりますが、しかし歩きではなく走りであるので動きに少々のギャップがあっても勢いがむしろ強調されるという点と、また6枚時の中ポーズのシルエットと4枚時の中ポーズノシルエットがあまり変わらないという点があるため、テレビアニメ業界では正面走りだけ「4枚走り」でも可能なのです。
しかしゲーム産業では正面向きでないのに、右向き左向き前向き後ろ向きすべてで、なんと「3枚歩き走り」なのです。ドット絵のゲームではキャラチップが小さいので、なんと3枚で歩きも走りも表現できてしまうのです。
このように、ゲームとアニメとでアニメーションの常識が大幅に異なります。
しかし、両業界でも一致している作画の風習もあり、それは歩行中グラでの頭の高さの上下運動です。
アニメ作画の頭の上下運動を文字だけで説明するのは難しいので、興味ある読者は外部サイトでアニメーターの作画教育サイトを見るなり、あるいは同人フリーゲーム用の公開キャラチップ素材などを実際に目で見るなどして、読者ご自身で研究してください。
ともかく、3枚で右向きの歩行を表現できます。RPGでは上下左右の4方向が必要なので、最低でも3×4 = 12枚 の絵画必要です。
なお、斜め歩行が加わると、2倍になるので必要枚数は合計24枚になります。
もし、外部のゲーム用フリードット素材を使わずに「ゲームエンジンを一人で作る」というなら、上述のようなアニメ産業とゲーム産業での作画のギャップも知って絵を描く必要が生じるでしょう。頭の切り替えが必要になります。
今までプログラマー脳だったのを、ドット絵を描くのに絵描き脳に切り替える必要があって、しかも既存のテレビアニメ作画理論はそのままでは使えないので、ゲーム用に人気作のドット絵のグラフィックを研究しなおす必要が生じるのです。

また、絵1枚ごとのRPGのキャラチップの作画も、テレビアニメとは違います。
まず、2D-RPGでは、前後向きのキャラチップの横幅のサイズ規格と、左右向きの横幅のサイズ規格が、RPGでは同じです。
しかし、テレビアニメでは、このような横幅はありえないのです。
なぜなら、人間が歩いていて左右の腕をふっていて前に突き出た状態の手先から胴体までの距離は、胴体の厚さに比べると、(手~胴体 の距離は)かなり長いです。
しかし、こういったリアルな腕の寸法に忠実に書くと、サイズ規格の横幅をオーバーしてしまい、少なくとも腕の片方の先がチップ外にハミ出てしまいます。
だから、進行方向側の腕だけは、2D-RPGキャラチップではあまり伸びていないです。
なお、進行中の胴体はやや進行方向に寄っています。これはリアルな人体がそうだからでしょう。
なので、もはや進行方向側の腕には、伸ばすだけの余裕がありません。
だから、進行方向側の腕を折り曲げる場合すらも存在します。または、進行方向側の腕だけ短くゴマかすなどしている場合もあります。
これは別に2010年以降の流行でなく、既に1980年代の商業ゲームでもファミコンのドラクエ3の勇者の母親のキャラチップも、実は進行方側に腕を伸ばしたときは、腕を折り曲げています。
なお、ドラクエ3の主人公である勇者は、剣を持っているので、利き腕の右手がもとから折り曲がっており、よく分かりません。
また利き腕の表現のためドラクエ3では、右向きと左向きのキャラチップを、けっして反転処理でゴマかさずに、きちんとポーズを書き分けています。
ともかく、一般にRPGの歩行キャラチップでは、進行方向の腕があまり伸びてないので、バランスを取るためにRPGでは、進行方向の反対側の手足を、目いっぱい、伸ばしています。
これはリアルで考えるとありえないし、テレビアニメでもありえない作画です。
ですが、ゲーム産業の2D-RPGでは、昔からこういう作画がよく行われています。

2D-RPGの歩行ではキャラは地面を滑ります。横向きグラフィックだと、比較的に確認しやすいでしょう。
テレビアニメだと、キャラが滑っているように見えなくさせるためもあってか6枚も使って作画する一方、
2Dゲームでは正反対であり、2D-RPGゲームでは「滑り上等!」な態度の作画です。
走りシーンだったら、「まるで滑っている」かのように高速で走っている身軽なキャラのようにも見えるのですが(実は、実際に足の作画が滑っているだけ)、
2D-RPGでは歩きですら滑りある作画です。
「3枚歩き」で描く以上、こういうリアリティを無視した作画ですので、あまり他のリアリティにこだわっても仕方ありません。

標準的なキャラチップの前側の腕は折りたたまれています。原理的には、キャラチップの横幅を長くすれば、横向き歩きのゲーム作画において、リアルの作画や、テレビアニメの作画に近づけることはできます。
ですがそれをすると、キャラチップがそのぶん大きくなってしまい、そのせいでチップタイルの横幅が大きくなってしまいます。
正確には計算していませんが、少なくとも2.5倍くらいは横幅が長くなると思います。斜め移動も含みで考えると、通常のツクールなどのチップタイルはやや横長なのに、さらにそれを2.5倍に長くするのは、やや編集時に見づらいかもしれません。
ドット絵のキャラチップという小さくて見づらい絵の、さらに「腕」という2ドット(枠線まで含めると4ドット)くらいしかない部分に対して、そこまでする必要あるのか、意義が不明です。
このように、ゲーム演出の特有の事情もあります。

また、もしキャラチップの横幅の規格だけ長くすると、マップチップの横幅の規格と、食い違いが出てきます。このため、プログラムがやや難しくなります。
なるべくキャラチップ横幅とマップチップ横幅の規格の長さが近いほうが、プログラムは楽になります。
このように、プログラミング側の事情もあります。
それでも、どうしても腕の振りをリアルやテレビアニメに近づけたいなら、
キャラチップのサイズ規格を変えるのではなく、キャラチップのサイズ規格はマップチップ規格と同じくらいの長さにしたままにして、
歩行時にキャラチップを3枚横につなげるなどの方法もあるかもしれません。3枚の真ん中のチップが胴体と腕の付け根側で、隣の左右チップがそれぞれの腕の先端側に対応、という手法です。おそらくですが、ファミコン時代の古いアクションゲームでも、巨大ボスなどを、複数のチップをつなげて作画していたでしょうから、そういうのを現代的に応用する手法というわけです。
ただし、これだとキャラの処理速度の負担も、単純計算で3倍になります。(実際は、左右のキャラチップは無描画の場合もあるし、描画量が少ないので、もっと少ないが。)
主人公とかボス敵だけのキャラチップなら、グラフィック重視のゲームなら、その意義もあるかもしれません。しかし、果たしてモブキャラのキャラチップにまで、そこまでのチップ3倍にする手間を掛ける価値があるかどうか。
また、製作ツールなどの事情により、読み込みできる画像の枚数に制限のある場合があるので、あまり目立たない部分のために画像を1枚増やすのは非効率です。
ですが、べつに全キャラに6枚歩きを実装する必要もありません。お好きなように。

どうしてもドット絵で手足の動きをリアリティある書き方で細かく表現したいなら、いっそ、ゲーム本編ではなく別途ゲーム中にミニゲームでリアルな腕の振り方のあるミニゲームを組み込むなどの方法のほうが、良いかもしれません。
この方法なら、たとえばもし2D対戦アクションゲーム(スト2みたいなの)のミニゲームを組み込んだら、歩きや走りだけでなく、ジャンプだろうが座りだろうが、もはやパンチやキックや剣撃なども思う存分に大きく作画できますし、作画によってゲーム性も向上します。(アクションゲーム特有の非リアル描写もあるだろうが、本ページはRPGの教科書なので、アクションゲームの非リアル描写には深入りしない。)
背景を手書き背景イラストにすれば、マップチップのサイズ規格に縛られる必要もなくなるので、思う存分にキャラの好きな大きさで作画できますので、腕などの細かい部分も目立つ大きさで作画できるでしょう。
ただし、この方法の背景だと、スーパーマリオのような、背景の空中ブロックの上に、キャラがジャンプして飛び移ったりとかの処理は、スト2的ゲームのままでは不可能です。別途、マリオ的システムのプログラムを組む必要があります。つまり「スト2のようなスーパーマリオ」というゲーム企画を実装する必要が生じてしまいます。
また、ツクール的システムのRPGでなければ「3枚歩き」に縛られず、歩きと走りの作画を分離するのも自由ですし、「6枚走り」と「6枚歩き」のシステムにすることで「滑り」も無くせてリアリティ向上します。そこまで作画する意欲があればの話ですが。
歩行グラフィックの切り替えパターンはゲームごとに違うのですが、下記コラムでは実装のラクなパターンを紹介します。
なお、ツクールやウディタの歩行パターンとは異なります(ツクールなどは、もっと複雑なパターン。後述する)。
実はツクールやウディタなどの歩行アルゴリズムは、本ページの上記コラムのプログラムのようにはなっていません。

なお、ツクーツとウディタで、キャラの標準的な歩き方のアルゴリズムは両方とも、
のように、直立ポーズを挟んで、前足あげと後ろ足あげを交互に繰り返す方式です。(最初に始まるのが前足か後ろ足かの若干の違いはあるかもしれませんが、本質的ではないので深入りしない。)
けっして、
のようにはなりません。
これはおそらく、直立のように見えるグラフィックが、実は歩行中の前足と後ろ足とが重なった状態を兼ねている表現だろうと思われます。
そのほか、ツクールやウディタで1マスだけ進むのを繰り返すと分かりますが、
1マスしか動かないで停止したとき、キャラチップをよく見ると、その場で足踏みして最終的に直立して止まることがあります。
ツクールもウディタもソース非公開なので不明ですが、これはプログラム的には仕組みはおそらく、
移動中の間だけ「移動中カウンタ」的な変数が進み、それが一定値になると0に戻るという仕組みを繰り返していると思います。
そして隣マスに到着時の進行判定の際、もし右ボタンが押されていなくてマスに停止しており、
移動中カウンタがまだ0に戻る前の値だったら、その値を保存したまま、
表示プログラム用にカウンタ値だけカウントアップしていって0に戻るまで表示が進むような仕組みで、実装できるかと思われます。
もし読者がツクールやウディタっぽい歩行アルゴリスムを実装したいなら、ご自身で研究してください。どのみち、ツクールとウディタで、歩行のポーズ切り替えタイミングなど微妙に違いますので、統一されていません。
どのみち、たとえばファミコン版ドラクエ3のアルゴリズムは、ツクールやウディタとも違います。ドラクエ3ではマップ上でマスに立ち止まっても、キャラチップは静止せずに足踏みを続けます。
このように歩行パターンはゲームそれぞれです。


おおむね、こういった作画の流れになるでしょう。もちろん個人差はあるでしょう。ですが、けっして「いきなり細部から描く」ことはしないのは、ほぼ確定でしょうし、線画はドットが潰れるので輪郭以外の線は描かないことも、ほぼ確定でしょう。
あくまで、2D-RPGのキャラチップの 40px × 40px 程度のドット絵だけに限定した話です。なので、反論などで顔グラフィックなどキャラチップ以外の話題を出されても、ピント外れです(相手が言ってもいないことで反論することを「w:藁人形論法」(わらにんぎょう ろんぽう)と言います)。ましてやRPG以外のアクションゲームなどのドット絵の手法で反論しないでください。
さて、いくつかフリー素材を調べたところ、横向き時の中ポーズの足は、1本しか見えません。
ついつい歩行中の中ポーズも意識して足を微妙にズラして2本書きたくなりますが、しかし静止ポーズにも使うことと、ドット絵なので微妙な足の段差を表現しづらいことなどから、
決断して横向き時の足は1本しか見えないほうにするのが効率的でしょう。
どうしても中ポーズでも足2本を見えるようにしたい場合の裏ワザとして、2本の足が合体した太い1本足を描くというワザがあります。やや太めの1本足です。 一部のフリーゲーム素材がこういうワザを使ってドット絵を描いています。
ドット絵なんてこんなもんのゴマカシの連発ですから、あまり下調べの段階なのに細部を調べても仕方ありません。さっさと書き始めてから、書いてる途中に気になった点から手本を見直して調べていけばいいのです。いろいろと調べるの必要になりますが、さっさと書き始めるのも重要です。こういうのは、調べていたらキリがありません。
デッサンのコツなんて、細部を書き始める時点までに、把握できていればいいのいです。
仕事でなければ、イラストなんて最終的には描いた自分で満足できればいいのです。プログラマー視点で見るにしても、歩行プログラムの検証をできる最低限のイラストさえ書ければいいのです。
当ページはプログラミングの教科書ですので、まず先にプログラム検証のための最低限イラストを描くことになります。
とりあえずバブルソートの話題など。ほか幾つか。
さて、戦闘中のモンスター隊列の構成を定義するための配列(または同等の内容の数列)も、必要です。
まず、画面に敵を、表示したい順に表示するためも必要です。
また、上述の「素早さ順」での行動処理のためにも、前提として、敵パーティの構成を表すための配列が必要になります。
説明の単純化のため、敵は横一列に、左から右に、並んでいるとしましょう(ドラクエ2~3みたいな方式だとしましょう)。

たとえば敵が左から順に
出現したとしましょう。(説明の単純化のため、モンスターは各種類ごとに1体だけとする。)
そして、ホブゴブリンのモンスター用データベース中でのIDが13番だとして、 毒々スライムのIDが8番、 ゾンビ兵士のIDが25番、 だとしましょう。
すると、この敵パーティを表すための配列として、
のような配列が必要です。(もしくは、配列に格納できるような数値の列「13,8,25,-99」)
末尾の-99は、これはその配列の読み終わりとして使用するための数字です。この数字は、別に「-10」でも「-99」でもいいですが、モンスターのidとけっして重ならないようにする必要があります。
通常、なんらかのデータベースのidの値は0以上の正の整数ですので、マイナスの整数を「終了」の意味で使用しておけば、安全でしょう。

このように、敵側にも、配列が必要になります。
しかも、この敵側の配列は、そのゲーム中で出現する敵パーティの全パターンを用意する必要があります。

たとい1体だけしか出現しない敵でも(たとえばボス敵や強敵)、その1体分の敵パーティの配列が必要です。
たとえば、その1体だけで出現する、あるボス敵「暗黒大王」のモンスター用データベース中でのIDが205番だとしたら、
のような、敵1体だけの配列を用意する必要があります。

なお、もしマイナスの数を含む数をふくめて並べ替えをしたいのでしたら、 上記の「-99」など終了処理を負数で区別する方法は、そのままでは使えないです。
たとえば、方向でもし東向きをプラス、西向きをマイナスとした場合、終了コードのつもりの「-99」は、誤解で「西に99マス」などと誤解される恐れがあります。
たとえば、
の並べ替えをしたい場合を考えましょう。
解決策としては、いろいろあります。
一番ラクな方法は、要素数を新たな変数として追加し、それと組み合わせて配列を使うことでしょう。
たとえば、
は7個の数が並んでいるので、
youso = 7;
みたいに新たに変数を用意します。
そして、たとえば最初の「-3」から順番意読み取りの際に、数えおわった個数を+1していき、+7になったら読み取りを終了することです。
この方法は、拡張性が高いのでオススメですが、ただし、要素を書く前に個数を宣言する必要があります。
実際の配列データは
のようになっているので、けっして数え終わって欲しいところでキリよく要素が終わるわけではないので、なので、要素数をあらかじめ宣言する必要があるのです。
さもないと、8番目の「0」が、読み取りたい数値としてゼロなのか、それとも、単にデータなしのためゼロなのか、不明になります。
終了コードなどとして負数を使用するのは、マイナスを含む並べ替えでは、あきらめましょう。それが安全でしょう。

最初の解決策1(要素数を新たな変数として追加)がもっとも安全かつ簡単ですが、比較のため、別の解決策も紹介しておきます。
次の解決策2は、数学的にはエレガントですが、しかしプログラミング的には、煩雑になり、また、バグ時などのエラーの波及をしやすい欠点があります。
さて、並べ替えのもうひとつの解決策として、
一例は、符号と絶対値を分離して、その組み合わせとして処理することです。
たとえば、
の並べ替えをしたい場合、
プレイヤーからは表面的には「-6」は1つの数に見えまずが、これをあえて、「フラグhugouが状態2(マイナスに相当)である」「絶対値 zetai が6である」というように、2つの変数hugou と zetaiに分けます
符号がプラスなら、hugou = 1 にでもしておきましょう。また、ゼロは便宜上、hugou = 1 にしておきましょう。
すると、上記の数の並びは、(hugou, zetai)のベクトルで考えると、
という組み合わせに変換するので、マイナスが使われない形になります。
なので、終了処理に、「-99」などの負数を割り当てても、並べ替え対象の数値と重なる心配がなくなります。: (2, 6,) , (2, 3) , (2, 2) , (1,0) , (1,1) ,(1,2), (1,5)
などのように、終了コード「(-99,0)」を末尾に追加しても、なんの混同の心配もなくなります。
さて、いったん上記のように、数を、符号と絶対値の組み合わせに分解して、同じ符号どうしで並びかえたなら、
あとは、符号が同じものどうしで、並べ替えをするだけですみます。
たとえば、
の並べ替えをしたい場合、ベクトルの第一引数に注目し、※ (第一引数、第二引数)
まず、
に分けます。
そして、絶対値(例では第二引数)だけに注目すれば、
となるので、簡単に並べ替えできます。
あとは、これを合成し、
と、並べ替えできます。

なお、説明の都合上でベクトルを蒸気の解説で使ったが、しかしC言語にベクトルの機能は無いので、もし上記の機能を実装するなら配列や構造体配列を使って、ベクトルと似たような処理を実装することになる。
たとえば配列で実装するなら、符号用の配列 hugou[id] と、絶対値用の配列 zetai[id] のようなものを用意したりすることになるだろう。
もし1番目の最初の数が「-3」なら、符号フラグは2、絶対値は3だからベクトル表現では
であるが、これは配列で表現するなら、たとえば
のように記述できる(C言語では配列の番号は0から数える)。

この方法は、一見すると数学的にエレガントに見えるかもしれませんが、しかし、もしバグやタイプミスなどによって数え間違えると、数え落としや重複があると、以降の符号が1個ずつズレてしまうなどの大きな影響があります。
たとえば、説明のため上記では
の分解を
とマトメて書きましたが、 実際には
のように別々の変数に分かれて保管されるのです。
もし、たとえば hugou の最初に、バグなどで「1」が加わると、
のようになってしまい、すべての符号が1個分、ズレてしまい、
となってしまいます。
正しい元々の数字の並びの
と比べると、符号がいくつも間違っており(1個目と2個目と4個目が違う)、解決策2ではエラーの波及が大きいことが分かります。