GOREとにゃんこの桃源郷

主観的にCDのレビューやら、日記やら、色々と。
ゴアとかメタルとかロックとか

ツクールとVXとaceと狗の臓物を喰らう幼子たち

2021-02-06 | RPGツクールMZ,VXace,VX,2000,95,1~5
 RPGツクールVXaceデフォルトのタイルセットを利用しているうちに、期待通りの橋チップが無かった。今回はダンジョン製作中、スイッチを押すことで水辺に橋が架かるという、ありがちなギミックを作ろうとしていた。しかし、一度ダンジョンを廻った後、スイッチを押して橋を探す際、それだけで二度探索することになる懸念があった。スイッチを見付けることが遅れても、探索量が倍になることは避けたい。橋の架かるポイントに目印があれば、スイッチを押した後でも何処に変化が出たか、分かりやすいのではないだろうか。
 次に考えたのは、目印を何にするか。橋の影だけ表示しておく、あからさまな銅像や燭台を置いておく、看板に明記するなど。そうした中で、中途半端に架かっている橋が欲しいという結論に達した。壊れているというよりも、気持ちの上で吊り橋のようなイメージだ。もちろんデフォルトのチップセットには入っていないのだが、これくらいなら切り貼りするだけなので、自分で作れると思い立ったので、作ってみた。双方から架けても中央だけ無いようなタイプと、片側向けの短めタイプを作ったので、使えるようなら使ってみてはどうか。キャラチップ規格で作ったのでキャラチップとして使ってもいいし、マップチップに組み込んでもいいと思う。可能性はいつだって、無限大-無限大+1なのだから。

RPGツクールVXAce -統失ばりに飽きない-

2020-05-07 | RPGツクールMZ,VXace,VX,2000,95,1~5
 ハローハロー、ハロー。今宵もまたツクールをカチカチやってるユーザーのため、と言えなくも無い記事を俺は…。テクノゴアグラインダーからテキサコデスメタラー迄、幅広く活用を目指して。また、願わくば今更ツクールVXaceの素材やら何やらもう我武者羅に遮二無二増えるよう祈りを込めて此処に...。
 やれRGSSだ、やれスクリプトだ、そんなことを考えるのは最優先事項とは言えないという内容。デフォルトのイベントコマンドやデータベースの設定では難しい場合のとっておきにしておきたい。それはなるべく競合を避けるためでもあるし、古き良きツクールユーザーにとっての嗜みとも云えよう。一句、ツクールは 手洗いうがい 検温後。コロナ撲滅と在宅継続、つまり緊急事態宣言の撤廃は「しない、させない、したがわない」の3無い運動を求めよう。

 ここから本題。
⇒攻撃属性を付与するステートを作った。
⇒付与される属性がランダムで決まるように設定したい。

⇒「風」属性が付与されると、他属性の付与ステートが無効状態になる。
⇒各属性分、同様に付与される属性以外の付与が無効になるよう設定。
⇒ふよふようっせーおまえら。


⇒スキル画面で、ランダムで付与させたいステートを設定する。
⇒7個なら、大体20~30%程度に設定すると、一定くらいの割合になる。(体感)
⇒最後の1つは100%に設定する。何も付与されないのを防ぐため。

 これだけの設定で、データベースだけでも概ねランダムなステート付与が作れる。単純に、設定した上から順に付加判定を行っているので、最初の付与が成功(図の例だと21%的中)時点で、他の属性付与が全て失敗する。無効化なので失敗メッセージも出ない、だからユーザにはランダムに見えるという仕組み。付与項目の数により、各確率は変更が必要と思う。

・3人でクジを引きました。当たりは1本だけです。
 1人目が当たる確率と、3人目が当たる確率は違うでしょうか。

ルール:
 ・当たりが出たらそこで終了。
 ・各人引いたクジは箱に戻す。

 この設問では、どの人も3分の1の確率で当たりを引くことが可能。ただし、2人目は1人目が外れた場合、つまり3分の2の確率の後でしか挑戦できない。3人目に至っては、3分の2が2度続いて、初めて抽選の3分の1を抽選する機会が訪れる。
 数学が分からないのでどれくらいの確率にすれば正しいのか全然分からくて画像の通りに設定したのだが、有識者なら計算してほぼ等倍に出来るはず。出来ないことを嘆くよりも、出来る方法を考える人に成りたい、来世あたりで。シーユーネクストぐらいんどふぉーまざーふあっかー


RPGツクールVXAceのRGSS3

2020-05-05 | RPGツクールMZ,VXace,VX,2000,95,1~5
 毎度久方振りの投稿になると、編集画面のUI変遷についていけない。旧態然とした脳内これ如何に。さて置き、RPGツクールVXAceが未だ死んでいなかった。緊急事態宣言の発令に伴い、基本在宅勤務と化した現環境にて、これまでの通勤時間分が睡眠或いは自由時間に充当されており、大変有意義なことこの上ない。いずれコロナショックが落ち着く暁には、五月病発症のリスクは避けて通れそうもない。必要なのはマスクでも自粛でも無く、言わずもがな答えは明白だ。
 そう不幸中の幸いとばかりにツクール日和を満喫すること頻りだが、製作途中にまたしても落とし穴が発見された。洞窟のトラップではなく、スクリプトの穴というか仕様の穴というか、ただの競合か、俺には皆目見当も付かないが、ゴールデーンウィークを一部棒に振った甲斐あり修正出来たので此処に残す。順を追って説明したい性分なので、順を追って説明する。

■戦闘不能から復活する魔法
 ・成功率100%
 ・ステート解除率50%(復活できる確率)
 ・蘇生時のHP回復量は最大HPの10%

 イメージはドラクエシリーズの定番蘇生呪文ザオラルだ。半分の確率で復活できる反面、半分の確率で失敗してしまう。さらに、復活後のHPは最大でも無ければ1でもない。ツクールの仕様上、ただ蘇生だけを行わせる場合、HP1で復活する。つまり復活後のHPを1超にするためには、計算式蘭、あるいは効果蘭からHP回復の設定が別途必要となる。
 そうした魔法自体は初めから準備していたが、今回ツクールを再開するまで、試行する機会が訪れなかった。というのも、蘇生魔法を味方メンバーが習得するのがゲーム中盤、レベル15以上であり、これまでずっと序盤に感けていたことで、発見が遅れた。実際にテストプレイを行っていた折、とあるボスが即死攻撃を行ってくる。その直後、蘇生魔法を使用した際、味方は想定通りHP10%で蘇生した。それまでにも、自分で作っているゲームなので基本的に味方が殺されることは無いのだが、操作ミス、敵の調整ミスなどから死人が出たこともあった。序盤は蘇生を行ってくれる施設、今作では病院にお金を支払い蘇生させていたが、漸く最近は魔法で、しかも戦闘中に復活させることさえ可能になった。つまり複数回の蘇生機会があったからこそ気付けた穴、そう、ステート解除率が100%になっていた
 データベース上は無論、50%のままであり、概ね5回程度試したら1度くらいは失敗してもいい計算、体感上はもっと失敗するはずの計算である。ちなみに、この発見が遅れた要因は他にもある。毒を治癒する魔法にも、解除率50%程度のものがあるのだが、そちらは正常に動いており、序盤から失敗や成功を繰り返していた。このことから、データベース上の解除率を盲信したまま製作を進めていたということだ。差別用語的に言うなればめくらだ。映画的な観点から言えば盲獣だ。
 さて、何故データベース上で解除率が100%でもないのに、蘇生が100%成功していたのだろうか。みんなで幾つか考えてみよう。
 ・ステート解除の他に、HP回復の設定もされていたため。
 ・味方単体(戦闘不能)というスコープの仕様。
 原因は、どれでもいいし明確には分からない。とにかくこの現象に対する簡単な回避方法なら見付けた。ステート解除率は100%に設定するが、スキル自体の成功率を50%にすることで、想定通りの動き方になる。だが今回、成功率はあくまで100%にしておく必要があった。既に後半で習得するスキルとして、ドラクエで言うところの天使のうたと似たスキルを作成していたのだ。その効果は、自分以外で戦闘不能の味方全員を半分程度の確率で復活させるというものである。もしこのスキル自体が、100%の確率で蘇生させられる場合、あまりに強力なため使用に際しての制約を考慮する必要があるだろう。また、成功率を下げる方向で調整した場合、全員復活か誰も復活しないかのどちらかになり、ギャンブル性が強くなり過ぎる。このような理由から、別の解決方法を模索した次第だ。以下、変更したスクリプトを載せる。

 主な修正は、$game_battlerクラス内、2つのメソッドになる。上から順に説明する。
