さすけの波乱万丈な日常 このページをアンテナに追加 RSSフィード

ホームはmoonwhistle.org。神無月サスケの近況報告。より詳細に雑多に日常をつづったtwitterはこちら→ktakaki00

2017-04-24 いろいろありました

[]Moon Whistle の曲に作詞しました・第2弾

前回、拙作ムンホイのフィールド曲に歌詞を付けたところ、大変好評でしたので、ふたたびいくつか歌詞を作成しました。

今回は4曲です。前回のオーソドックスなのと比べて、若干変化球を選びました。

好評ならまたやります。

曲のダウンロード

下記の歌詞の曲は、ここからダウンロード出来ます。

http://fhouse.s17.xrea.com/moonwhistle_remake/midimh.html

いろんな人たち (XMIDI009.mid)

1.

(安いよ安いよ お買い得だよ)

八百屋のご主人

(うなぎの蒲焼 香り振りまく)

魚屋のご主人

みな、立ち止まり、商品ながめる

お客さんを 魅了していく

2.

(タイムサービスの 鐘鳴らすよ)

ブティック店員さん

(試食をしてって そっと勧める)

パン屋のお兄さん

みな つられて 不可抗力で

引き寄せられる いろんなお客さん

3.

(ダイエットには この薬!)

薬局の 看板

(眠ってる和服 ありません?)

問いかける 着物屋

商売努力

みんな 必死に 頑張るお店

応援 したくなる

4.

(うちはスポーツマージャンです)

老舗の雀荘

(お酒とカラオケをどうぞ)

カラオケ喫茶

どんな お店なの 僕には分からない

でも なんだか 悪い気はしない

エレベーターダンジョン(XMIDI013.mid)

(1…3…6…9…10…12…15…19)

(とびとびとびとび……からくりだ

とびとびとびとび……こまる)

ビルの中 ずらりと並んでる

エレベーターの 奇妙な表示板

(とびとびとびとび……からくりだ

とびとびとびとび……こまる)

どこの階に どうすれば 行けるの?

どの箱に 乗れば 辿り付けるんだろう?

(とびとびとびとび……からくりだ

とびとびとびとび……こまる)

あーわからない もうお手上げ

だけど 行かなくちゃ

ひとつひとつ 数字を覚え

ひとつずつ ひとつずつ やらなきゃ

僕は行かなきゃ

待ってる人のため

(そう……だ……やる……んだ……)

絶対あきらめない!

おうたをうたおう(XMIDI020.mid)

1.

さあみなさん きょうは みんなに

あたらしい おうたを おしえましょう

まずはわたしが うたうから

みんなそれに つづけて うたってね

さいしょは みんな なれないでしょうけど

くりかえす うちに きっと おぼえる

あたらしい おうたを おぼえた あとには

おうちの ひとにも うたってあげて

2.

さあみなさん きょうは みんなに

かみしばいを みせて あげますよ

わるいおにも こわいおばけも

でてくるけれど こわがらないで

さいごには みんな せいぎのみかたが

わるいやつ せいばい してくれる

だからみんな あくびせずに しんけんに きいてね

わたしの はなす この はなしを

嵐の予感(xmidi064.mid)

夕間暮れ 忍び寄る

暗闇の中 ひっそりと

にじり寄る この空気

きっと何かが 僕を 狙ってる

空には三日月 星の群れ

穏やかに 僕を照らす

でもその空と この風は

じきに 嵐を 呼び起こすだろう……

2016-08-04 久々の更新

[]Moon Whistle の曲に作詞しました

Moon Whistle は 1999年公開。リメイクも2011年に出ており、その間、歌詞を作ってくれる人がたくさんいました。

フリゲの中には作者公式の歌詞があるゲーム音楽もあるようですね。ふと気が向いたので、主要なフィールド曲に歌詞をつけてみました。

普段はあまり作詞などしない僕なのでたどたどしいのはご容赦を。

曲のダウンロード

下記の歌詞の曲は、ここからダウンロード出来ます。

http://fhouse.s17.xrea.com/moonwhistle_remake/midimh.html

いざ行かん (XMIDI005.mid)

春の土手を歩く風の匂い

草は萌えてちょうちょは舞いを楽しむ

川は流れメダカが泳ぐ

柔らかい日差しが川を照らして 輝く

ふと浮かぶよ あの日の思い出

みんなわいわい 陽気の中 駆け回った

