チュートリアルシナリオを開く
まず、"Tutorial" ディレクトリにある "Tutorial.qk2" を開いてみてください。"Tutorial" ディレクトリには、簡単な RPG を作るための最低限の素材が用意されています。開きましたか?では、次にマップブラウザを開いてください。"Field.qm"、"House.qm"、"Town.qm" という簡単な 3 つのマップがあらかじめ用意されています。それぞれのマップに Field、House、Town というマップ関数が関連付けられています。マップ関数については前述していますが、要するにそのマップにおけるゲームの動作を定義するための関数です。これらの関数をスクリプトに記述することで、ゲームが動作します。
初期マップの設定
まず、ニューゲームを開始した直後に読み込まれる最初のマップを設定しなければなりません。"House.qm" を最初のマップとすることにしましょう。一般設定の「初期マップ」に "House.qm" と入力してください (ダブルクォート " " は不要です)。これで、最初に "House.qm" が読み込まれるようになりました。次に、このマップに関連付けるマップ関数 House を定義します。スクリプトブラウザから "Main.qc" を開き、次のスクリプトを入力します。
最初のマップ関数
localsave int g_Init = 0; // 主人公作成フラグ /* * 家のマップ関数 */ mapfunc House(){ // 主人公を作成 (初回のみ) if(!g_Init){ void *ruki = CreateChara(1, 3); // キャラ作成 RegisterChara(1, ruki); // キャラ登録 SetCharaGroup(ruki, 1); // 所属勢力の設定 SetCurrentChara(ruki); // 操作対象に設定 SetTransit(3, 3, 0, 3); // 初めに置く場所を設定 g_Init = 1; // フラグを立てる } // 毎回のロード処理 PutPlayer(); // 主人公を置く PlayMusic("House.mid", 1); // BGM 再生 TransitMap(-1, 10); // 画面切り替え // メインループ while(1){ // 無限ループ PeekAllMessage(); // 必ず必要 NormalProcess(1); // RPG 処理 } }
最初にやること
ニューゲームが始まったら最初にやらなければならないことは、主人公のキャラクターを作成することです。とりあえずプレイヤーが操作できるキャラクターがいなければ、いきなりゲームオーバーになります。しかし、主人公を作成するのはニューゲームが開始された最初の 1 回だけなので、主人公を作成した、というフラグ (変数) を用意する必要があります。最初の行の g_Init というグローバル変数がこのフラグにあたります。g_Init という変数は localsave 記憶クラスなので、セーブデータにこの変数の内容が保存されます。'g_' というのはグローバル変数であることをわかりやすくするためのものですが、特にこうしなければならないという決まりはありません。次にマップ関数 House です。関数の初めで、g_Init にフラグが立っている (0 以外の値が代入されている) かどうか調べ、フラグが立っていなければ主人公を作成します。キャラ作成→キャラ登録→勢力設定→操作対象に設定、という順序になります。名前や顔グラフィックも必要なら設定します。パーティーに所属させたい場合はここでパーティーの作成と設定を行ってもかまいません。また、作成したキャラクターをマップ上に配置するときの座標を SetTransit 関数で設定することも忘れてはなりません。最後に「主人公を作成した」というフラグを g_Init に立てて、主人公作成処理は完了です。
ロード処理
どのマップ関数でも、そのマップが読み込まれたときに最初にしなければならない作業がいくつかあります。Queek I で言うところのトッププロセスですね。この場合は、主人公の配置、BGM 再生、画面切り替え、という 3 つの処理を行っています。特に、PutPlayer 関数でプレイヤーのパーティー (キャラクター) を配置する作業は必ず必要です。PutPlayer 関数でキャラクターを配置する座標は、普通は移動前のマップで SetTransit 関数により行っておきますが、最初に主人公を作成したときにもこの設定を行います。敵が出現するようなマップでは、ここで敵の作成処理を行います。また、NPC (プレイヤー以外のキャラクタ;町人など) の作成などもここで行います。
メインループ
最後に、毎フレームの処理を定義するメインループを書きます。これは、イベントによる自動制御のみのマップ以外では常に必要です。メインループは、普通 while(1){ のような無限ループ (break もしくは return するまで繰り返す) によって記述します。メインループに最低限必要な処理は PeekAllMessage 関数と NormalProcess 関数の呼び出しです。NPC との会話や、オブジェクトに対するコマンド処理などはメインループ中で行います。
実行してみる
それでは、スクリプトをコンパイルして実行してみてください。キャラクターが家の中に表示され、歩き回ることができれば今回のプログラムは完成です。まだ何も他の処理を行っていないので、外へ出たり箱を開けたりはできませんね。次のレッスンでは箱を開けてアイテムを取り出すコマンド処理を作ってみます。