1.使用効果ステート解除
 チャンス(chance)という変数が、ステート解除率を示す。これはデフォルトで存在し、チャンス分からrand関数でステート解除するか抽選させている。今回の改変ではステート解除の抽選に外れた場合、成功結果(success)を否(false)と設定し、ステート解除を行うメソッド(remove_state)を呼び出さないようにした。

2.スキルまたはアイテムの効果適用
 かなり強引だが引数として受領しているスキルまたはアイテム情報(item)変数が持つ効果対象(scope)で処理内容を分岐させた。効果対象9が味方単体(戦闘不能)、効果対象10は味方全体(戦闘不能)に当たる。そうでない場合、つまり戦闘不能者用のスキル以外は通常の処理を行わせる。ここで気を付けたいのは、戦闘不能者用のスキルという呼び方をしたが、これは効果対象が戦闘不能に対する設定ということで、スキル使用時に戦闘不能メンバーを選択していることとは関係無い。仕様かどうか定かではないが、移動中と異なり戦闘中にスキル適当可否の判定は行われず、HP満タンの相手に回復魔法をかけることも、状態異常に掛かっていない仲間にステート解除魔法を掛けることも可能だ。初めはここも判定可否させようかとも考えたが、えげつない系のボス戦で先読み回復などの行動が出来たほうが良いと思い変更しなかった。
 閑話休題、上記で分岐した中では、項番1の使用効果ステート解除のメソッドを経由するための記述だけ先に記載する。その結果如何に応じて、成功結果(success)にtrueまたはfalseが入っている。これはステート解除確率の抽選が行われた結果だ。もし成功(true)が入っていた場合だけ、HP回復量を算出するメソッドと、実際にHP回復を行うメソッドを呼び出す。

 基本的にはこれだけの改変で、蘇生魔法はステート解除率に従って動いた。蘇生が失敗した場合、戦闘不能のままでHP回復も行わない。反対に蘇生が成功した場合は、戦闘不能から復活し、指定のHP量を回復させる。
 ところが、動きとしてそうなるだけで、別の問題がある。メッセージ表示が不可思議になる。蘇生失敗の表示ついては、「%sには効かなかった。」が出るため、あとはこだわりの問題だが、そのメッセージの前に「%sはダメージを受けていない。」が表示されて非常に違和感がある。これを解決するために、以下のメソッドについても手を加える必要がある。別クラスのため、敢えて画像を分けている。

 これに関しては非常にシンプルで、赤枠で囲った部分を追記するだけで済む。要はステート解除に成功した場合だけ、HPダメージに関するバトルログを表示させる、という内容だ。先に述べた改変方法により、成功結果(success)にfalseが入るのは蘇生失敗の時だけなので、おそらく競合は極力避けられたのではないかと思っている。思ってはいるが、そもそも詳しくないので分からない。だから今日も備にテストプレイをする。

 ところで、製作中のRPGの舞台が西川口で、ビデオポーカーの店が幾つか在る為、ポーカーゲームを作成した。ジョーカー無し、倍率が実際の確率と変わらないため、かなりシビアで基本的に稼げない仕様になっている。そのため難しい役を狙う必要は無く、保守プレイに終始するという遊び方になる。何故なら、役が出来た時点で、ダブルアップゲーム(ハイ&ロー)に挑戦できるようになっている。これをメインで稼ぐことが可能だ。要は原作であるところの西川口に可能な限り忠実に、ビデオポーカーで言うところの叩き台を再現している。割れがどうとか、複雑なものは作れないので、以前CUIでさんざん作ったハイ&ローにした。パチンコ作らずにポーカーだけ作成したのも、GUIでCPU対戦型のポーカーを作ったことに起因する。カードの強さを算出する部分を始め、かなりの処理が流用出来たので良かった。
 村人のセリフに関して、ほぼ通常ウインドウ1ページ分に収まる程度しか書かない俺が、久し振りに文字を沢山書いた。しかし筆不精というわけではなく、然るに大前提として不精ゆえのことだ。そう、あの緊急事態宣言を受け、在宅勤務が始まったのはその数日後だった。本日までに1日だけ、出社を余儀なくされたものの、その日以外、1度たりとも外出をしていない生粋の自粛人間である。ゴールデンウィークに安易に帰省した人が居るとすれば見倣うべき自粛と自負している。さて、これ以上の執筆は自粛して、またツクールに耽るとしよう。合言葉は、ともすれば!

RPGツクールVXAceが終わらないため素材投下。

2019-02-06 | RPGツクールMZ,VXace,VX,2000,95,1~5
 まだまだ終わらない。ダンジョンのナンバリングも32となった昨今、スイッチを操作して洞窟の岩を消滅させる仕掛けを作ろうとしたが、適当な素材が無かったので自作してみた。RPGツクールVXAceの改変素材という位置付けだが、なんということは無い、ただマップチップの岩をイベントで使い易いようにオブジェクト化しただけのことだ。



 必要という人が居れば是非とも使ったらいい。必要じゃない、という人が居れば、何とかして使ったらいい。どう使うかは自分で考えるものだ、何故ならツクールの可能性は無限大なのだから。


 それとは別に、敵の無意味行動やコモンイベント発動用、などのスキルを改めて練り直した。常々、戦闘テキストが表示されるが、特にアニメーションも設定していないとテキストが一瞬で消えてしまい読めない。これを逆手に取れば、アニメーションさえ設定されていれば、その表示が終わる間はテキスト表示中にウェイトが入るということだ。
 今回は何もフレーム数だけ任意の数にして、SEも何も設定しない”テキスト表示用の戦闘アニメーション”を拵えた。テキストがきちんと読める程度のフレーム数にして、無意味行動やコモンイベント「戦闘中断」等の戦闘スキルのアニメーションとして設定した。ただし効果範囲は使用者などの誰かにしておかないと、戦闘アニメーション自体が省略されるため意味が無い。
 さりとてこれだけでは、何か「ミス」だの「~には効かなかった」などの失敗表示が出てしまう。これを回避するため、今回の戦闘アニメのIDを、スクリプトに直接記入してしまう。Window_BattleLogのdisplay_action_results(target, item)の中、display_failure(target, item)という記述を下記の一行に変更する。
display_failure(target, item) if item.animation_id != 285
 この表記は、戦闘アニメーションIDが285以外の場合、失敗表示をさせる、という記述だ。つまり、戦闘アニメーションにID285番を設定しているスキルを使った場合は、効果無しでも失敗のメッセージを表示させないという意味だ。


 直接編集するのに抵抗がある場合は、▼素材の下に再定義でもいいと思う。行動結果表示を改変する素材は少なそうなので、競合も少ないほうだと思う。