季節巡り 雪が解けて また来た春 また思い出になる

ひざしの中を (XMIDI024.mid)

青空を覆ううろこ雲

ビルの谷間から覗く太陽

心地よい風が吹いてくる

空き地から聴こえるよ虫の声

セイタカアワダチソウも 赤く色づくもみじも

どうして 僕の心を 揺るがすの?

友達と一緒に出かけよう

きっとみんなおんなじ気持ちだろう

国道沿いの枯れすすき

遠くまで道はずっと続いてる

夕闇にとける街 (XMIDI001.mid)

お日様が 低い空で 町を赤く染める

街灯が 僕の影 長く延ばしてるよ

公園の 賑やかな声 今はもう静まった

誰かさんの サッカーボール ぽつんとたたずむ

夕焼けに 光る 一番星

晩御飯が 待ってる おうちに 帰ろう

あしたまた 遊ぼう

さわがしい大通り (XMIDI006.mid)

1.

忙しそうに歩く人達 腕時計 見ている

窓越しに喫茶店 見てみたら さぼってる サラリーマン

ビルが 立ち並んで 見知らぬ人が 通り過ぎる

窓の ガラス光る 昼の太陽 反射する

黒い革靴 書類手に持ち 繁華街 

無心に 駆け回る 大人たちの午後

2.

犬の鳴き声 鳥のさえずり 自動車のクラクション

しゃれた生垣 干された布団 青空の飛行機雲

路地の 隅の方で 井戸端会議 おばさん達

デパートの 駐車場で こっそり遊んでる 子ども達

晴れた昼下がり けだるい午後 元気出し

さあ 歩き出す 探検だ 知らないとこ 行くぞ

手をつないで歩こう (XMIDI054.mid)

住んでる 町は違っても 心は通じ合うよ

歳の差 気にならないよ 仲良く行こう

僕が困れば 助けてくれて

君が困れば 僕が行く

何も話をしなくても 笑顔が一番

言葉はいらない 分かり合える

手と手を とりあおう 友達になろう

嫌な子 いるけど きっと仲良くなれる

一緒に 歩こう 街は魅力で一杯

僕らみんな一緒に 凄い冒険するぞ

(追記 2017.04.23 若干歌詞に不自然な部分があったので修正を行いました)

2015-04-25 Moon Whistleのセルフノベライズ

[]ムーンホイッスル小説版を電子出版します

ご無沙汰しておりました、久々のブログ記事です。

今回、拙作ムーンホイッスル(Moon Whistle)の小説版を、Amazonで電子出版することになったので、お知らせです。既にアマゾンで登録を済ませており、数日内に公開される流れです。

ここまでの大まかな流れ

このセルフノベライズは、僕が2013年の春から夏にかけて仕上げたものです。おりしもフリーゲームのノベライズが盛んになっていた時期、ということで執筆を思いつきました。

2013年の9月に、某社の編集者さんに読んでいただける機会があり、内容としては、一定の理解を示していただけたのですが、事情があって出版には至りませんでした。

それは、ライトノベル専門の編集部だったこともあり、「あまりライトノベルらしくない」という理由が大きかったようです。確かに、キャラクターを立てるというより、ちょっと児童文学っぽい描写が多いのは僕も承知しています。

もう一つは、「長年愛されておりファンのすそ野が広いのは事実だが、ここ数年の盛り上がりには欠ける」という点も挙げられました。

そういうわけでその編集部では出していただけませんでしたが、丁寧な対応をしてくれたと感謝しています。

そして、同じ会社の別の書籍部に渡してくださいました。これが2014年1月のことです。

しかしそちらの編集者さんからは、あまり良い対応をしていただけませんでした。いくつかのフリーゲームのノベライズを担当している方なのですが、僕の小説は、いつまでたっても読んでもらえないばかりか、こちらがメールで相談してもなしのつぶてということが続きました。興味がなくても、最低限、読んでは欲しかった、それは無理でもきちんとその旨ご連絡いただけたら、と思っています。このように、編集者さんにも、いろんなタイプがあるのだと痛感しました。

2013年の末ごろに、「ムーンホイッスルが商業展開するかも」ということを僕はツイッターで表明したのですが、それはこの件が進んでいることでした。かなりいろいろと考慮してもらったのですが、前述のとおり、出版には至りませんでした。

電子出版で出してみることに

