2016年10月15日土曜日

宿泊コモンイベント

前の記事で宿屋成長システムが完成しましたし、今度は宿泊のコモンイベント側を実装しました。
宿泊は、採取場のリセットなど、他の機能とも絡んでくるので、かなり処理量が多くなます。


結局こんな感じになりました。

キルスコアや経験値の表示は、かなり飛び道具として直書きスクリプトを使っています。


さて、完成形の宿泊イベント画面を紹介します。
前提として宿泊前に敵を倒していて、なおかつおもらししています。
おもらしぱんつを穿いたまま寝ることも現状可能なのですが、可哀想なので脱がしてあります。ノーパンです。おしっこでじんわり湿った下半身を露わにしたままベッドに入ります。

敵を倒している場合、暗転後にキルスコア表示イベントが始まります。

倒した敵の一覧が出ます。

合計経験値が表示されますが

おもらしをしている場合、おもらしによるマイナス補正値が表示され

得られる経験値は少なくなります。


以上です。
さあ、あとはイラストを描いて、イラスト表示を制御するスクリプトとイベントを作ったら、遂に次バージョンが公開できます。



あ、さっきのおもらししたまま布団に入れるの、積み残しだな…

グラフィックサイズの調整

前回記事の最後で、キルスコア表示画面で敵グラフィックを表示する際、大きいグラフィックの敵がいるとはみ出してしまうという積み残し問題を紹介しました。
今回は、それを解決します。

ビットマップの縮小自体はこの機能だけで必要になるとも限らない汎用的な用件なので、Utilsを作り、そこにメソッドを定義しました。
特に拡縮用のメソッドなどは見当たらなかったのですが、ピクセルに色を直接セットできるので、手書きすることにしました。
以下のような仕様にしました。

  • 引数はビットマップオブジェクトと幅・高さの整数値
  • 1/nに縮小した時に、幅・高さともに引数値以下に収まる最小のnを求め、縮小率とする
  • 縮小後の新しいビットマップオブジェクトを返却する

ソースはこんな感じになりました。

縮小率が整数限定だったり、色々雑な処理ですが、プレイヤーが見て最低限「ああ、あいつな」って分かればいいんです。0.5刻みにするとか、0.25刻みにするとか、ましてやアンチエイリアスだのフーリエ変換だの、やるつもりは毛頭ありません。


さて、テストです。
テスト用の見掛け倒し雑魚軍団を編成しました。

こいつらが、こんな感じの表示になります。 
はい、完璧ですね。
縦幅の狭い表示領域にしているので、縦に長い敵グラがすごく小さくなってしましますが、その辺は可能な範囲で調整すれば良いでしょう。


さて、宿屋成長システムのコア部分はこんなもんでしょう。
おもらし回数の表示とかも必要ですが、それはまあ出来たらまた記事書きます。


宿屋成長システム

ずっと実装すると言いながらも延び延びになっていた、宿屋成長システムですが、やっと完成しました。
概ね完成しました。

前記事で何度も説明している内容ではありますが、当ゲームでは、おもらししてしまった場合のペナルティとして、経験値にマイナス補正をかけようと考えています。
宿屋とトイレは基本的に隣接するデザインとしたいので、トイレ直前でのおもらしにも実効的なペナルティを与えるために、敵撃破時の経験値は一旦は保留し、宿屋に泊まった時におもらし回数によるマイナス補正を掛けた上で一括で獲得されるという仕様としました。

居合のところでは面倒になったのでコードの紹介を端折りましたが、あんまりそれやってると、このブログの意味が無くなるので、今回はちゃんとやります。

その前に、詳細な仕様ですね。
以下のようなモジュールによって、この機能は構成されています。
  1. 経験値の獲得処理を上書きし、キルスコア記録処理に変更
  2. キルスコアのグラフィック表示および、その消去
  3. 合計経験値の算出と汎用一時変数へのセット
このうち、2,3は同一クラス内に定義し、グローバル変数に常に一つだけオブジェクトを持ち、これを使い回します。同オブジェクト内にはハッシュを持ち、敵種別をキー、撃破数を値として保存します。
1はBattleManagerの再定義することによって実現しています。なお、当ゲームでは敵はお金をドロップせず、ドロップアイテムを換金することでお金を得るようにするので、お金の取得処理もついでに無効化します。