class Window_BattleLog < Window_Selectable
#--------------------------------------------------------------------------
# ● 行動結果の表示(再定義)
#--------------------------------------------------------------------------
def display_action_results(target, item)
if target.result.used
last_line_number = line_number
display_critical(target, item)
display_damage(target, item)
display_affected_status(target, item)
display_failure(target, item) if item.animation_id != 285
wait if line_number > last_line_number
back_to(last_line_number)
end
end
end

 言うまでもないが、該当戦闘アニメーションがID180番だったらスクリプト上の数字285は180に変える。

RPGツクールVXAce~敵が次々出現の巻~

2019-01-23 | RPGツクールMZ,VXace,VX,2000,95,1~5
 また色々と頑張っている次第だ。今回は疑似的な「仲間呼び」、「復活」の時のバトルイベントを作った。

 バトルイベント上で、「ターン終了時」、タイミングは「ターン」にする。これで、ターン終了時(毎ターン)に一度だけ実行される。内容は、敵メンバー1が死亡している時、その敵を全回復させる、且つ、「~が現れた!」とメッセージを出力する。敵メンバーは今回4体なので、4体分同じように設定する。

 ありがちなイベントなのに何故わざわざ記事に起こすのか。それは、同じ敵キャラに付与されるA~Zの所謂レターも次のナンバリングが出るようにしたから。上の画像のように、スライムAが倒されるとスライムAが復活するのだが、名前がスライムEになる。もう一度スライムE(中身はスライムA)を倒すとスライムFとして復活するし、BやCでもG、H…と次のレターになるので、プレイヤーは復活ではなく出現したと思うに違いない。でも、経験値やゴールドまで増やすの面倒だから、該当の敵はどちらも0にしてしまった。これもやろうと思えば死亡時に変数に加算させて取得できる。ただしイベントコマンドじゃないほうのスクリプト上、経験値やゴールドの取得数のとこに+$game_variables[??]みたいに書き込む必要がある。

 実際の作り方1.変数初期化のためのイベントを戦闘開始時に設定。画像では変数11を敵を倒した実数とし、変数12を敵に付くレター用のカウントにしている。初期値を3にしているのは、最初に出現する敵が4匹のため。
※バトルメンバーのカウントは1~ではなく0~になるため、0,1,2,3で初期値を3にしている。
ちなみに敵のレター情報はそのまま取得することが出来ないので、変数88に直接代入した。$game_troopの頭のほうに載っているのでコピペ。半角と全角の2種類あるのは、日本語用と英語用で分けているため。
また、敵を倒す度に1加算する変数11と12で分けているのは、レターZまで行った後に出現させる敵をAに戻るため。


バトルイベント2ページ目、実際のイベント内容を上から説明。
変数11が22以下の時だけ実行。⇒敵23体以降は復活しない(出現させない)。
変数13はイベント開始時に変数11(倒した数)代入して、イベントの最後で値が一致しない時、出現したと判断させ「~が出現した!」とメッセージ表示させるために利用。スイッチでも可。
1.スライムが死亡⇒敵1のスライムが死亡している場合の処理。
変数11と変数12それぞれ1加算し、敵1を全回復させる。
スクリプト:変数88をvとし、トループメンバーをtとする⇒イベントコマンドのスクリプトは文字数制限が厳しいため、グローバル変数はこうして文字数の省略を図っているだけ。
変数12が25を超えている(26以上)時、変数12は0にする。※今回は敵倒したのが22以下の時だけ実行されるように条件分岐したので実際はこの命令が実行されることは無いが、もし26体以上まで戦闘を続けさせたいなら必要。
最後に、$game_troop.members[0].letterを、変数88のレター情報から変数12番目のものに変更する。スライム2ならt[1]、3ならt[2]になる。

最後に、インスタントやローカルではない実際の変数($game_variable)に配列を入れる場合の注意。配列以外でも、数値以外の時は同様に注意。同じ変数をマップイベントの実行条件として設定していると、数値以外のものが入っているということでエラーが出る。マップの情報は、そのマップに進入した段階で、そのマップ上の全イベント含め情報が読み込まれる。よって、マップ進入した瞬間にイベント開始条件が不正というエラーになる。なので数値以外で使う時は使用後に適宜0を代入するなりしてリセットしておくと安心。とはいえ、イベントの開始条件に利用しなければ何も起きないので気にしなくても平気。

お疲れ~。


 やっぱり、せっかく敵倒して何も無しは侘しさが募るので、経験値とゴールドも追加されるようにした。
・Scene_Battle開始処理や終了処理などどこでもいいので該当変数に0が代入されるようにする。
・敵が出現するタイミングで$game_variables[107] += $game_troop.members[0].expと
$game_variables[108] += $game_troop.members[0].goldを追加。
※出現と同時に加算されるので、敵が逃げてもこの分だけ増えるので逃げない敵専用。

$game_troop内のスクリプトを変更。
#--------------------------------------------------------------------------
# ● 経験値の合計計算
#--------------------------------------------------------------------------
def exp_total
dead_members.inject(0) {|r, enemy| r += enemy.exp } + $game_variables[107]
end
#--------------------------------------------------------------------------
# ● お金の合計計算
#--------------------------------------------------------------------------
def gold_total
dead_members.inject(0) {|r, enemy| r += enemy.gold } * gold_rate + $game_variables[108]
end

RPGツクールVXAceは死なない。

2019-01-03 | RPGツクールMZ,VXace,VX,2000,95,1~5
 久し振りに再開し、また特に意味の無いものを、長時間費やして作った。画像でよく分からないかと思うが、複数人を同時に押すというだけのシステムだ。
 まず人に当たると、プレイヤーの向きに合わせて、1マス隣を確認。
⇒イベント無し、且つ移動可能タイルの場合、このイベントは隣へ移動する。
⇒イベント有りの場合は更に1マス隣も確認。
⇒イベント無しだが移動不可能タイルの場合、「もう無理ー。」と言われ移動しない。
 ⇒⇒イベント無し、且つ移動可能タイルの場合、このイベントと、隣接したイベントどちらも移動する。
 ⇒⇒イベント有りの場合は更に1マス隣も確認。
 ⇒⇒イベント無しだが移動不可能タイルの場合、最も先のタイルに居る人だけジャンプして「もう無理ー。」と言い誰も移動しない。


 変数メインで書いたため、何人だろうと押せると思うが、画面のマス数によりジャンプが見えなくなるため、なるべく狭いマップで使用したい。また、コモンイベント1つで収まったので、イベント自体はコモン呼び出しを設定するだけで機能する。
・イベントコマンド 現在座標(変数)のxに、このイベントのマップXを入れる。
・イベントコマンド 現在座標(変数)のyに、このイベントのマップYを入れる。
・イベントコマンド 移動先座標(変数)のxに、このイベントのマップXを入れる。
・イベントコマンド 移動先座標(変数)のyに、このイベントのマップYを入れる。
・条件分岐 プレイヤーの向き。
・向き下⇒移動先座標yを加算1する。 向き上⇒減算1する。
・向き左⇒移動先座標xを減算1する。 向き右⇒加算1する。
・イベントコマンド 指定座標の情報取得でイベントID⇒移動先xと移動先yの変数で指定。
・条件分岐 指定座標のイベントIDが1以上。
 ※設定されたマップイベントはID1から始まるため、1以上=マップイベント。