そういうわけで、一度はお蔵入りにした小説ですが、その後「紙の書籍がだめでも、電子出版ならいけるんじゃないか」と思うに至りました。

なにしろ、昨年あたりから、僕のよく知っている人達が次々に電子出版に参加しており、あちこちで話を聞いていたからです。

これまで「紙の書籍でないと、読みたい人の手に届かない」そう思っていたのですが、これだけ電子書籍が普及してきたなら、その懸念は小さくなる、と感じました。

それで早速、その準備を始めました。2014年9月ごろのことです。

その後、表紙絵やイラストを描いてくれる方(飛鳥好一さん)とも出会い、こうやって電子出版することが出来ました。感謝。

読んでくれる皆様に感謝

今回、こちらの小説については、いろんな方に読んでもらいました。そして、いろんな意見をいただけました。

特に、今回、電子書籍での販売に至ったのも、知人からのアドバイスでした。

小説を公開するだけなら「小説家になろう」など、無償で公開可能なサイトはたくさんあります。しかし、今回は、あえて有償にした方がいい、という意見が圧倒的でした。フリーで公開しても、数件感想書いてもらうだけで風化しかねない、といった意見が聞かれました。

この「フリーより有償の方がいい」という意見については、僕の中では肯定する気持ちと否定する気持ちが半々でしたが、やはり「本当に読みたい人にだけ手に取ってもらいたい」という気持ちで実験的な要素も含めています。

金額はひとまず5ドル(500〜600円くらい)にしました。こちらも、僕は300円くらいにするかと思っていましたが、それじゃ安い、というご意見を伺ってのことです。確かに、本当に読みたい人にだけ届けるのなら、妥当かもしれません。価格は変更可能らしいので、少しこの金額で余裕を見ます。

今しばらくお待ちを

現時点(17:04 2015/04/25)ではまだ公開されていません。

公開されたら、恐らく、プレビューとして序盤が読めると思いますので、興味がある方は見ていただけたら幸いです。

追記(21:05 2015/04/25):公開されました!

小説ムーンホイッスル

http://www.amazon.co.jp/gp/product/B00WO3O3O0

今後地味にプロモーションしていきたいと思います。

2012-01-02 地味な技術

[][]ムンホイXPの地味な技術:その2.ビューポート分割

導入動機:天候を導入しようと思って出てきた障壁

ムンホイのXP版にあって、オリジナルになかった要素のひとつに、天候があります。雨が降ったり、雪が降ったりする演出です。これを導入した最初の動機は単純で、せっかくRPGツクールXPに、そのような機能が準備されているのだし、導入すればささやかな演出の華になるだろう、と思ったことでした。

しかし、そこにひとつの障壁がありました。それは本作のマップの構成です。

本作のマップ構成:屋内でも屋外部分が描かれている

ムンホイの屋内マップ構成の一例を次に挙げます。

f:id:ktakaki:20120101054316p:image

ご覧になっての通り、周囲に外の景色が描かれています。これは、RPGツクール95時代には比較的一般的なやり方でした。一方、RPGツクール2000以降は屋内では周囲が黒い壁に囲まれており、屋内マップでは外の景色は描かれないのが一般的になりました。

これには理由があります。ツクール2000で初めて天候が導入されたのですが、もしこれを導入する場合、屋内に外の景色が描かれていると、その外の部分にも雨を降らせないと不自然になるからです。ツクール2000には(それ以降のツクールでも)「屋内部分では雨が降らず、外の部分にだけ雨を降らせる」といった機能はないため、屋内では単に雨をやませる、その際のマップで外の景色は描かない、というやり方が定着したのでしょう。

要求:「屋内から見える外の部分だけ雨が降っている」を実現できないか

さて。オリジナルのムンホイは天候のシステムが無かったRPGツクール95作品です。このため、天候のことを意識しないマップ構成になっています。このため、天候などは入れずに行くべきか? と思いました。

あるいは、マップの方を書き換えて外の部分を塗りつぶすという手もあるでしょう。しかしそれはしたくありませんでした。あくまでオリジナルの雰囲気を変えたくなかったし、そこに手を加えるくらいなら、天候など入れない方がいい、と。

そのように考えたのですが、最終的には「屋内から見える外の部分だけ、天候のアニメーションを表示する」という処理が実現できました。これは試行錯誤して出来たというよりは、あるとき急にひらめいて、その考えに基づいて入れてみたらすんなりうまく行った、という性質のものです。そのメカニズムを紹介していきたいと思います。