さて、コードの紹介です。処理順に説明していきます。
これが、上記のクラスです。コンストラクタ内ではキルスコア表示用のスプライトオブジェクトの生成と位置決めを事前に済ませています。ステータス表示モジュールと同様の実装方法です。

続きまして、上記1の部分です。

上のmodule内が該当部分です。ちょっとダルいソースですが、よくある一般的な集計処理ですね。

ここで敵を表すクラスについて説明しておこうと思います。
敵を表すクラスにはGame_EnemyとRPG::Enemyの二種類があり、前者は個体を、後者は種別を表しています。GUIから作成したエネミーのデータ1件につきRPG::Enemyのオブジェクトが1件ツクールシステム側で生成され、ハッシュだか配列だかに格納されています。Game_Enemyは自己の種別を表すためにRPG::Enemyのオブジェクトを参照しています。

当機能では種別ごとの撃破数を記録することが目的なので、集計用ハッシュのキーはRPG::Enemyのオブジェクトとしています。


続きまして表示です。
合計経験値が多い順に最大で現状では9件まで表示するようにしています。
件数はスプライトオブジェクトの数を参照して切り替えているので、コンストラクタでの生成と並び替えのほうを変更すれば自動的に調整されます。

画像表示について、調査を要したのは以下の点でした。
  • エネミーの画像はキャッシュされているので、Cache.battlerメソッドを用いてBitmapオブジェクトを取得する
  • Bitmap.draw_textメソッドを利用すれば、文字列を画像として自動生成できる

余談ですが、後者は画面左上にステータス表示処理を実装していた時に、ウディタで出来たのにツクールでは出来ないのかと長らく思っていた点でした。扱い慣れないうちは機能を探す目も鈍いものですね。
しかし、この処理は所要時間が長いため、毎フレームの処理には適さないようです。この機能では全く問題になりませんが、ステータス表示には適さなかったでしょう。その点、結果的には適切な実装方法が選択できていました。
余談終わり。


そして、最後に、値をセットする部分です。
イベントとの接合部なので、汎用一時変数に値をセットします。

合計経験値の取得と、記録ハッシュの初期化はなるべくアトミックにしたいと思いました。最終的に値を利用するのはイベント側なので完全ではありませんが。
配列などのメソッド名に倣ってpopと付けています。
どうなんだろう、この実装とネーミング…



さて、スクリプトができたのでイベント側を準備してテストです。
実際には、他にも色々処理のある宿泊処理に組み込むのですが、テストドライバとしてはこんな感じで良いでしょう。

さあ、テストプレイです。適当に雑魚を屠ります。

経験値とお金の取得メッセージが出なくなっています。

さっきのニワトリに話しかけると、敵のグラフィック、経験値、撃破数が表示されます。
この表示は実際のゲームでは宿泊中の暗転を背景に表示される予定です。

経験値入手のメッセージ。これは文章の表示機能の中で変数を参照しているだけです。

レベルも上がります。この表示は、経験値取得イベントでメッセージ表示にチェックを入れておけばツクールシステム側が自動的に生成してくれます。楽チンですね。


おもらし回数を参照して取得経験値に補正をかける部分がまだできていませんが、宿泊コモンイベント内でいくつかの処理をGUIから追加すれば済む話です。宿屋成長システムはほぼ完成したと言って良いでしょう。


ところで、このドラゴンを見て下さい。
こいつは見掛け倒しのテスト用クソザコナメクジなのですが。


びゃああああああああああああ



次回、グラフィックサイズの調整。
最悪力技でゴリゴリ書けば簡単に解決する算段はあるぜ。
乞うご期待。

2016年10月13日木曜日

進捗報告まとめ

長らく更新していませんでしたが、開発はぼちぼち進んでいます。

そもそもこのブログは、宣伝用や進捗報告用でもありますが、それ以上に自分が設計を忘れた時用の備忘録という側面が強いので、ソース以外の進捗に関してはあんまり「記事書くぞー」ってならないのです。

さて、こうして久しぶりにブログを書く気になったのも、マップやイベントの作業が一段落して、再びスクリプトの工程に移ったためなのですが、書きかけのスクリプトを紹介する前に、まずはマップをざっくりと紹介しようと思います。