・1以上の場合、適当な変数に加算1する。(直線上に何人いるかここでカウントしている)
・1未満の場合、同じ座標の情報取得でリージョンIDを取得。
・リージョン1なら移動可として、移動処理にラベルジャンプ。
 ※通行可否判定(passable?)で入り口に入られても困るためリージョンにした。



 実際の移動の設定は、さっきと逆順で対象座標のイベントIDを取得しながら行う。先にイベント末端の座標が移動可能か判定し、移動出来ない場所だったら、最後に取得したイベントIDでキャラクターをジャンプさせ(やり方は後述)処理を中断する。移動可能な場合、プレイヤーの向きに応じてx或いはyを加減し、イベントIDを取得したら移動させ、移動されたら必ず人数カウントの変数を減算1する。これが0になったら、プレイヤーと当たったイベントを移動させて終わり。
 最後に、当たった対象ではない、イベントIDを取得しただけのイベントを動かす方法。イベントコマンドのスクリプトで入力。

v = $game_variables;r = RPG::MoveRoute.new
c = RPG::MoveCommand
r.repeat = false;r.skippable = false;r.wait = true
r.list = []
r.list.push(c.new(29,[5]))
r.list.push(c.new(37),c.new(2),c.new(38))
r.list.push(c.new(29,[4]),c.new)
cha = get_character(v[13])
cha.force_move_route(r)
if r.wait
Fiber.yield while cha.move_route_forcing
end

※長い部分はアルファベット一文字に省略している。通常の移動ルート設定と同様に、繰り返し、移動出来ない場合スキップ、移動完了までウェイト、の設定が必要。次に空の配列を準備。コマンドはスクリプトエディタで$Game_Characterの定数、に書いてある。配列への追加は複数まとめて可能だし、別けても大丈夫。イベントのスクリプト欄はこれでも限界に近いため、複雑な移動には不向き。以上、正月から何やってんだ俺は、のコーナーおしまい。。

RPGツクールVXAceですごろく!

2015-06-30 | RPGツクールMZ,VXace,VX,2000,95,1~5


 1年振り、それとも2年だろうか。かなりご無沙汰していたが、また「RPGツクールVXAce」を更新した。今回作成したのは「すごろく」だ。内容的には、ドラクエ3(SFC)及びドラクエ5(PS2)のすごろくと、いただきストリート・ゴージャスキング(PS)のすごろくを、足して2で割ったようなイメージだ。システムは殆ど、以前RPGツクール2000で作成したものの焼き直しとなる。参考までに、その時の記事はコチラだ。つまりこのすごろくは、サイト「気紛れな空間」様の「すごろく作成講座」が根幹として在り、それをドラクエ的にアレンジし、さらに今回VXAce用にアレンジしたというわけだ。ついでに、以前は無かったすごろくアイテムという要素も取り入れた。ここが、いたスト風と思しき所以である。

 仕様としては、完全1人用のすごろくだ。何かボタンを押すと、「サイコロを振る、設定、リタイア」の項目が出るので、サイコロを振ってゴールを目指し進んでいく。ゴールした時に所持していた金額(すごろく所持金)が賞金となる。そのまま賞金とするか規定の賞金額から差し引きさせるか、細部は思案中である。
 開始時に、すごろく戦士、僧侶、盗賊、魔術士の4種類から、任意の職業を選択する。職業により特性があり、戦闘マスや地形を調べた際のランダムエンカウント時に、戦い方が変わる。どの職業でも、MPを消費して放つ特技、或いは魔法を1つだけ持っている。戦士なら通常攻撃の2倍のダメージを与える攻撃、僧侶はHP回復、盗賊は数ターンだけ自身の回避率を70%上昇させる技、魔術士は魔法攻撃で戦士の2倍攻撃と同等かそれ以上のダメージを与えられる。ただし、魔術士だけ物理攻撃力が他の職業の半分しかないため、MPが切れることが死活問題となる。
 また、何かアイテムを入手した場合、画面右上の所持アイテムの箇所にアイテム名が表示され、先程の項目にも、「アイテムを使う」が追加される。アイテムは任意で使用するもの、所持していると自動で使われるもの、マイナス効果のあるものなど、合計27種類作成した。任意での使用が不可能なアイテムでも、アイテムを使うを選択すれば説明が出るようになっている。



 たとえば、上の画像がアイテム「お金ヘラーズ」が発動した瞬間のもの。このアイテムを所持していると、お金が減るマスに止まった時に、お金が減るのを防いでくれる。発動すると無くなる。また、好きなタイミングで使用することは出来ず、該当マスに止まると必ず発動する。
 似たような効果のものに、ぬかるみマスの効果を防ぐ「ぬかるみガード」、サイコロの残り回数が減らない「サイコロヘラーヌ」、溶岩マスでダメージを受けない「マグマガード」、HP減少マスとMP減少マスをどちらも防ぐ「ショックガード」などがある。
 逆に任意で使用可能なアイテムは、出したい目が出せる各種サイコロ「1の目サイコロ」など、HPを回復する「すごろくやくそう」、所持金を倍にする「ゼニバイン」などがある。
 最後にマイナスアイテムについて。お金が減るマスの効果を倍にしてしまう「蛇口ガマグチ」や、所持している間ずっと、歩いた分だけお金が減る「破れガマグチ」、宿屋と道具屋が利用できなくなる「くさいモノ」などがある。これらがマイナスアイテムとして問題無く機能させるために、拾ったアイテムを捨てることは不可能となっている。また、アイテムは常に1つしか所持できない。既に何かしらのアイテムを所持している場合のみ、新しく取得したものと既に所持しているもののどちらを残すか選べる。たとえば、先に紹介したマイナスアイテムのうち「破れガマグチ」は、消耗しないため、拾ってしまった場合はなるべく早く別のアイテムを取得したほうがいい。
 アイテム自体はツボのマスから手に入る他、森や山地を調べるとたまに拾えたり、戦闘後に敵が落とすこともある。道具屋ではお金を払って購入することも可能だ。つまり、運次第ではあるが割りと簡単に手に入る。



 この画像が、現在作成したすごろく用のマス全てだ。まず左上に並んでいるのが強制的に進ませるマス、下段が強制的に戻されるマス。進むマスの右のサイコロは、サイコロを振って出目の数だけサイコロの残り回数を増やしてくれるマス。その右が宿屋、下段は道具屋だ。
 中央部の上段には、転職マス、回復の井戸マス、戦闘マス、ワープマス、階段2上下、ぬかるみマス、溶岩マスがある。その下はMP減少マス、HP減少マス、ツボマス、空白3箇所、森マス、山地マスが並ぶ。
 サイコロの増減マスとお金の増減マスについては、絵柄で一目瞭然だろう。その横の疑問符と感嘆符があるマスについては、これぞドラクエ式すごろくからそのまま引用している(画像は自分でWin標準のペイント機能を用いて作成)イベントマスとパラメータ変化マスだ。その横が、荒地、砂漠、骨、草原となり、金色の像に関しては、貧乏神マスというものを作った。所持アイテムがあろうが無かろうが、止まると強制的にマイナスアイテムを押し付けられる、という迷惑なマスだ。
 さて、他の特殊なマスと地形マスについて説明する。もし自身ですごろくを作る際に、どのようなマスが考えられるかの参考にされたし。