実例

メカニズムの説明の前に、先にこの実装によって、具体的にどういう風になったかを、スクリーンショットを使って紹介します。百聞は一見にしかず。

この「屋内マップで描かれている屋外の部分にだけ画面処理を加える」というシステムの実装により、天気のほかに、夕焼けの描画もオリジナル版から変更することが出来ました。オリジナルの95版では、屋内でも全体が夕焼けのパレットになっていましたが、リメイク版では、屋外部分のみが夕焼けになっています。次のような感じです:

f:id:ktakaki:20120101054314p:image

パレットが変わっているのが、屋外部分というわけです。雨のアニメーションなども、この部分にだけ描画されるのです。

具体的にどうしたのか、RGSSでの実装やマップエディタでの設定方法を紹介します。

実装:屋内と屋外でビューポートを分ける

屋外用のビューポート(名づけてビューポート0)を作成

基本的な考え方は、屋外のあるマップでは、屋内用と屋外用に、スプライトを表示するビューポートをそれぞれ用意する、というものです。

既存のRGSSでは、ビューポートは、viewport1〜viewport3 が用意されていて、viewport3 が一番手前にあり、viewport1 が奥です。そして、通常のマップ(Tilemap)は、viewport1 に表示されています。(奥にある=z座標が小さい、ということです)

今回は、そこに拡張を行います。屋内マップで屋外も表示する必要がある場合、屋内部分と屋外部分を分けて表示するために、屋内部分を既存のviewport1に、屋外部分をそれより奥にある新設したビューポートに表示することにします。この新設したビューポートは、viewport1 より奥にあるため、viewport0 と呼んでいます。

マップの屋内用と屋外用の Tilemap オブジェクトを作成し、それぞれのビューポートに置きます(どうやって屋内と屋外を分けるかは後述)。そして、天候の処理、雨や夕焼けなど、外だけに処理が必要になった時は、屋外用(ビューポート0)に対してだけその処理を行うことによって、「外側だけ、天候やパレットが変更される」という処理が実現できます。

タイルマップの要素を屋内と屋外に分ける

このように「屋内と屋外の部分でビューポートを分けて表示する」ことにしました。では、マップの要素で、どこが屋内でどこが屋外かを設定するにはどうすればいいでしょう。

マップエディタを見ると、以下のように設定されています:

f:id:ktakaki:20120101054315p:image

マップの外側を示す部分に×、窓の部分に\という記号が置いてあるのが見えると思います。結論から言うと、これらの記号は3つあるレイヤのうちの最も手前(レイヤ2)に置かれています。×の記号は、残りの2つは外側に、\の記号はレイヤ1を内側に、一番奥(レイヤ0)を外側に置く、という意味です。(特に記号が無ければ、全て内側です)

内側と外側に分かれたタイルマップを作成する処理は、Game_AnotherMapData クラスによって行われています。Game_AnotherMapData#setup メソッドを見てもらうと分かりやすいと思います。マップから読み込んだ マップデータオブジェクト(Table)をもとに、inner および outer と名づけられたマップデータ(Table)を作成しています。これらが、内部用、外部用の Tilemap で使用されるのです。

なお、このように「屋内と屋外で表示を分ける処理を行う必要があるマップかどうか」の設定は、初期化イベントというもので設定しています。原則、マップの座標(0,0)に置かれているイベントで、イベントの名前に「!init」が含まれているものが初期化イベントと見なされます。初期化イベントのグラフィックにタイルを設定すると、そのタイルIDが、特別な処理をするものになります。ここで、×マークの描かれたタイルが設定されています。(\は、×マークの次のIDのタイルです)

このようにして、屋内用と屋外用の2枚のTilemapオブジェクトを作成し、それぞれ別のビューポートに所属させることによって、屋内と屋外を表現しているのです。

おさらい:エディタで中を見ながら確認

さて、ここまで読んで理解出来ているでしょうか。RPGツクールXPで実際にムンホイXPを読み込みスクリプトエディタを起動して、該当箇所と付き合わせながら読んでいくと理解しやすいと思います。

ここまでの理解を元に、Spriteset_Map クラスを読んでみましょう。簡略化のため、タイルマップ、パノラマ、天候の処理は、Spriteset_MapElements クラスを作成し、そちらに処理を移しているため、それらを合わせて読んでいってください。

