人工知能に関する断創録スマートフォン用の表示で見るスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。Learning、Kerasに関する記事が多いです。2008-06-28会話するPygameキャラクターイベント(2008/6/22)で作ったイベントファイルに各キャラクターのメッセージを登録したの覚えてますか?今回は話しかけたときにそのメッセージを話すようにしてみます。メッセージウィンドウの表示(2008/6/28)ではすべてのウィンドウの基礎となるWindowクラスを作りました。今回は、Windowクラスを拡張してはなしたときのメッセージを表示する機能を持ったMessageWindowクラスを作ります。キャラクターの方を向き、スペースキーをおすと話します。pyrpg15.zipはなすMessageWindowクラスの機能を説明する前にどのように使うか解説します。MessageWindowの詳細がわからない場合はとりあえずどのように使うかわかればよいと思います。使うだけならそんなに難しくありません。キャラクターにはなす処理はmain()にあります。&quot;)MessageWindowはWindowのサブクラスです。引数にはWindowと同じように表示範囲の矩形Rectを指定します。MessageWindowオブジェクトはmsgwndに格納します。イベントハンドラでスペースキーを押したとき、メッセージウィンドウが表示中でないなら「はなす」処理を開始します。Playerクラスのtalk()でプレイヤーの目の前にいるキャラクターを取得します。目の前にキャラクターがいるならMessageWindowのset()にそのキャラクターのmessageをセットします。set()すると自動的にメッセージウィンドウが表示され、セットしたメッセージが表示されるしかけです。」というメッセージをset()します。メッセージウィンドウが表示されている状態でスペースキーを押した場合は、MessageWindowのnext()を呼び出します。next()はメッセージを次ページに進めます。次ページがない場合は、メッセージウィンドウを消します。メッセージウィンドウの使い方はこれで全部です。使うだけなら簡単でしょ?ここで、プレイヤーの目の前にいるキャラクターを取得するPlayerクラスのtalk()を詳しく見てみます。charaコメントに書いたとおりなのですが、まずプレイヤーの向いている方向の隣の座標を調べます。向いている方向によって隣の座標は違うのでifで分岐して調べています。わかったらそこにキャラクターがいるか調べます。これは、Mapクラスのget_chara()を使います。talk()にmapオブジェクトを渡していたのはこのためです。&quot;&quot;&quot;(x,y)にいるキャラクターを返す。キャラクターがいるか調べます。マップ内のキャラクターはすべてcharasリストに格納されているのでそこから1人ずつキャラクターを取り出して座標が一致するか調べます。一致するキャラクターがいたらそいつを返します。いなかったらNoneを返します。talk()の最後ですが、これはそのキャラクターをプレイヤーの方向に向ける処理です。プレイヤー様が話しかけてんだからこっち向かせたいですよね(笑)これは、プレイヤーの向きと逆方向に向かせることで実現できます。プレイヤーが右向きにキャラクターに話しかけたならそのキャラクターは左に向ければ向かい合います。次にMessageWindowクラスの詳細を説明します。MessageWindowはメッセージをセットしてウィンドウを表示するset()とメッセージを次ページへ進めるnext()だけ知ってれば内部は知らなくても使えます。ここの説明が難しいと感じたら飛ばしてしまっても大丈夫です。クラスの全体コードを示します。今までの中で一番ぐちゃぐちゃしたコードです。1まずは、MessageWindowは下図のような構成になってます。text_rectがあるのがポイントです(実際の色は赤ではなく黒です)。inner_rectに直接テキストを描画すると少しきつきつな感じがしたのでtext_rectを作りました。メッセージウィンドウのサイズは決めうちです。文字のサイズや一行の文字数などを考慮してこの大きさにしました。行間の大きさこの部分は、表示できるメッセージの文字数などを定義しています。文字のサイズはメッセージエンジンで説明したように16x22ピクセルです。下図のように行間にLINE_HEIGHT=8ピクセルとると1文字16x30ピクセルになります。行間を入れないと文字がつまった感じがして読みにくいです。1文字16x30ピクセルで横に20文字、4行だとちょうどtext_rectと同じサイズ320x120になる計算です。4行目はページ送り用の▼を中央に表示するだけで文字列は表示しません。MAX_LINES=30は、1回のset()で格納できる最大行数です。20x30=600文字が1回の会話の最大サイズです。原稿用紙1枚半ですね。この世界には学校の校長のように長話する人はいないのです(笑)メモリは食いますがもっと長くしておいてもOKです。メッセージエンジンは、改行や改ページもサポートしています。文字列中に/を挿入するとそこで改行されます。%を挿入するとそこで改ページされます。わかんない人は黒猫とはなしてください。set()でメッセージの内容をself.textという1次元リストに格納します。かんじはつかえませんが/なんとかよめるでしょ?は、self.textに次のように格納されます。_は全角空白文字です。わかりやすいように行ごとに2次元リストで書いていますが、実際は1行でずっとつながった1次元リストです。改行文字/や改ページ文字%の場所でちゃんと改行、改ページされていて飛ばした部分に全角空白文字が格納される点に注意してください。30行目set()では、self.textのどこの位置に格納するかをpという変数で制御しています。普通の文字の場合、そのまま文字を格納してp+=1するだけですが、改行文字や改ページ文字が入ったあとpを飛ばしています。どこまで飛ばせばよいかの式は少し複雑ですが上のサンプルを具体例として自分で計算してみてください。いうふうにやっているか納得できると思います。最後にself.max_pageに最大ページ数を格納したあと、show()でメッセージウィンドウを表示しています。show()するとメッセージウィンドウがdraw()で描画されるようになります。メッセージウィンドウとset()で格納した文字列self.textを描画するのがdraw()です。今回は、1ページの内容をまとめて表示します。ドラクエのように文字が流れるように表示する方法は次回取り上げます。(dx,dy))現在表示中のページはself.cur_pageに入っています。draw()では現在表示中のself.cur_page、1ページ分の内容をメッセージウィンドウ内に描画します。計算してMessageEngineのdraw_character()で描画しています。このとき、制御文字(/、%)は描画しない点に注意してください。現在、表示中のページ(self.cur_page)が最終ページでない場合は、▼をメッセージウィンドウの4行目、中央に表示します。next()は、次ページへ進めるメソッドです。1現在表示中のページ(self.cur_page)が最終ページだったらhide()でメッセージウィンドウを閉じます。self.cur_pageに+1して次ページへ進めます。self.cur_pageを+1するとdraw()では次ページの描画が自動的に行われます。実行してみるとわかりますが、1ページの内容がぱっと表示されるため何か味気ないです。▼が点滅しないと何かやです。ドラクエのようなピロピロと文字が流れる表示方法は次回取り上げます。流れるメッセージメッセージエンジン»プロフィールid:aidiary人工知能とその関連分野に興味があります。Blog|ブログを報告する。