・転職マス⇒すごろく戦士、すごろく僧侶、すごろく盗賊、すごろく魔術士の中から、好きな職業に転職できる。レベルは引き継がれるが、イベントで増減した能力値はリセットされる。
・回復の井戸マス⇒HPとMPを全回復できる。ただし、マイナスアイテムである「みずいらず」を所持している場合、利用できない。
・戦闘マス⇒強制的に戦闘に突入する。地形マスでのランダムエンカウントよりも、強い敵が出易くなっているが、逃げることも可能。戦闘用アイテム「ダメージハーフ」は、その戦闘中に受けるダメージを半分にする。そして「攻撃プラスワン」は、通常攻撃が2回(実質2倍ダメージ)になる。どちらも所持していれば、戦闘開始時点で使用するかを問われる。
・ワープマス⇒近くのワープマスまで強制的にワープさせられる。場所によってはワープで先に進む場合もある。マス上で止まらないと効果は発揮されない。
・ぬかるみマス⇒次に振るサイコロの出目が、半分(1~3のいずれか)になってしまう。「ぬかるみガード」があれば効果を防げる。
・溶岩マス⇒自身のレベルに応じたダメージを受ける。レベル4までは2ダメージだけ。「マグマガード」でダメージ受けず、このアイテムは発動しても消耗しない。
・森、山地、荒地、砂漠、草原マス⇒所謂、地形マス。足元を調べるか選択可能。結果は、何も無い、お金が拾える、戦闘が起きる、アイテムが拾えるなど。草原は何も無いことが多く、お金が拾える額も少ない。森は何も無いことが少ない。山地は、戦闘とアイテムが多いが、マイナスアイテムが出ることもある。荒地は、草原とほぼ同じ。砂漠は、調べることでぬかるみマスと同じ効果を受けてしまう可能性がある。
・イベントマス(?マス)⇒様々なことが起きるが、何が起こるかは完全にランダム。キャラグラが変化することもあるし、所持金が倍になることもある。
・能力変化マス(!マス)⇒サイコロを3回振る。1回目のサイコロで、最大HP、最大MP、攻撃力、防御力、魔法防御、素早さのどのパラメータに効果を示すか抽選。2回目のサイコロで変動するポイントを最低1、最大6抽選。3回目のサイコロが4以上なら上昇、3以下なら下降となる。
・骨マス⇒ランダムで、何も起こらない、MP全快、アイテム入手または消失(アイテムに関しては未所持なら確実に入手、所持していれば確実に消失)というよくわからないマスになった。本来はゲーム本編中で利用できる素材アイテムを手に入れられるマスにしたかったのだが、本編を有利に進めるためにすごろくを強いられる事態になりかねないと危惧し、現在の仕様にした。
・貧乏神マス⇒マイナスアイテムを押し付けられる。すでに所持しているアイテムは失われる。

 よくある「振り出しへ戻る」や、「落とし穴(はじきバネ)」などのマスを、まだ拵えていない。それは今回作ったのが「無限すごろく」というテーマのためである。無限と銘打っているが、実際は無限に続くわけではない。とはいえ、サイコロを100回振ってもまったくゴールの見えない「まるで終わりの無い回廊に迷い込んだ」ような雰囲気にしたかったため、無限すごろくとした。
 これは実際にテストプレイしてみて思ったことだが、無限すごろくは精神的に疲弊する。また、一度の挑戦失敗で再スタートをする気になれない。何故なら、たとえばサイコロを200回振った地点まで戻るため、また200回のサイコロを振ることに気が滅入る。さらに、途中セーブが出来るわけでもない為、一回の挑戦に時間がかかりすぎることが問題だ。
 以上のことから、やはり難易度の違う複数のマップを作り、マップの難易度に合わせて景品を豪華にする仕様が、月並だが結局は一番良いのかという結論に達した。とは言え、途中までにしろかなり作成してしまったため、まずは今回の無限すごろくマップを完成させてから、他のマップに取り掛かろうと考えている。どれくらいまで作成したのかについては、次の画像を見てほしい。



 310×150のマップに、ほとんどびっしり敷き詰めたタイル。分岐あり、ワープありの凝ったマップだ。無限と謳っているのに、ゴールが見えては興醒めなので、敢えて「マップを見る」という機能は排除している。もしそれを取り入れるのであれば、作り方は簡単。プレイヤーの座標、向きを取得して同じ場所に同じグラフィックのキャラを表示させ、プレイヤーの透明可とすり抜けを設定すれば、自由にマップの移動が可能になる。更に、スイッチで並列処理イベントを起動させ、キャンセルキーなどが押された場合に設定を戻せばいい。はず(まだ作っていないため未検証)だ。

 さて、久し振りに長い記事を書こうと思い立った今回の内容は、いよいよイベントの作り方などに触れていく。何かの参考にされたし。途中でツクール2000に有ったがVXAceでは削除されてしまった、イベントの呼び出しを使うため、それが可能になるスクリプト素材を導入しておく必要もある。無くても可能だが、あると格段にイベント作成の手間が少なくて済む。分岐とワープの処理に関して、毎回使うため、非常に重宝する。
[01]スクリプトエディタ(イベントコマンドのスクリプトではない)で、サイコロの残り回数など表示するウィンドウを作ります。既存のWindow_Goldをコピペして改変すると楽です。initializeのfitting_height(1)という部分で、このウィンドウが何行分のものか指定します。例えば、この記事の画像と同様に表示させるには3行必要なため、カッコ内は3にします。HPを表示させるdraw_textには$game_party.members[0].hpでいいと思います。イベントコマンドのスクリプトでも、この取得方法で構いません。

[02]すごろく開始時の自動実行イベントを作る。基本的に任意ですが、プレイヤーの向きは変数に入れておくといいでしょう。また、イベントコマンドのスクリプトで、$window = Window_Sycoro.newと入力します。これは、01番の工程で用意したウィンドウを表示させるためのものです。私の場合は、Window_Sycoroという名称にしたため、このようになっています。それから、すごろく開始のスイッチをonにします。

[03]すごろく開始のスイッチがonになった場合のイベントを、先のイベントの次ページに作成します。これも自動実行です。ラベル「入力待ち」を作ります。次に条件分岐のスクリプトで、Input.trigger?(:A) or Input.trigger?(:B)、などを作ります。この条件に適合した際のイベントは、ラベルジャンプ「メニュー選択」です。次にウェイトを1フレームだけ入れ、ラベルジャンプ「入力待ち」、さらにラベル「メニュー選択」を作ります。
※解説:こうイベントを組む事で、AボタンまたはBボタンが押されたときはメニュー選択(これから作成する)に飛び、押されない限りは画面上何も起きない、という挙動になります。

[04]主人公の座標などを各変数に代入しておきます。次に「すごろくアイテム」という変数を用意し、これが0ではない場合と、条件に当てはまらない場合とで分岐させます。該当の場合、選択肢の表示で、サイコロを振る、アイテムを使う、設定、リタイアです。該当しない場合は上記から、アイテムを使うだけを削った選択肢にします。
※解説:すごろくアイテムという変数で、アイテムを所持しているか判定します。つまり、データベースのアイテム欄は利用しません。変数0ならアイテム無しと見なします。変数が1なら○○を所持中、2なら××、というように設定します。マイナスアイテムだけ番号を離しておくと後の設定で楽になる部分があります。使用可能アイテムと自動発動アイテムは混在していても自分で覚えていさえすればいいです。

[05]先程の選択肢から、サイコロを振るはラベルジャンプ「サイコロを振る」、アイテムを使うは変数すごろくアイテムの数値ごとに条件分岐を入れ、それぞれアイテムの説明メッセージを入れて、任意使用が可能なアイテムならば「使いますか?」と選択肢はい、いいえ、で分岐させます。たとえば次のサイコロが必ず5になるアイテムを使う場合のイベントを書きます。アニメーションの表示(何か相応しいものを任意で)、スイッチ操作「出目操作済み」on、変数「サイコロの出目」に5を代入、変数「すごろくアイテム」に0を代入、スクリプト「$window.refresh」。
※解説:今回私はほぼラベルとラベルジャンプを利用してイベントを組んだのですが、作り終わってみると実行内容が非常に長くなり、修正箇所などを探すために注釈を挿入していても時間がかかったため、動作ごとにコモンイベントにして分けたほうが良いかもしれません。さて、出目操作済みのスイッチは出目を指定する時に毎回onにして、後に作るサイコロを振るイベントの際に分岐で使います。また、最後の$window.refreshは、工程01で作成した自作ウィンドウを更新する場合は毎回入れます。何故ならこのウィンドウは、自動的に更新させる命令が無いため、スクリプトで更新命令を都度出してやらないと、情報の書き換えが行われないのです。