Spriteset_MapElements#initialize メソッドを見てください。屋内と屋外に分けたデータ(AnotherMapData クラスのオブジェクト $game_map.am_data)を元に、ビューポート0とビューポート1に分けて作成している様子が分かりやすいと思います。

屋外部分にあるイベントの設定

タイルセットのビューポートを分けることが出来ました。次は、イベントの設定です。

イベントの中には、屋外部分に配置されている物もあります。例えば、上記のスクリーンショットの中では、外にカプセル(宝箱)があるのが見えると思います。ゲームをプレイした方ならお分かりでしょうが、建物の北の駐車場から回り込めば取ることが出来るのですよね!

このように、外側部分にあるイベントはビューポート0に置く必要があります。そのようなイベントは、名前に「!v0」という文字を含ませることによって設定するようにしています。具体的には、Game_Event#viewport0? というメソッドで判定しています。

そして、このメソッドでビューポート0用と判定されたイベントのスプライトはSpriteset_MapElements#add_sprite_to_viewport0 メソッドでビューポート0に配置されています。

このように、ビューポート0に配置するイベントは手動で設定する必要があるため、若干面倒ですが、これは仕方が無いですね。自動判別する仕組みが作れたら便利だったのですが。

プレイヤーが外側の部分に出るときの処理

次に考慮するべきなのは、プレイヤーが外側、つまりビューポート0の部分に出る場合です。

f:id:ktakaki:20120101054313p:image

この場合、ビューポート0に配置するイベントと同様、プレイヤーをビューポート0に配置しなければ、パレットの変更などに対処できません。

このため、外に出るマップの場合、通常(ビューポート1)用と、外に出た時(ビューポート0)用の2種類のスプライトを作成し、現在位置のビューポートに合致する方だけを表示するようにしています。つまり、屋内にいる時は、ビューポート1用のスプライトだけを表示し、ビューポート0用は消去、逆に屋外に出たらビューポート0用を表示し、ビューポート1用は消去するということです。

この処理を実装したのが、Sprite_Character2 です。通常の Sprite_Character にビューポートの監視を行う処理を追加し、異なるときは表示を行わないようにしています。

このビューポートの監視に使う変数が、Game_Player に追加された @viewport_id というインスタンス変数です。プレイヤーが内側にいる時(あるいはビューポートを分けない場合)は 1 を、外側の時は 0 を取るようにしています。

ビューポートの切り替え(内側と外側を切り替える)は、イベントで行っています。コモンイベントの12番と13番に「ビューポート0」と「ビューポート1」というのがありますが、これをイベントから呼び出すことで、切り替えているのです。

結論:限りなく地味な技術。僕自身、他の作品で採用するかどうか不明

解説は以上ですが、いかがだったでしょうか。この「外だけ雨が降っている」という処理、スーファミなどのRPGでは、普通に見られた処理なので、本作で見かけても目新しいとは思えなかったと思いますが、ツクールの他の作品で見かけたことがないという人も少なくないのではないでしょうか。

無理もありません。外と内を分ける為には、マップ設定から若干ややこしい処理を行う必要があるので、なかなかやる人はいないでしょう。現にこの僕も、リメイクということで元のマップを変更したくないために行った処理です。1から新作を作る場合は、こんなややこしい処理を入れる代わりに、外側を黒く塗りつぶしていたと思うのです。

このため、この技術は本作のみのものになるかもしれません。しかしこの「Tilemapを2枚作り別々のビューポートを作る」という発想は、何かあなたの制作のヒントになるかもしれないと思い、紹介させていただきました。RGSSでこのあたりを大胆にいじっている人は少ないのですが、このあたりの改変こそが、RGSSの醍醐味だと僕は思っているのです。

[][]ムンホイXPの地味な技術:その3.フィールドマップのあれこれ

普通のRPGだと、ウィンドウのレイアウトとか戦闘のシステムやレイアウトなどに凝るものらしいですが、本作品ではそういうのは極力据え置きにして、マップ画面の仕様とかそういうものばかりいじっていました。

このため、町を移動するのが結構意味も無く楽しかったりするでしょう。それは、システム的に地味なことをたくさんしているからかもしれません。

プライオリティの導入

RGSSゲームライブラリ、Tilemapクラスにはプライオリティという概念が導入されています(RPGツクールXPのみ。VX以降は廃止)。タイルごとにプライオリティを、なし(0)から5までの間で設定することで、そのタイルの位置する「高さ」を設定しているのです。

