前のページ | 次のページ

title image

ホーム | トップ | 掲示板 | FAQ | 検索 | サイト情報 | リンク

+ ホーム > トップ > ゲーム制作講座 > メッセージの表示

メッセージを表示しよう

RPGやアドベンチャーゲームでは、メッセージの表示を一文字ずつおこなうことが多いですよね。
今回はこの表示効果を出す方法を解説します。

全角文字と半角文字について
 まず、忘れてはならないのが一文字というのが必ず同じ大きさのデータではないという点です。
 MS-DOS、Windows95などで使用されているシフトJISコードでは、1バイトで表される半角文字と、2バイト使用する全角文字の2種類の文字が混在しています。これを正しく判別しないと表示内容がおかしくなってしまいます。
 C++Builderでは、AnsiStringクラスを使って文字列の保持を行います。AnsiStringクラスでは、ByteTypeメソッドを使って特定の位置の文字の種類を判別できます。

プロポーショナルフォント
 Windowsのフォントには、固定ピッチのフォントと可変ピッチのフォントがあります。後者はプロポーショナルフォントと呼ばれるもので、一文字一文字の横幅が違っています。
 MS-DOS時代には固定ピッチのフォントしか使えなかったため、メッセージを表示する範囲の横幅が決まればそこに表示できる文字数は必ず一定だったのですが、プロポーショナルフォントを使うとなるとそうはいきません。決められた横幅に合うように文字数を決定するには多少工夫が必要です。

単に表示するだけなら
 一文字ずつ表示するのでなく、全体を一括して表示するなら話は簡単です。
 Windows APIのDrawText関数を使えば指定した範囲に入るようにテキストを整形し、表示してくれます。
 しかし、多くのゲームのように一文字ずつ表示するようなことはできません。


考えてみると結構面倒ですね。
というわけで、面倒そうな処理をクラスにまとめてみました。
もっとも、実際にはゲーム制作ツール「コミックメーカー for Win95」から抜粋したコードが元になっているんですが…

それでは、こちらからダウンロードしてください。


使用方法は、ダウンロードしたファイル内のドキュメントを読めば分かると思いますので、ここではクラスの動作内容を含めた改造、改良方法について解説していきます。
ただ、まともに全部説明するくらいならソースコードを自分で読む方が速いくらいではないかと思いますので、大雑把な動作内容と制御コマンドの追加方法に絞りました。

クラスの動作説明・改造方法
 TMessageOutクラスを理解する上で最も重要なことは、このクラスが簡易的なスクリプトシステムとして動作していることです。
 MessageOut関数は、まず表示するテキストに埋め込まれたコマンドを解析し、原始的なスクリプトコードに変換。続いて、生成したスクリプトコードを実行し、実際の表示効果を現します。

 スクリプトコードは、TMsgOutData構造体を利用したポインタリストとして生成されます。
 実際にスクリプトを作成するのはMsgOut_MakeCmdList関数です。この関数ではMsgCmdCtrl関数を呼び出して制御コマンドを実行させながら文字の配置を決定します。

 制御コマンドの追加時には、コマンドコード変換を行うMsgCmdSet関数と、実行を行うMsgCmdCtrl関数の2つを書き換えれば実現できるのですが、前述の理由によりMsgCmdCtrl関数の書き換え時には配置計算中の関数呼び出しに対し、フォント属性の変更以外の処理をしないように注意しなければなりません。
 初期状態で用意されている簡易スクリプトコマンドのうち影響のあるコマンドは、
 MSGOUT_CMD_MSGOUT (実行されると画面にゴミがでる)
 MSGOUT_CMD_KEYWAIT (解析中にキー入力が必要になる)
 MSGOUT_CMD_WAITTIME (解析速度が大幅に低下)
 MSGOUT_CMD_WAITTIMEAUTO (解析速度が大幅に低下)
 MSGOUT_CMD_SCROLL (メモリ保護違反がでる可能性がある)
以上のコマンドで、コマンド解析中に実行されることを禁止しています。括弧の中はもし実行された場合どういった影響が出るかの参考としてください。
 これらのようなコマンドを新たに追加した場合、MsgCmdCtrlに引数として与えられているAllCtrlがtrueのときだけ処理を行うようにプログラムしてください。

 また、属性制御コードを書くときには、ScrollFlagの存在にも注意する必要があります。
 ScrollFlagは、メッセージの表示方法にEFF_LINE_SCROLL、またはEFF_CHAR_SCROLLが指定されたときだけtrueとなります。
 メッセージをスクロールする必要がある場合、指定された画面に対してだけでなくテキストイメージのバックアップバッファ"TextImageBuffer"と、テキストイメージのマスクバッファ"TextMaskBuffer"にも描画する必要があります。TextImageBufferには、通常の画面と同じ内容を描画しますが、TextMaskBufferは文字の部分を黒とした、白黒2色のデータにしなければなりません。これらのバッファはスクロール処理のときに必要になります。
 尚、ScrollFlagがfalseとなっているときには、これらのバッファにアクセスしないでください。不正メモリアクセスをしてしまいます。

Text & Programing by みっくす


  目次に戻る


 ご意見、ご感想などありましたら、メール又は伝言板への書き込みをお願いします。

E-Mail : m_hikida@muh.biglobe.ne.jp

Copyright (c) 1997-2007 Masaya Hikida