[06]すごろくアイテム毎の条件分岐は最後に、ラベルジャンプ「メニュー選択」を入れます。

[07]メニュー選択時の条件分岐の設定には、任意の設定を作ってください。同じく条件分岐リタイアは、すごろくを途中で止める場合の設定を作ります。必要に応じて変数をリセットしたり、任意で結構ですが、スクリプトで「$window.dispose」と「$window = nil」の命令を何処かに入れます。
※解説:最後のスクリプトコマンドで入力する命令は、自作ウィンドウの解放と消去です。これを入れ忘れると、いつまでもウインドウが出続けます。

[08]メニュー選択の分岐の後、ラベル「サイコロを振る」を作ります。ここがサイコロを振る際の処理です。まず変数「サイコロの残り回数」を減算1して$window.refreshを入れます。次にサイコロが何回、回転するのかを変数に代入します。絵が描ける人なら、回転に関しては戦闘アニメーションとして作成すると、見映えが良いと思います。条件分岐のスイッチで出目操作済みがoffの場合に限り、サイコロの出目に乱数1~6を代入します。この後は、特にオリジナルのものではないため、省きます。
※解説:出目操作済みがonの場合にもサイコロの出目を指定すると、操作が無効になるため、offの場合だけにします。

 これ以降は先に紹介したサイトを参考にした方が良いため、具体的な処理については大幅に省きます。

[09]サイコロが回転した後に、条件分岐でスイッチ「ぬかるみ」がonの場合に、サイコロの出目を2で除算する処理を入れました。ただし、入れ子にした条件分岐、サイコロの出目が2以上の場合に限ります。除算した後は各サイコロピクチャを非表示にし、最終的な出目に応じたピクチャを出します。この処理も済んだら、スイッチの出目操作済みとぬかるみ、どちらもoffにします。
※解説:最終的なサイコロの出目は任意の別の変数にも代入しておきます。そうしておけば、移動直後にキャンセルを可能にする時、利用できます。(例、このマスに止まりますか?→はい、いいえ)

[10]移動開始の処理です。ラベル「移動開始」を設定します。また、移動前のプレイヤーの座標から、上下左右2マスずつの地点に、何が存在するかを調べます。ただし、プレイヤーの向きと逆方向に限り、そもそも進むことが出来ないようにするため、除外します。予め、すごろく用マップの各タイル、左上のマスにだけ地形タグ1を設定しておきます。地形タグ1且つそこがプレイヤーの向きの逆方向でない場合、移動可能を判定するためのスイッチをonにします。また、変数の分岐数に1を加算します。
※解説:地形タグで何のマスか判定できれば便利ですが、タグの数が圧倒的に足りない(7まで)ため、「すごろくのタイルか?」を判定すること限定で利用します。ちなみにプレイヤーの向きには変数、2,4,6,8のいずれかが入ります。キーボードにテンキーがある人は、それを見ると簡単です。そう、2なら下、4なら左、というように、数字と方向が一致します。最後の分岐数は、進める方向がいくつあるかを数えるためのものです。

[11]工程10の結果、変数の分岐数が2以上(進める方向が1箇所ではなかった)の時に、分岐点の処理を入れます。細かい作り方は省きます。現在地のイベントIDを調べて、イベントが存在しなければダミーイベント(空のイベント)番号を変数に入れます。マスとしては複数の移動可能な方向が存在しても、都合によりそのマスから進ませたくない方向がある場合に、該当の移動可能スイッチをoffにする処理が必要です。現在地に対するイベントの呼び出しで対処します。結果的にやはり進行可能な分岐がある場合、どちらに進むことが可能かをプレイヤーに教えるための画像を表示します。
※解説:ワープマスに関してもそうですが、該当マスのイベントを発生させる(イベント呼び出しを行う)場合、直前に任意のスイッチを入れ、そのスイッチがonの時だけ、イベントの中身が実行されるようにします。VXAceでは、デフォルトでマップイベントの呼び出し機能が無いため、トリガーに「開始しない」がありません。接触やキー入力でマップイベントが実行されると不都合が生じる場合があるため、スイッチを設定します。

[12]移動可能な進行方向のキーが入力された場合、移動ルートの設定でプレイヤーの移動(ウェイト)、すり抜けon、歩くSE、(下に移動するのであれば)下に移動を2回、すり抜けと向きという流れにしました。○歩戻る、という戻るマスのために、戻るマス用スイッチがonの場合には、すり抜けの他に向き固定をonにしています。また、移動するたびにサイコロのピクチャを出目が1つ少ないものに変更します。そしてサイコロの出目が1以上である限り、移動する度に移動開始の処理に戻らせます。
※解説:移動開始の処理(工程10)からこの工程までは、一連の流れになるため、移動するマス(サイコロの出目)の分だけ繰り返します。マスを進むたびに、ラベルジャンプでラベル「移動開始」に飛ばします。移動可能な方向を調べる→分岐について確認する→出目1つぶん移動させる、の流れです。

[13]メニューで設定の確認機能をonにしている場合のみの分岐処理です。このマスに止まらないという選択をした際、サイコロを振り終えた時点まで戻さなくてはなりません。画面フェードアウト、予め記憶しておいたプレイヤーの場所へ移動、サイコロの出目に元の出目を代入(工程09の解説参照)、前回の向きによってプレイヤーの向きを移動ルートで指定、サイコロのピクチャを元の出目数に則ったピクチャにして画面をフェードイン、移動開始の時点にラベルジャンプ。
※解説:1マスずつ戻れるようにするより、このやり方のほうが作成する手間がかからないため、こうしています。前回の向きに関しては、サイコロを振る際に設定しておきます。

[14]出目の数だけ移動させたら、現在の向きを変数に入れておき、戻るマス用スイッチをoffにします。

[15]ようやくマスの効果を発動させるためのイベント処理です。現在のプレイヤー座標(出目の分だけ進めてたどり着いたマス)を変数に格納します。その座標の「タイルID」を任意の変数に取得させます。タイルIDによって、それが何のマスか判別するため、マスの分だけそれぞれ条件分岐を設定し、何が起こるか設定します。
※解説:タイルIDはコンソールで調べてもいいですが、何か別ですごろく用のマスを敷き詰めたマップを作成し、調査に必要な箇所にイベントを設定して、1つずつ調べるほうが分かり易いです。座標代入→情報取得→メッセージ表示で該当変数の値を出力(\V[100]など)させる。ちなみに調べるタイルIDのレイヤーは、今回タイルセットEにすごろく用マップチップを導入しているため、レイヤー3のみ調査します。他のレイヤーは使用しません。

[16]各マスの効果を設定した後に、条件分岐で死亡した場合の処理を作ります。まず復活だけさせて、挑戦失敗に関するアナウンスなど、何かしら任意で作成したらいいと思います。


 すごろくも然ることながら、この記事を書くことも疲れた次第だ。これを書く時間があるのであれば、サンプルプロジェクトを作れたかもしれなかったとさえ思う。(いや、とりあえず動く、だけの組み方だとサンプルとして不適切なので俺には出来ない気もする)何にしても明日から忙しいため、結局、落とし穴など色々な要素が作れないまま終わってしまい不完全燃焼だ。もっと趣味に没頭できる時間が欲しいものだ。世紀単位で。

2014/06/02 - 脳漿仕立てのぽたぽた焼き