ムンホイXPのシステムでは、この考え方を Game_Character オブジェクト(イベントやプレイヤーなど)にも導入し、タイルとの親和性を高めました。

Game_Character#priority の仕様

具体的には、Game_Character に @priority というインスタンス変数を追加しています。priority の取ることの出来る値は、タイルと同様0〜5で、これにより、同じプライオリティにあるタイルと同じ高さに表示されることになります。

これによって、様々な仕様を変更しています。例えば、Character#screen_z は、priority 導入により、それを用いた計算式に拡張しています。

プライオリティを使った多層処理

通常はプレイヤーやイベントのプライオリティは1ですが、このプライオリティを操作することで、多層処理を行っています。具体的には、以下の例が挙げられるでしょう。金網の下をくぐりぬけたり、上を通ったりすることです。

f:id:ktakaki:20120102021551p:image

f:id:ktakaki:20120102021550p:image

ここでプレイヤーが金網の下を通っている時のプライオリティは1、金網の上に乗っている時のプライオリティは3です。プライオリティ1の時を「下層」、プライオリティ3の時を「上層」と呼んでいます。

そして、タイルのプライオリティは次の方針に基づいて決められています。

  • 0=プレイヤーの下にあるもの(床や地面など)
  • 1=プレイヤーと同じ高さにあるもの(民家の壁など)
  • 2=プレイヤーの上にあるが上層になると下になるもの(屋根など)
  • 3=プレイヤーが上層に出たとき同じ高さにあるもの(屋根の上にある障害物)
  • 4以上=プレイヤーが上層に出ても上にあるもの(アドバルーンなど)
マップエディタでの設定方法

タイルにあったプライオリティをイベントに拡張するにあたって、イベント名に「@2」や「@4」などの「@+数字」が付いていた場合、その数字を、そのイベントのプライオリティとして設定することにしています。イベントを上層に置くためには、名前に「@3」という文字を入れると良いわけです。下層に置く場合は、デフォルトのプライオリティが1のため、わざわざ「@1」と書く必要はありません。

なお、下層と上層では、タイルの通行判定が違います。このため、上層の通行判定だけ、別のタイルセットのものを使っています。ムンホイXPでは、タイルセットはひとつにまとめており、ID=1番のものを使用していますが、上層の場合はID=2番の通行判定を使っています。

プレイヤーの上層と下層の切り替え

イベントから「スクリプトの呼び出し」で以下のようにすると変更できるようにしています。

下層に変更する場合:

$game_player.set_priority(1)

上層に変更する場合:

$game_player.set_priority(3)

これは、コモンイベントの1番(上層→通常)と2番(通常→上層)から呼び出されいます。イベントから、これらのコモンイベントを呼び出して切り替えます。ただし、実際にはもう少し複雑な処理を追加しているため、興味がある人は実際にコモンイベントおよび、そこから呼び出されているスクリプトを確認してみてください。

結論:多層処理だけなら、他のより簡単な実装方法がある

以上、ムンホイXPでの多層処理のメカニズムでした。実際には多層処理を行いたいだけなら、わざわざこんなことをしなくても、より簡単な方法はいくつかあります。

例えば、RPGツクール2000の方法として、同じタイルセット(2000ではチップセットという)グラフィックを使って、通行判定だけを変更したものを準備します。通常と上層を切り替えるタイミングで、イベントコマンド「チップセットの切り替え」を行えば、通行判定やプライオリティを変更させることが出来ます。XPには「タイルマップの切り替え」はイベントコマンドにはありませんが、同様のことはスクリプトで出来ると思います。

また、RPGツクール95では、オリジナルのムンホイでは、屋上など、上層の地形は「海」になっています。上層に出る時は、RPGツクール95特有の機能「主人公タイプの変更」でタイプを「通常」から「船」に変更することによって、海は通れるが普通の地形は通れない、つまり屋上のタイルは動けるが、別のところには行けない、というようにして実現しています。

以上を参考にすれば、より簡単な方法はあるのですが、ここではデータの一貫性があった方が拡張がしやすいと思い、今回のような方法を採用しました。

補足:この方式の採用を検討する人への注意