今回のリリースでは、レベルを上げながら一つのダンジョンを探索・攻略して、ボスを倒すところまで遊べるようにするつもりです。
ダンジョンは大きく分けて、森、地下通路、砦の3つのパートから成ります。





また、その他に拠点となる集落があります。

お店もあります。

チュートリアルの貼り紙

チュートリアルさんたち


宝箱があったり


あと、オープニングもできてます。



オープニング中におしっこを漏らしてしまったら…?


敵も、ほぼできています。

ボスもいます。

こんな感じです。
スクリプトできたら、また紹介します。


2016年9月26日月曜日

('ω'乂) 実装の不具合は \( 'ω')/ テストでカバー

なんか今回、自分の書いたコードに自信持てなかったんですよね。
なんで、職業プログラマ流の力技で解決しました。

ああああああああああああああああああ


はい、バグいっこ見つかって、全ケース完走しました。
あー面倒くさかった。ケースの妥当性? 知るか。

居合

お久しぶりです。
宿屋成長システムは置いておいて、先に「居合」というシステムを実装していました。このシステムは、武器を持ち替えるのと同時に攻撃する戦闘中技を可能にします。

このゲームは、主人公が常に一人であることを前提にデザインしてあるので、戦闘が単調になりがちです。そこで戦闘の幅を持たせるため、この「居合」システムを実装しました。


戦闘シーンのクラスを、複数箇所上書きして作成しています。
ちょっとしたハックじゃないかと思うくらいの修正箇所です。

ウィンドウの仕組みとか、いちいち説明めんどいので、割愛します。


さて、割愛したので、早速ですが出来た物の紹介です。
まず技ですが、メモ欄にキーワードを書く定番の実装です。
居合をstripoutと訳すのは、何かのTRPGで見かけた訳例です。
そこまで良い訳とも思いませんが、iaiと書くのもなんかダザいので、これでいきます。

武器が複数必要なので、武器の入った宝箱を設置します。
これは別に普通の武器と宝箱です。

対応した技を選択すると、武器一覧が表示されます。
これは、装備変更画面で使われているウィンドウを流用しています。

武器の選択が終了すると、武器ウィンドウが閉じ、敵キャラ選択ウィンドウが出ます。
なお、敵選択をキャンセルすると、再び武器ウィンドウが出ます。

攻撃エフェクトから判断する限り、きちんと武器が切り替わっているようです。


戦闘終了後、確認すると装備が変更されていました。
これが仕様として良いかどうかはともかく、正しく実装は出来ているようです。




居合システムはプレイヤーが一人であるという特殊な仕様を前提に実装しています。戦闘参加プレイヤーが複数人いると、バグが発生します。


さて次こそは、宿屋成長システムを実装します。

2016年9月23日金曜日

採取場_イベント側

前回記事で、作るよって言ってた採取イベントのイベント側実装です。

イベントタブ構成や名称のルールは前回記事で紹介した通りです。

ランダムで、袋が落ちていて、ポーションが拾えるというイベントです。


この羊は、前回作ったセルフスイッチ初期化スクリプトを呼び、また日替わりの乱数に値をセットします。実際のゲームにおける宿泊イベントを想定したテストドライバです。

第一タブでは非表示になっていますが、この袋を5つほど落としてあります。
2個セットの袋は前回のテストデータなので無関係です。

初期状態では、日替わりの乱数がセットされていないので、何もありません。
羊に話しかけ、イベントの一時消去を解除するためにマップ移動を挟みます。

袋が2つ落ちています。

回収します。

再び、羊に話しかけ、部屋を往復すると、今度は3つ袋が落ちていました。

続きまして、おもらしした場合の検証です。
ぬいちゃんには毎度申し訳ありませんが、おしっこを漏らしてもらいます。

おしっこ臭さの表示が現れるのと同時に、マップ内の袋が消えました。


さて、採取場の実装はこれで完了です。
そもそも課題として挙げるのを忘れていたので、今バージョンに含める予定も無かった仕様なのですが、作ったので含めます。


あれ? おしっこ臭さ関連機能としてついでに盛り込んだけど、
別におしっこ臭さ参照してなくね…?(参照しているのはおもらし回数)