2014-06-02 | RPGツクールMZ,VXace,VX,2000,95,1~5
 またしてもRPGツクールVXace、またしてもミニゲームの制作。画像左は「ぶっこわし屋」と題したミニゲームで、箱、ツボ、タル、テーブル、イス、石版を壊すことで点数を稼ぐという、ストレス社会を象徴するかのような内容。これらは、デフォルトで破壊チップが入っていることから選抜された。ただ物に向かって決定キーを押せば、プレイヤーが物に突進し、高確率で物が半壊状態となる。半壊状態の時にもう一度叩くと、完全に破壊され、グラフィックは消える。1つのコモンイベントと、2つのセルフスイッチを使っただけの、シンプルな破壊活動だ。ただ、これだけではゲーム性が薄いため、各所に倉庫番と称してロボットを徘徊させた。このロボットを破壊することは不可能で、触れると1マス吹き飛ばされてしまう。制限時間があるため、ロボットの動きを気にしていないと、出入り口で邪魔されるため、思い掛けないタイムロスが発生する。
 さて、物が多いと、一度入れたセルフスイッチをリセットさせるのは手間だろう。そこで、イベントスクリプトで一発解決を提案したい。特にこのミニゲームは140個以上も物を置いたため、一つずつ解除させるのは残酷絵巻き級だ。
i = 1
loop do
$game_self_switches[[68,i,"A"]] = false
$game_self_switches[[68,i,"B"]] = false
i += 1
break if i == 142
end

 そんな悩みは、上記イベントコマンドのスクリプトで瞬時に解消する。イベントID1番~141番のセルフスイッチA及びBを、このたった7行のスクリプトが実行してくれる。ループによる変数やスイッチの操作は、至るところで活躍する機会があるため、大変おすすめ。
  
 続いて画像右側は、音ゲーっぽいミニゲームで「ゴーストバスター」と名付けた。それぞれの魔方陣に、ランダムでゴーストが湧く。左側の魔方陣は方向キー、右側の魔方陣は各種ボタン(A,B,C,X)に対応している。ボタンを押すと、そのボタンに対応した魔方陣が、画像のように光りを発する。その光でゴーストを包むと、音が鳴り、ゴーストを浄化させることが出来る。「押しっぱなし」を避けるために、条件分岐のコマンドには「Input.trigger?」が適切。それでも、全ボタン連打で簡単にゴーストを退治できてしまうため、ボタンが押される度に「押した回数」を加算し、ゲーム終了時に押した回数に応じて得点から減算する。しかし、普段リズムゲーをやらないため、コンボ機能を搭載し忘れてしまった。それを失念したまま、4ステージと難易度4種類を拵えてしまったので、これから入れるのは大変面倒臭い。だからこれで完成とした。
 ちなみにこれに関しての、戦闘アニメーションを利用するちょっとした小技を紹介。戦闘アニメを表示させたい場所に、空のイベントを置けば、その地点に表示できる。普通はX,Y座標による指定が不可能だが、戦闘アニメ表示用のイベントを作り、それをイベントの位置設定で任意の場所に配置すれば、画面上好きな場所に表示させることが出来るという寸法だ。

 とにかく本編が飽きというかスランプというかネタ切れのため、どうもミニゲームを考えるか吉本新喜劇を観るか懐かしのたにツク動画を観るか初代熱血硬派くにおくんをやるかキッズタイムにドラクエ10をやるかくらいしかない。このままだと、長編RPGの予定が、「ツクールで作るちょっとしたミニゲーム詰め合わせ」になってしまう。お子さんの誕生日プレゼントにぜひ。

2014/05/31 - 硫酸による腸内洗浄

2014-05-31 | RPGツクールMZ,VXace,VX,2000,95,1~5

 相変わらず、RPGツクールVXAceをちまちま作業。さすがに近頃飽き始め、昨日は気分転換に本編と関係無い(シナリオ上必須でない)シューティングのミニゲームを作った。シューティングと言っても、イベントコマンドで組んだちょっとしたもので、所謂スクリプトを用いるような弾幕系や、ステージクリア型のものではない。たとえ頑張って作るとしても、俺自身が全くシューティングゲームをやらない(RPGとシミュレーション以外に興味が無い)ため、テストプレイが不可能になる。ゆえにこれは、射的ゲームだ。イメージとしては、昔よくゲームセンターなどに置いてあった、西部劇を意識した射的で、悪人のパネルが出てきたらそれを撃ち、たまに市民のパネルも起き上がるが、それを撃つと得点がマイナスされる、といった懐かしいもの。だから敵は動かないし、攻撃してくることもない。一応、画面下部に得点と自己ベストを表示させることにした。やはり、目に見えて得点が推移するほうが、やる気が出るというもの。今回の射的においては、弾丸は同時に3発まで、パネルも最大3枚まで同時に現れる。つまりイベントに関しても、弾丸3つとパネル(敵あるいは市民)3つは必須となる。こんなふうに作ったので、よかったら以下の作り方をどうぞ。(ネット上にもっと効率のいい組み方なり講座なりあると思うけどね)

!!下準備!!
まず必要な数だけ空のイベントを作成。名称は【イニシャライズ(自動実行)】【射的弾丸管理(並列処理)】【射的タゲ管理(並列処理)】【弾丸1(並列処理)】【弾丸2(並列処理)】【弾丸3(並列処理)】【ターゲットA(決定ボタン)】【ターゲットB(決定ボタン)】【ターゲットA(決定ボタン)】今回はこれだけ。細かく処理を分ける理由は、こちらで管理し易くするためだけなので、必須ではない。ちなみに弾丸は全てすり抜け属性を指定。

!!イニシャライズ!!
マップに入った時、【自動実行】のイベントを作る。メニュー禁止にしたり、主人公の向きを固定したりした後、【射的スタート】のスイッチを入れ、イベント一時消去。このミニゲームでは、主人公の移動速度を2倍にした。あと、忘れてはならないのがタイマーの開始。1~3分くらいが丁度良さそうに思うが適宜。カウントが早いほうが臨場感があるため、個人的にはスクリプトを弄ってカウントを6倍速にした。

!!射的弾丸管理!!
【射的スタート】のスイッチが入ると、並列処理イベントの【射的弾丸管理】が始動する。まずプレイヤーのX座標とY座標を取得する。そして発射ボタン(今回はBボタン)が押されている状態という【条件分岐】を作る。その中でさらに条件分岐【弾丸残りが1以上】の場合。これは【弾丸残り】という変数を作り、最初の自動実行イベントで予め3を代入しておく。ここに代入した数が、同時にマップに出現可能な弾丸の最大数となる。

そしてスイッチを3つ、【弾丸1】【弾丸2】【弾丸3】を用意。先の条件が揃った際、それぞれのスイッチが入っているか否かを条件に、どの弾丸を発射するか決める。発射位置は、初めに取得したプレイヤーのY座標のみ1減算する。イベントの位置設定を変数【プレイヤーX】【プレイヤーY】で指定すれば、プレイヤーの前方(1マス上方向)に弾丸イベントが設定される。最後に弾丸のスイッチを入れると、イベントが出現する。弾丸発射になった時に、変数の【弾丸残り】を減算1する。

!!弾丸1~3!!
弾丸の並列処理イベントは、【このイベントのマップX及びY】をそれぞれの変数に代入する処理を最上部に設定。つまり弾丸の数が3つなら最低6つは座標用の変数を用意する。同時にターゲット用の座標変数についても、ターゲット数の2倍(つまり今回は同様に6つ)用意する。そして条件分岐を入れ子で指定。まずスイッチ【タゲAアニメーション中】でない時、次に【ターゲットA】が入っている(ターゲットAがマップ上に出現している)時、最後に変数【この弾丸座標とターゲットA座標】が一致する時。座標の確認は長くなるが条件分岐タブ4つ目のスクリプトに「$game_variables[77] == $game_variables[112] && $game_variables[78] == $game_variables[113]」と書けば、一つに収まる。