もうひとつ重要な注意があります。ムンホイではプレイヤーなど、主要なキャラクターの大きさが32までになっています。これはVXやVX Aceのキャラチップに近い仕様です。このため、これらのプライオリティの設定で問題ないのですが、より大きなキャラチップを使用している人が多いでしょう(32x64など)。この場合、この設定だけでは不十分な場合があります(キャラクタがプライオリティ2の屋根を突き破る、といったことがある)。このため、この考えを導入したい人は、タイルのプライオリティの値を吟味する必要があるでしょう。

斜め移動

はじめに:なぜ斜め移動はRGSSに標準搭載されないのか

斜め移動は、結構スクリプト素材も出回っており、単に斜めに移動するというだけなら、大して難しくはありません。そもそも、RGSSレベルでも、イベントコマンドでは斜め移動が標準搭載されており、これなら、プレイヤーの移動にも斜め移動が採用されてもおかしくないように思えます。(更に言えば、イベントコマンドでの斜め移動はRPGツクール2000の時代からありましたよね)

しかし、実際はRPGツクールVX Aceで、多用な機能が標準搭載されたRGSS3でさえ、斜め移動を採用しませんでした。これはなぜでしょうか。

僕に考えられる大きな理由の一つは、「ユーザー側が考慮しないと、斜め移動の見た目が不自然に見える場面が多くなるから」だと考えられます。

斜め移動が不自然に見える3つの例

まず最初に。斜め移動の通行判定は、RGSSではどのように組まれているのか、見てみましょう。左下に移動する場合(Game_Character#move_down_left)を引用します:

    # 下→左、左→下 のどちらかのコースが通行可能な場合
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))

コメントにあるように、左下に行く場合「下→左、左→下 のどちらかのコースが通行可能な場合」は通行可能で、通行の処理を行うのです。

確かにこれなら、通行できないはずの地形に迷い込むようなことはありません。しかし、見た目としては、非常に不自然になることがあります。僕がテストプレイしていて見つけた(そして対処した)大きな問題点を3つにまとめ、それぞれ次の名前で呼ぶことにしました。

  • 梯子
  • 吹き抜け
  • プレート(壁)

これらを、ひとつずつ説明して行きます。

梯子

次のような移動を考えます。すなわち、階段や梯子のような地形に、斜め移動で入る(あるいは出る)場合です。

f:id:ktakaki:20120102031702p:image

この時、「壁の中を斜めに横切って、階段(梯子)の途中の部分に飛び移っている」というように見えてしまいます。

吹き抜け

次のような移動を考えます。

f:id:ktakaki:20120102031701p:image

この時、「何もない吹き抜けを斜めに横切って、空中移動している」ように見えてしまいます。

プレート(壁)

次のような移動を考えます。移動先は「下への移動のみが不可」という、平らな壁(プレート)のような地形です。プレートに斜めに入る(または出る)場合です。

f:id:ktakaki:20120102031700p:image

この時、「身体半分を壁にめり込ませながら移動している」ように見えてしまいます。

斜め移動禁止地形の導入

そこで、ムンホイXPでは、タイルに「斜め移動禁止」属性を追加しました。上記の3つのうちどれであるかは、自動判定されます。すなわち……

  • 「斜め移動禁止」で、通行不可であれば、吹き抜けタイル
  • 「斜め移動禁止」で、通行可能で、プライオリティがプレイヤーより低ければ梯子タイル
  • 「斜め移動禁止」で、通行可能で、プライオリティがプレイヤーより高ければプレートタイル

ということです。

なお、この「斜め移動禁止」属性は、地形タグで実装するのが一般的でしょうが、本作では茂み(0x40)を使用していないため、茂み属性を「斜め移動禁止」として使用しています。

スクリプトでの斜め移動禁止の実装

Game_Map#ladder? で梯子判定を、 Game_Map#wellhole? で吹き抜け判定をしています。プレート判定は、梯子判定と処理が共通する部分が多いため、Game_Map#ladder? の引数を変えることで、まとめて判定します。

これらのメソッドを、斜め移動の際に呼び出し、斜め移動禁止でないか判定します。Game_Character#move_lower_left に追加された処理を引用します:

    # ★斜め移動禁止地形の場合
    if $game_map.ladder?(@x, @y, @priority, true) or
       $game_map.ladder?(@x - 1, @y + 1, @priority, false) or
       $game_map.wellhole?(@x, @y + 1, @priority) or
       $game_map.wellhole?(@x - 1, @y, @priority) then
      return false unless @through
    end