上記の3条件が満たされた段階で、コモンイベント【タゲA命中】を発動。内容は、スイッチ【タゲAアニメーション中】を入れ、【タゲAの属性】という変数により点数を加算あるいは減算させる。たとえば属性が10以下だとオーク、11~15はゴースト、20以上は市民、という具合に判定させている。次にアニメーションの表示をターゲットAにウエイト指定で実行。最後に、【タゲAアニメーション中】と【ターゲットA】のスイッチをそれぞれ解除する。

このコモンイベントの後、弾丸は変数【弾丸残り】に1を加算し、件の【弾丸(1~3のどれか)】スイッチを解除する。同じように【タゲBアニメーション中】【タゲCアニメーション中】についても、同様の手順を踏む。

その後、その弾丸の座標のタイルID(Layer3)を取得する。初めに載せた画像の場合、プレイヤーの前にある柵は、ID481番である。そのため、【タイルIDが481でない時】の条件分岐をつくり、更に条件分岐のスクリプト【!$game_player.passable?($game_variables[77], $game_variables[78], 8)】を設定。このスクリプトは、プレイヤーがその座標を移動可能かどうかを調べるもので、この場合だとX座標が変数77、Y座標が変数78の上方向が、「プレイヤーにとって」移動可能かどうかを判別する。
※イベントを基準に調べると、すり抜けのために全箇所移動可能になり、タイルID481を除外しないと弾丸を発射した瞬間に条件が満たされてしまう。

上記2条件が満たされている場合も、ターゲットに命中した時と同様、【弾丸残り】に1を加算し、該当する弾丸のスイッチを解除する。

以上の条件文の後に、【移動ルートの指定】このイベント上に移動(ウエイト無し)を設定。

!!射的タゲ管理!!
今度は、ターゲット(的、パネル)が画面の何処に出現するかを指定するためのイベント。まず条件分岐のスイッチ【タゲAアニメーション中】でない時、更に条件スイッチで【ターゲットA】が入っていない時。

この2条件が満たされている場合、変数【タゲA属性】に乱数0~25を代入。これにより、これから出現するターゲットAのグラフィックが決まる。次にラベル【タゲA座標】を設定。他のターゲットと同じ座標に表れるのを防ぐためだ。そして変数にターゲットAのX座標、Y座標をそれぞれ乱数で指定する。この乱数の範囲が、出現する可能性のある範囲となる。もし射的のステージが複数ある場合、変数【射的ステージ】を用いてそれぞれの場合に座標を指定する。

条件分岐タブ4つ目のスクリプトに【$game_variables[112] + $game_variables[113] == $game_variables[114] + $game_variables[115]】と指定する。これは、変数112(タゲAのX座標)と変数113(タゲAのY座標)を足した数字が、変数114と115(タゲBのXY座標)を足した数字とイコール(同じ)時、という条件。これが満たされる場合、ターゲットAとBが、重なって現れてしまう可能性があるので、ラベルジャンプ【タゲA座標】を指定し、座標を再計算させる。
※あくまで座標の合算を比較しているため、「x,y」で言うと例えば「4,12」と「12,4」は、マップ上で違う場所だが、上記の例では同じになる。しかし、なるべく簡略化したかった(条件文を1行で済ませたかった)ため、このような記述にした。

さて、先の条件分岐に当て嵌まらなければ、スイッチ【ターゲットA】を入れ、【イベントの位置設定】でターゲットAを先ほど代入した変数の位置に指定する。

同様の処理を、【ターゲットB】【ターゲットC】の分も作成する。

!!ターゲットA~C!!
出現条件はスイッチ【ターゲットA】が入っている時、足踏み無し、すり抜け任意、向き固定任意で設定。イベントページは、変数【タゲA属性】に依存する。今回の場合だと、スイッチ【ターゲットA】及び変数【タゲA属性】がxx以上という指定で、ターゲット毎に9ページ使用している。例えばその属性の数値が10以上だと悪魔にしているので、2ページ目には変数10以上という指定がされる。属性の数値は0~25にしたため、26分の10の確率(0~9)で、オークが選ばれる。

ページ毎に、自律移動のタイプをカスタムにし、移動ルートを設定する。ウエイト60、スイッチ【ターゲットA】OFF、スイッチ【タゲAアニメーション中】OFFにすれば、1秒(60フレーム)経過すると自動的に消え、再び別の場所にターゲットが現れるようになる。もちろん、消える前に弾丸を当てることが出来たら、その時も強制的に消えて別の場所に出現する。

得点の高いグラフィックは、この移動ルートのウエイト時間を短く設定すればいい。ちなみにゴーストをウエイト30にしたら、結構運ゲーになった。かといって60だと、そこそこ余裕を持って倒せるので、参考までに。

!!終了!!
とりあえずこんな感じ。もっと手を加えれば、弾丸の消える判定をプレイヤーの移動可否にしていることから、射的コースによって、弾丸を阻害する岩がランダムで出現する、というギミックは作りやすそう。ただ一回組んだものをまた作り直すのが面倒なので、俺はやらない。写真右のマップが上級コースということにして、マップを少し広くしてある。あとは何も変化無し。そうそう、得点などのウインドウに関しては、スクリプトのWindow_Goldを改変したWindow_Shatekiを作り、射的スタートのスイッチが入った時に並列処理で$windowに指定している。ウインドウに関しては、faida様のブログ「点線上の文字の羅列」のこのページに、詳しい作り方が載っている。俺の環境だと「$window.dispose」の直後に「$window = nil」を実行している。

 それにしてもあれだなぁ。飽きてきたなぁ。もうそろそろドラクエ10のバージョンアップだし、また戻ろうかなぁ。なんて思い始めている今日この頃、暑いね。
 

2014.05.27 - RPGツクールVXAceが止まらない。

2014-05-27 | RPGツクールMZ,VXace,VX,2000,95,1~5
 
 忍者屋敷を作っている途中、画像は鉄球の罠だ。鉄球が左右に常時動いており、触れると鉄球の向いている方向に押される。そして通路の両端の穴に落ちると、地下まで落下してしまう、という罠だ。起動判定をイベントから接触にしてテストしてみたら、決定ボタンでも開始されるうえに、隊列メンバーに衝突判定があるため、彼らは鉄球の動きを止めてしまう。しかも座標の問題で、どうも押されているように見えないのだ。そこで、鉄球はすり抜け属性にし、衝突判定はMAP内に用意した1つの並列処理イベントに任せることにした。判定はプレイヤーとイベントの座標を調べ、X座標、Y座標ともに一致する場合はイベントの向きによってプレイヤーを移動させる。ここでもう一度プレイヤーの座標を取得し、その地形タイルIDが穴のタイル(この場合は1536)と一致した場合、落下イベントを発動させる。間違えて自分から落ちることも考慮し、タイルIDの確認はイベントIDの確認直前にも入れる。
 コモンイベントからマップイベントを扱う際のVXAでの仕様だが、これは当たり前のことだろうか。たとえば移動ルートの設定には、プレイヤー、このイベントとあるが、コモンイベントからも「このイベント」という指定は有効で、この場合は呼び出し元のイベントに効果がある。それどころか、イベントIDによる指定も可能。コモンイベント上で移動ルートの設定を選ぶと、最後にアクティブにしたマップIDのイベント一覧が読み込まれるので、設定したいマップを表示させた状態でコモンイベントを開けば、通常のイベント作成と同じようにイベントが組めて便利だ。

 あと、これまで「難しそうだから」と敬遠していた山のマップを、遂に作った。案の定、村や塔に比べて時間が掛かり、とても疲れた。題名には止まらないって書いたけど、思い付かなかったりして結構頻繁に止まっている。