こうすることによって、斜め移動禁止の地形で、斜め移動を行わせないことが可能です。

斜め移動が行えない場合通常移動を行うことが大事

さて。斜め移動を制限したわけですが、ここで移動の快適さのために重要なことがあります。それは、例えば「右上に動こうとして動けなかった場合、右か上に動ける場合、その方向に移動を行う」ということです。

すなわち、斜め移動が行えなくても、通常移動が可能なら、それをするということです。この考え方は、斜め移動禁止を導入しなくても重要ですが、斜め移動禁止を入れて制限を多くするなら、なおさら必要です。

なお、右上に動こうとして動けなかった場合で、右と上の両方に動ける場合はどちらに動けばいいのでしょう。どちらでもいいのでしょうが、僕は経験則から、上下の動きの方を優先しています。このあたりは、議論の余地があると思いますので皆さんも調整しながら考察するとよろしいでしょう。

これらの実装は、Game_Player#update の中に書かれていますので、興味のある方は解析してみてください。

結論:斜め移動で一番厄介なのは見た目の問題

斜め移動は常に見た目との戦いなのです。つまり、斜め移動を無くすか制限を強くすれば解決するのでしょうが、それではプレー時の爽快感が失われてしまいます。よって若干面倒でも、こだわっていきたい、そんな僕のこだわりをどうか皆さんも理解して欲しいのです。

なお、今回、斜め移動の見た目問題については、一番端的な部分を押さえたつもりですが、まだまだ、他にもあるように思えます。こういうのは、理屈ではなく見た目の問題なので、探すだけ見つかるでしょう。ぜひ、皆さんも、斜め移動を導入するときは、このような見た目の問題を意識してみてください。

移動速度(ダッシュの速度)

もう一つ小さなことですが、指摘しておきたいのは、移動速度の問題です。

RPGツクールXPの移動速度は、1〜6まで指定でき、数が大きいほど速いのです。プレイヤーのデフォルトの移動速度は4なのですが、これは少し遅く感じます。一方で5にすると、少し速く感じてしまいます。何とか、この中間が取れないものでしょうか。

本作では、ここをいじって、通常の移動速度を4と5の中間、低速ダッシュを5と6の中間、高速ダッシュを6の移動速度にしています。

実装

プレイヤーやイベントの移動速度については、Game_Character#update_move で、以下のように定義されています。

    # 移動速度からマップ座標系での移動距離に変換
    distance = 2 ** @move_speed

ここで @move_speed が1〜6の値を取るのです。1タイルは32ピクセルですが、これが論理座標で128の大きさになります。よって、例えば @move_speed が 6 なら、distance は2の6乗、すなわち64になり、2フレームで1タイルを移動する計算になります。@move_speed が5なら4フレーム、4なら8フレームです。

そこで、中間の速度を取るためには、3フレームや、6フレームで1タイル移動することを考えてやればいいのです。そこで、先程のコードの後に、以下を追加しています。

    # ★若干移動速度アップ
    if @move_speed == 4
      distance = 22
    elsif @move_speed == 5
      distance = 43
    end

これで、@move_speed が4の時、6フレームで、@move_speed が5の時、3フレームで1マス進むようになります。実際に計算すると進む座標の数は128より大きくなるように見えますが、多くなった部分は後の処理で丸められるので、問題ありません。

フレームレートをいじるよりも簡単な解決方法

ここで紹介した方法は、驚くほどシンプルに移動速度を変える方法です。

ツクールXPが出た当時は、内部フレームレートを通常の40fps から 60fps に変更することによって、移動速度を1.5倍にするという人が結構いました。CPUの性能が上がった今なら、それでも問題ないかもしれませんが、フレームレートを増やすということは、負荷を増やすということです。カクカクと処理落ちする人も多くなったのではないでしょうか。

移動速度のために処理落ちを増やすなんてナンセンスです。それよりは、こういうシンプルな方法がありますよ、ということです。

なお、この手法は、RGSS2(RPGツクールVX)以降でも比較的簡単に実装できます。

結論

以上、マップ関連のあれこれを見てきました。自分で読み返していて、つくづく地味なことやっているなあ、と痛感したのでありました。でも、僕は確信しています。本当に重要な技術は、レイアウトとか演出とかを派手にすることではなく、こういう縁の下の力持ち的な地味なものなんだ、ということを。

今回の紹介が皆さんの参考になれば幸いです。