RPGツクールXP講座



RPGの作り方 Lv4

 今回は、スクリプト(RGSS)も使って、もう少し高度な処理に挑戦したいと思います。


始める前の下準備

 これから説明をしていくために、専用のプロジェクトを作ります。みなさんも、同じことをして確認する場合は、同じようにプロジェクトを作って準備してください。

 Lv3からデータを引き継ぎますが、区別するため、フォルダ名とタイトルは、ともに「test4」にします。

 また、この章では、スクリプト(RGSS)を使います。この段階では、まだ詳しいことは知らなくても良いですが、出来ればヘルプの「スクリプト入門」「基礎編」を読んでおくと良いでしょう。


スクリプトをコピーする際の注意

 この章から、スクリプトが出てきますが、この文書に書かれたスクリプトを、ツクールのスクリプトエディタに貼り付ける場合、注意が必要です。
 この文書のスクリプトには、正常に表示させるために全角のスペースが使ってあります。しかし、スクリプトでは、全角スペースは使えないため、実行するとエラーになります。半角スペースに変換してください。
 スクリプトエディターに貼り付け後、置き換えの機能を使って、全角スペース1つを、半角スペース2つに置き換えると良いでしょう。


ゲームの用語を書き換える

 今回は、スクリプト(RGSS)を使ってみようと思います。
 スクリプトというと難しいと思っている人も居ると思いますが、簡単に出来る部分もたくさんありますので、あまり身構えず、まずはやってみましょう。
 ここでは、まだスクリプトの詳しい説明はしません。難しいことは省いて、すぐに実践から始めます。


◆スクリプトを見る
 まず、スクリプトがどんなものか、見てみましょう。
 下図の矢印のところをクリックして、スクリプトエディタを開いてください。

▼スクリプトエディタを開く


 下図のようなウィンドウが開いたはずです。
▼スクリプトエディタ


 ざっと、見てみてください。何が書いてあるのかよく分からないと思います。今の時点では、それでもいいです。 ただし、ひとつだけ注意があります。それは、スクリプトエディタの内容を不用意に書き換えてはいけないということです。
 スクリプトエディタには、RPGツクールXPで作ったゲームが、どのように動くのかということが書かれています。ですから、不用意に書き換えると、ゲームが正常に動かなくなります。それだけ注意してください。



◆用語を書き換える
 RPGツクールXPには、様々な用語が使われています。データベースのシステムタブで、多少の用語は変更できますが、変更できない部分もたくさんあります。
 しかし、スクリプトを変更すれば、すべての用語が変更できます。


◆タイトルを書き換える
 まず最初に、タイトル画面の用語を変更しましょう。
 現在のタイトル画面は、下図のようになっています。

▼初期状態のタイトル画面


 この「ニューゲーム」、「コンティニュー」、「シャットダウン」という用語を変更してみましょう。
 スクリプトエディタを開いてください。左側のスクリプトのリストの中に「Scene_Title」というスクリプトがありますので、クリックしてください。右側に、その内容が表示されます。

▼「Scene_Title」の内容


 37行目から39目に、下記のような設定があります。
  s1 = "ニューゲーム"
  s2 = "コンティニュー"
  s3 = "シャットダウン"
 これを、
  s1 = "ゲーム開始"
  s2 = "記録から再開"
  s3 = "終了"
 と書き換えてみましょう。
 そして、ゲームを実行して確認してみるとこうなります。

▼変更後のタイトル画面


 自分の好きな言葉に変えてみてください。


◆メニューを書き換える
 次に、メニュー画面の用語を変更しましょう。
 現在のメニュー画面は、下図のようになっています。

▼初期状態のメニュー画面



 スクリプトエディタを開いてください。左側のスクリプトのリストの中に「Scene_Menu」というスクリプトがありますので、クリックしてください。右側に、その内容が表示されます。

▼「Scene_Menu」の内容


 20行目から25目に、下記のような設定があります。
  s1 = $data_system.words.item
  s2 = $data_system.words.skill
  s3 = $data_system.words.equip
  s4 = "ステータス"
  s5 = "セーブ"
  s6 = "ゲーム終了"
 これを、
  s1 = $data_system.words.item
  s2 = $data_system.words.skill
  s3 = $data_system.words.equip
  s4 = "主人公の状態"
  s5 = "冒険の記録"
  s6 = "ゲーム終了"
 と書き換えてみましょう。
 そして、ゲームを実行して確認してみるとこうなります。

▼変更後のメニュー画面



 ところで、s1〜s3の設定の意味がよく分からないと思います。「$data_system.words.item」というようなものです。実はこれ、データベースのシステムタブの用語のところにある、「アイテム」、「スキル」、「装備」の用語設定を参照しています。
 つまり、s1〜s3の用語を変えたいときは、データベースのシステムタブで、用語設定をすればいいわけです。
 直接「s1 = "アイテム"」というように書き換えた場合、システムタブの設定は無効になります。
 ただし、それはおすすめしません。なぜなら、s1〜s3の用語は、戦闘など他の場面でも使われるからです。変更するなら、メニュー画面だけでなく他の表示設定も全部変更しないといけなくなります。

 他にも、色々と変更可能です。例えば、メニュー画面に表示される、「Lv」や「E」といった項目名、ステートのノーマル状態を表す「[正常]」という表示など、細かい部分も変更可能です。
 これらは、「Window_Base」というスクリプトの下記の行で設定できます。
143行目  self.contents.draw_text(x, y, 32, 32, "Lv")
175行目  text = "[正常]"
204行目  self.contents.draw_text(x, y, 24, 32, "E")

 他にもまだたくさんの項目がありますが、とりあえずここまでにします。


ダッシュシステム改良版

 ダッシュシステムとは、主人公キャラの移動速度を上げて、歩くのを早くする(あるいは走れるようにする)システムのことです。
 マップが広かったり、同じところを何度も行き来したりする場合は、あると便利です。

 Lv3で、並列処理を使ったダッシュシステムを作りましたが、あれはまだ不完全でした。
 今回は、より完全に近いダッシュシステムを、スクリプトを使って作ってみたいと思います。


◆ダッシュシステムを作る
 前回と同じく、Aボタンを押している間だけスピードアップするようにします。(Aボタンは、キーボードの場合は、Shiftキー)

 スクリプトエディタを開いて「Game_Player」の中を見てみましょう。200行目あたりに、フレーム更新の処理が設定されています。

▼スクリプトの内容


 この中の下記の部分に注目してください。
   case Input.dir4
   when 2
    move_down
   when 4
    move_left
   when 6
    move_right
   when 8
    move_up
   end

 これは、Input.dir4という変数の値によって分岐する処理で、値が2ならキャラクターを下へ移動させ、4なら左へ移動させ、6なら右へ、8なら下へ移動させるというものです。
 ここで、キー入力に応じて、キャラクターを移動させているわけです。
 ですから、この前に、Aボタンが押されているかどうかで、移動速度を変更するような処理を入れてやれば、ダッシュシステムができます。
 例えば、こんな感じです。
  if Input.press?(Input::A)
   @move_speed = 5
  else
   @move_speed = 4
  end

 if〜else〜endというのは、コモンイベントの条件分岐と同じ形式の条件分岐をする処理です。
 この場合、もしAボタンが押されているなら、@move_speedという変数に5を代入し、そうでないなら@move_speedという変数に4を代入するという処理をします。

 実際に、スクリプトを編集しました。

▼スクリプトの内容 編集後



◆動作確認
 動作確認をしますが、その前に忘れずに、Lv3で作ったコモンイベントのダッシュシステムを消しておきます。
 ゲームを開始して、ダッシュシステムが機能するか確認してください。


◆スクリプトを改良する
 スクリプトを少し改良しました。条件分岐が重なっているのでちょっと分かりにくいかもしれませんが、やっていることは単純です。

  if $game_switches[12] == true
   if Input.press?(Input::A)
    if @move_speed != 5
     @move_speed = 5
    end
   else
    if @move_speed != 4
     @move_speed = 4
    end
   end
  end

 まず、「if $game_switches[12] == true」これは、ゲームスイッチの[0012]番がONの時に実行するという条件分岐です。OFFの時の処理はありません。
 これで、ゲームスイッチの[0012]番が、ONの時だけ、ダッシュシステムが働きます。
 当然、ゲームスイッチの[0012]番は、ダッシュシステムのON/OFFに使うようにしておきます。

 次に、下記の条件分岐、
   if @move_speed != 5
    @move_speed = 5
   end
 これは、変数@move_speedの値が5ではない場合に、変数@move_speedに5を代入するというものです。
 つまり、Aボタンが押されていても、すでに移動速度が5になっているなら何もせず、5ではない場合のみ5を代入するということです。これによって、何度も同じ値を代入し続けることを防ぎます。
 下記の部分も同じ意味です。
   if @move_speed != 4
    @move_speed = 4
   end

 これで、ダッシュシステムは、一応完成です。


テストプレイの高速化

 テストプレイをしていると、文章表示が遅かったり、バトルの進行が遅かったりして、イライラすることがあります。
 そこで、文章表示やバトルを高速化させ、効率よくテストできるようにしましょう。

 ダッシュシステムと同じく、Aボタンを押している間だけスピードアップするようにします。(Aボタンは、キーボードの場合は、Shiftキー)


◆文章表示の高速化
 スクリプトエディタを開いて「Window_Message」の中を見てみましょう。
 188行目あたりに、「フレーム更新」というスクリプトがあります。
 それを、下記のように改造します。
 Aボタンが押されていないときには、waitを24に、押されている時は255にします。値が大きいほど速く表示されます。255が最大です。

#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
 super
  # フェードインの場合
  
  # 文章表示高速化 追加分 ここから
  if Input.press?(Input::A)
   wait = 255
  else
   wait = 24
  end
  # 文章表示高速化 追加分 ここまで
  
  if @fade_in
   self.contents_opacity += wait #24からwaitに変更
   if @input_number_window != nil
    @input_number_window.contents_opacity += wait #24からwaitに変更
   end
   if self.contents_opacity == 255
    @fade_in = false
   end
   return
  end
 


◆バトル 行動側アニメーションのスキップ
 スクリプトエディタを開いて「Scene_Battle 4」の中を見てみましょう。
 393行目あたりに、「フレーム更新 (メインフェーズ ステップ 3 : 行動側アニメーション)」というスクリプトがあります。
 それを、下記のように改造します。
 これで、Aボタンが押されていないときに、行動側のアニメ表示をします。押されていれば、アニメ表示が無いのでその分高速になります。


 #--------------------------------------------------------------------------
 # ● フレーム更新 (メインフェーズ ステップ 3 : 行動側アニメーション)
 #--------------------------------------------------------------------------
 def update_phase4_step3
  # 行動側アニメーション (ID が 0 の場合は白フラッシュ)
  
  # 戦闘高速化 追加分 ここから
  if not Input.press?(Input::A)
   if @animation1_id == 0
    @active_battler.white_flash = true
   else
    @active_battler.animation_id = @animation1_id
    @active_battler.animation_hit = true
   end
  end
  # 戦闘高速化 追加分 ここまで

  # ステップ 4 に移行
  @phase4_step = 4
 end




◆バトル 対象側アニメーションのスキップ
 行動側アニメーションと同じ要領で、もう一箇所、その下にある「フレーム更新 (メインフェーズ ステップ 4 : 対象側アニメーション)」も書き換えます。
 これで、対象側のアニメーションもスキップできます。

 #--------------------------------------------------------------------------
 # ● フレーム更新 (メインフェーズ ステップ 4 : 対象側アニメーション)
 #--------------------------------------------------------------------------
 def update_phase4_step4
  # 対象側アニメーション
  
  # 戦闘高速化 追加分 ここから
  if not Input.press?(Input::A)
   for target in @target_battlers
   target.animation_id = @animation2_id
   target.animation_hit = (target.damage != "Miss")
   end
  end
  @wait_count = 8
  # 戦闘高速化 追加分 ここまで
  
  # ステップ 5 に移行
  @phase4_step = 5
 end



◆バトル リザルトウィンドウの表示を早める
 戦闘終了時に出る、獲得した経験値などを表示するウィンドウが出るのが、ちょっと遅い気がしますよね?
 あれを、もっと早く出るように変更します。
 スクリプトエディタを開いて「Scene_Battle 2」の中を見てみましょう。
 393行目あたりに、「アフターバトルフェーズ開始」というスクリプトがあります。
 その一番最後にある「@phase5_wait_count = 100」の部分を変えます。

 if Input.press?(Input::A)
  @phase5_wait_count = 10
 else
  @phase5_wait_count = 80
 end



◆動作確認
 実際に、会話中や戦闘中にAボタンを押してみましょう。
 アニメ表示が無くなって、速くなったはずです。


顔グラフィックを表示する

 RPGツクール2000のように、顔グラフィックを表示できるようにします。

◆顔グラフィックの画像を用意する
 ツクールXPには、顔グラの素材はありませんので、まず、顔グラフィックの画像ファイルを作らないといけません。
 とりあえず、顔グラに最も近い、バトラーグラフィックを加工して、顔グラの代わりにしたいと思います。
 
▼アルシェスの顔グラ


 このようになりました。
 サイズは、120x120ピクセルです。ファイル名は「アルシェス.png」としました。

 他の3人の仲間も、それぞれ作りました。
 バトラーグラフィックなので、顔グラとしては変ですが、とりあえず仮素材なのでいいでしょう。

 これらのファイルを、マテリアルベースで、「Graphics/Pictures」にインポートしましょう。
 透明色の設定は必要ありません。


◆ウィンドウの位置とサイズの調整
 文章表示ウィンドウは、そのままでは、顔グラフィックを表示するスペースがありませんので、表示位置を変更します。
 しかし、顔グラを表示しない場合もあるので、普段どおりのウィンドウも表示できなければいけません。
 そこで、変数を使って、通常モードと顔グラ表示モードを分けることにしましょう。

 スクリプトエディタを開いて「Window_Message」の中を見てみましょう。165行目あたりに、ウィンドウの位置と不透明度の設定が設定されています。

▼スクリプトの内容


 図の179行と180の間に、下記を書き加えます。

   if $kao == nil or $kao == ""
    self.x = 80
   else
    self.x = 160
   end

 これは、$kaoという変数の値によって、文章表示の位置をずらすスクリプトです。
 「$kao == nil or $kao == ""」というのは、変数$kaoがnil(データが入っていないという意味)か、もしくは、変数$kaoが""(空の文字列という意味)なら、という条件分岐の条件です。
 この条件が満たされている場合、ウィンドウの表示位置「self.x」を80にします。これは、通常モードのウィンドウの位置です。
 条件が満たされない場合は、「self.x」を160にします。これは、顔グラモードのウィンドウの位置です。

 この処理はつまり、$kaoに何もデータが入っていなければ通常モードの表示にし、何かデータが入っていれば顔グラモードの表示にするということです。

▼スクリプトの内容 変更後




◆顔グラフィック用ウィンドウの表示
 先ほどのスクリプトにさらに、顔グラ用ウィンドウの表示を付け加えます。下記のとおりです。

   if $kao == nil or $kao == ""
    self.x = 80
   else
    self.x = 160
    #顔グラ用ウィンドウ表示
    if $kao_window == nil
     $kao_window = Window_Base.new(0,304,160,160)
    end
    $kao_window.y = self.y
    $kao_window.contents = Bitmap.new($kao_window.width-32,$kao_window.height-32)
    $kao_window.back_opacity = self.back_opacity
    #顔グラ表示
    $kao_file="Graphics/Pictures/アルシェス"
    bitmap=Bitmap.new($kao_file)
    $kao_window.contents.blt(4,4,bitmap,Rect.new(0,0,120,120))
    $kao_window.visible = true
   end

 順番に説明します。


  if $kao_window == nil
   $kao_window = Window_Base.new(0,304,160,160)
  end

 「$kao_window」という名前で、新しいウィンドウを生成します。
 「$kao_window」がnilの場合にのみ($kao_windowが無い場合のみ)作ります。
 数字は、順に、表示座標X、表示座標Y、幅、高さ、をピクセル単位で表したものです。


  $kao_window.y = self.y

 $kao_windowの表示位置のy座標を、文章表示ウィンドウに合わせます。


  $kao_window.contents = Bitmap.new($kao_window.width-32,$kao_window.height-32)

 画像表示のための領域を設定します。


  $kao_window.back_opacity = self.back_opacity

 $kao_windowの背景の不透明度を、文章ウィンドウと同じにします。


  $kao_file="Graphics/Pictures/アルシェス"

 アルシェスの顔グラ用ファイルを、顔グラ表示用画像ファイルに設定します。この処理は仮のものです。


  $kao_window.contents.blt(4,4,Bitmap.new($kao_file),Rect.new(0,0,120,120))

 顔グラの画像を、$kao_windowに貼り付けます。


  $kao_window.visible = true

 $kao_windowを可視状態にして、表示します。


▼スクリプトの内容 修正後




◆動作確認 
 これで、一応アルシェスの顔グラが表示できるようになりました。
 確認してみましょう。適当なマップにイベントを作って、下記のように設定します。

▼動作確認用イベントの内容


 まず、普通に文章表示をします。

 次に、スクリプトコマンドで、$kao = "あああ" とします。
 これで、変数$kaoに「あああ」という文字列が代入されました。
 変数$kaoに何かデータが入っていると、顔グラモードで表示されるように設定しましたから、次に表示される文章は、顔グラモードで表示されるはずです。

 次に、スクリプトコマンドで、$kao = "" とします。
 これで、変数$kaoに空の文字列が代入されました。
 $kaoが空の文字列だと、通常モードで表示されるように設定しましたから、次に表示される文章は、通常モードで表示されるはずです。

▼実行結果


 うまく、実行されました。
 しかし、ここでひとつ問題が生じたはずです。
 一度表示された顔グラが、消えません。これではまずいので、ウィンドウを消す処理を書き加えます。

   if $kao == nil or $kao == ""
    self.x = 80
   else
 この部分に下記のように書き加えました。

   if $kao == nil or $kao == ""
    self.x = 80
    if $kao_window != nil
     $kao_window.dispose
     $kao_window = nil    
    end
   else
 これで、変数$kaoにデータが無ければ、顔グラ表示用ウィンドウが消去されます。
 $kao_window.disposeというのが消去で、次にnilを代入して変数を初期化しています。
 if $kao_window != nil という条件分岐に入れているのは、すでにnilなら何もしないためです。

▼スクリプトの内容 修正後


 この修正で、通常モードで表示した場合は、顔グラが消えるようになりました。
 もうひとつ、文章表示を終了する時に、消さないといけません。その処理を追加します。
 「Window_Message」のスクリプトの最後の方に、「# 表示すべきメッセージがないが、ウィンドウが可視状態の場合」という処理があります。そこを下記のように書き換えます。

  # 表示すべきメッセージがないが、ウィンドウが可視状態の場合
  if self.visible
   @fade_out = true
   self.opacity -= 48
   #顔グラ消去 追加分
   if $kao_window != nil
    $kao_window.opacity -= 48 
    $kao_window.contents_opacity -= 48
   end
   if self.opacity == 0
    self.visible = false
    @fade_out = false
    $game_temp.message_window_showing = false
    #顔グラ消去 追加分
    if $kao_window != nil
     $kao_window.dispose
     $kao_window = nil
     $kao=""
    end
   end

 実際に書き換えたのが下図です。

▼スクリプトの内容 修正後


 この図で言うと、314〜318行目、323〜328行目に追加しています。
 314〜318行目は、ウィンドウを突然消すのではなく、すうっと消していくための処理です。文章表示ウィンドウと同じように消えていきます。
 323〜328行目は、さっきと同じ、顔グラ表示用ウィンドウを消去し初期化する処理です。
 ひとつだけ違うのは、 $kao="" が入っていることです。これは、文章表示終了時に変数$kaoに空の文字列を代入して初期化するためのものです。
 これが無いと、次に文章表示するときに前の設定が残っていて、関係ない顔グラが表示されることがあります。


◆動作確認 
 これで、ちゃんと顔グラフィックが消えるようになったはずです。


◆顔グラの登録
 今の状態では、アルシェスの顔グラしか表示できません。
 これを、変数$kaoに代入した文字列によって、それに対応した顔グラを表示できるようにします。
 つまり、$kao = "アルシェス" として表示すれば、アルシェスの顔グラが表示され、$kao = "ドロシー" として表示すれば、ドロシーの顔グラが表示されるようにしたいわけです。
 下記のように設定しました。

    kao_folder = "Graphics/Pictures/"
    case $kao
    when "顔グラ無し"
     kao_file = Bitmap.new(kao_folder + "顔グラ無し")
    when "アルシェス"
     kao_file = Bitmap.new(kao_folder + "アルシェス")
    when "グロリア"
     kao_file = Bitmap.new(kao_folder + "グロリア")
    when "ドロシー"
     kao_file = Bitmap.new(kao_folder + "ドロシー")
    when "ヒルダ"
     kao_file = Bitmap.new(kao_folder + "ヒルダ")
    else     
     kao_file = Bitmap.new(120,120)
    end
    $kao_window.contents.blt(4,4,kao_file,Rect.new(0,0,120,120))
    $kao_window.visible = true


 順番に説明します。

  kao_folder = "Graphics/Pictures/"

 ここで、変数kao_folderに、顔グラの画像ファイルが入っているフォルダを設定しています。
 顔グラは、Graphicsというフォルダの中のPicturesというフォルダにインポートしていますので「Graphics/Pictures/」と設定します。


  case $kao

 変数$kaoの値で分岐します。


  when "アルシェス"
   kao_file = Bitmap.new(kao_folder + "アルシェス")

 $kaoの値がアルシェスなら、変数kao_fileに画像を設定します。
 Bitmap.newは、画像を生成する命令です。「(kao_folder + "アルシェス")」は、画像ファイルの指定です。変数kao_foldeには、フォルダ名が入っていますので、それにアルシェスをプラスするということは、「Graphics/Pictures/アルシェス」となるわけです。
 つまり、Graphicsというフォルダの中のPicturesというフォルダに入っているアルシェスというファイルを読み込んで画像を生成するということになります。
 画像ファイルの拡張子(.pngなど)は、指定しなくて良いです。

 ちなみに、顔グラ無しというのは、顔グラを作ってないキャラのために表示する画像です。今回は画像ファイルを作っていませんので、これを指定するとエラーになります。
  

  else
   kao_file = Bitmap.new(120,120)

 変数$kaoの値が、どのケースにも当てはまらない場合に、透明な画像を生成します。


  $kao_window.contents.blt(4,4,kao_file,Rect.new(0,0,120,120))

 画像をウィンドウに貼り付けます。


▼スクリプトの内容 修正後


 このようになりました。


◆動作確認 
 ちゃんと顔グラフィック表示されるか確認しましょう。

▼動作確認用イベントの内容


 最初に普通に表示し、次にアルシェス、グロリア、ドロシー、ヒルダと表示されます。
 次に、$kao = "でたらめ"と書いてあります。「でたらめ」などという顔グラは設定してありませんので、顔グラは何も表示されません。ウィンドウだけ出ます。

▼実行結果



 これで、顔グラフィックの表示は一応終わります。
 顔グラの設定を増やしたければ、条件分岐の、whenの部分を付け足していけばよいです。


◆ゲームの修正 
 今まで作った会話イベントを修正して、文章表示の前に顔グラフィックの設定をします。


地名表示システムを作る

 マップを移動した時、しばらくの間、そのマップの地名が表示されて消える、というものがあります。あれを作ってみましょう。


◆地名を表示する
 地名表示は、頻繁に行う作業なので、例によってコモンイベントにします。
 内容は、下記のようになります。

$ti_w = Window_Base.new(440,0,200,64)  #$ti_wという名前でウィンドウを作る
$ti_w.contents = Bitmap.new(168,32)   #描画領域の設定
$ti_w.contents.font.name = "MS P明朝" #フォントを明朝に
$ti_w.contents.font.bold = true     #太文字に
$ti_w.contents.font.italic = true    #斜体に
$ti_w.contents.font.size = 24      #フォントサイズを24に

kage=Color.new(0,0,0,255)        #kageという名前で色を作る(黒)
timei=Color.new(255,255,255,255)     #timeiという名前で色を作る(白)
$ti_w.contents.font.color = kage     #フォント色をkageに設定
$ti_w.contents.draw_text(3,3,168,32,$timei,1) #文字を描画
$ti_w.contents.font.color = timei    #フォント色をtimeiに設定
$ti_w.contents.draw_text(0,0,168,32,$timei,1) #文字を描画

$ti_w.back_opacity = 140         #ウィンドウの背景を半透明に
$ti_w.visible = true           #ウィンドウを可視状態に


 上記のスクリプトを、コモンイベントに設定しました。

▼コモンイベントの内容




◆動作確認
 適当なマップに適当にイベントを作り、実行してみましょう。
 内容は、下記のような感じです。

$timei="のどかな森"
コモンイベント:地名表示システム

 $timeiに、表示する文字列を代入してから、コモンイベントを呼び出します。

▼実行結果


 このように表示されます。


◆表示の仕方と消し方の設定
 今の状態では、突然表示されてそのままです。これを、すうっと表示されて1秒ほど待ち、またすうっと消えていくようにします。

 まず、最初にコモンイベントを、並列処理にしておきます。そうしないと、処理を行っている間、主人公が動けません。
 条件スイッチは、[0014:地名表示システム]にしました。

 次に、先ほどの
$ti_w.back_opacity = 140
$ti_w.visible = true

 の部分を下記のようにします。可視状態にする前に、ウィンドウと文字の不透明度を0にします。

$ti_w.opacity = 0
$ti_w.back_opacity = 0
$ti_w.contents_opacity = 0
$ti_w.visible = true

 次に、下図のような処理を付け加えます。

▼コモンイベントの内容 修正後


 順番に説明します。

○表示する処理
 ループを使って、少しづつ不透明度を上げています。
 変数@iに、20づつ加算していき、ウィンドウや文字の透明度を@iの値に設定しています。
 不透明度は最大255までですので、@iが255以上になったらループから抜けます。

○表示時間
 1秒待機します。

○消す処理
 「表示する処理」と逆のことをやって消していきます。
 最後に、下記の処理で、ウィンドウを消します。

if $ti_w != nil  #$ti_wがnilじゃないなら(ウィンドウが存在するなら)
 $ti_w.dispose  #ウィンドウを消し
 $ti_w = nil   #nilを代入して初期化
end

 そして、スイッチ:[0014:地名表示システム]をOFFにして、終了します。



◆マップの出入りに合わせて表示する
 今度は、実際に各マップへ入った時に、地名を表示するようにします。
 各マップに、地名表示用の透明のイベントをおきます。マップのどこか邪魔にならない場所に置きます。
 トリガーを自動実行にします。
 イベント内容は下記の通りです。

$timei="のどかな森"
スイッチの操作:[0014:地名表示システム]=ON
イベントの一時消去

 これで、地名表示後、イベントが消去されて無くなります。
 各マップごとに「"のどかな森"」の部分を、そのマップにの地名に書き換えればOKです。


◆問題点の修正
 ここで、いくつか問題が予想されます。

 まず、地名表示中にセーブした場合です。
 スクリプトの変数の値は、ゲームを終了すると同時に消えてしまいます。セーブで記録されません。ですから、地名表示の途中でセーブすると、再開した時、値が消えているため困ったことになります。(セーブの際の並列処理の扱いは、よく分からないのですが、少なくともウェイトが入っていると、途中でセーブ可能なようです)
 そこで、地名表示中は、セーブできないように、地名表示の最初に「セーブ禁止の変更:禁止」を入れます。もちろん、最後で「セーブ禁止の変更:許可」します。


 次に、マップに入ってすぐに元のマップに戻った場合です。その場合、地名表示をしている間に、またマップが変わってしまいますので、地名表示がうまくいきません。
 そこで、以前に作った、コモンイベントの「マップ移動前」に下記の処理を追加します。

スイッチ[0014:地名表示システム]=OFF
if $ti_w != nil
 $ti_w.dispose
 $ti_w = nil
end

 条件スイッチをOFFにして、ウィンドウが存在すれば削除するという処理です。

 修正したコモンイベント「マップ移動前」は、下図のようになります。

▼コモンイベント マップ移動前の内容


 これで、マップを移動する前に、現在表示中の地名表示の処理を停止して、ウィンドウを消します。

 もうひとつ、戦闘に入ったときも、地名表示を消さないといけませんが、戦闘システムに関しては、後で変更する予定のため、とりあえずはこのままにしておきます。(Lv5で設定する予定)



◆動作確認
 実際に、各マップに、地名表示用のイベントをおいて、実行してみましょう。
 うまく、表示されたでしょうか?



◆ウィンドウ幅の調整
 今、ウィンドウの幅は200ピクセルに設定されています。
 しかし、もし地名の文字数が多くなると、どうなるでしょうか? ある程度は縮小されて表示されますが、あまり長くなると表示されません。
 そこで、地名の長さにあわせて、ウィンドウの幅を変えることにします。
 下記のように書き換えました。

tw = $ti_w.contents.text_size($timei).width  #描画する文字列の横幅をピクセル単位で取得
tw += 32               #ウィンドウ枠の幅、左右16ドットづつを余白としてプラス
$ti_w.width = tw           #ウィンドウの幅を調整
$ti_w.contents = Bitmap.new(tw-32,32) #描画領域を設定
$ti_w.x = 640 - tw          #ウィンドウ表示位置のx座標を調整

kage=Color.new(0,0,0,255)       #前と変更無し
hontai=Color.new(255,255,255,255)   #前と変更無し
$ti_w.contents.font.color = kage   #前と変更無し
$ti_w.contents.draw_text(3,3,tw-32,32,$timei,1) #描画テキストの幅が、描画領域と同じになるように設定変更
$ti_w.contents.font.color = hontai  #前と変更無し
$ti_w.contents.draw_text(0,0,tw-32,32,$timei,1) #描画テキストの幅が、描画領域と同じになるように設定変更

これで、自動的に幅が調整されるようになりました。



◆画面が暗い時表示待ち
 画面切り替えの時、画面の色調変更で、フェードイン・フェードアウトなどの処理をすることがあります。
 この時、地名が表示されると、画面が暗いうちに表示されてしまうので変です。ある程度明るくなるまで、ループして待つようにします。
 
▼コモンイベント内容 修正後


 このようにしました。
 ポイントは、この部分です。

@r = $game_screen.tone.red
@g = $game_screen.tone.green
@b = $game_screen.tone.blue

 これで、画面の色調の値を、変数に取得しています。
 これは、イベントコマンド「画面の色調変更」で設定する、赤、緑、青、の値と同じです。
 この3つの値の合計が、-400未満なら、暗すぎると判断し、ループします。
 しかし、3秒以上経過したら、暗くても表示するようにしてあります。


戦闘 シンボルエンカウント

 今まで、標準のランダムエンカウントシステムを使ってきましたが、このゲームではシンボルエンカウントシステムを採用しますので、作り変えます。
 シンボルエンカウントというのは、マップ上をモンスターが歩き回っていて、接触すると戦闘が発生するというものです。


◆ランダムエンカウントの設定を消す
 まず最初に、洞窟のマップの「マップの設定」で、エンカウントの設定を全部消してください。


◆仕様を決める
 シンボルエンカウントシステムをどんな仕様にするか決めます。
 今回は、シンプルなシステムを作ります。より高度なものは、次のLv5にしたいと思います。

 今回のシンボルエンカウントシステムは、イベントの自律移動を「ランダム」や「近づく」に設定し、トリガーを「イベントから接触」にしておく方法です。
 これで、実行内容に、「バトルの処理」を書いておけば、接触したときバトルが発生します。

 バトル終了後は、消して待機させ、一定時間経過すると復活するようにします。


◆配列変数を使う
 今回、復活までの時間を記録するために、配列変数という変数を使います。
 配列変数とは、$abc[1]のように、変数に番号がついたものです。
 $abc[1] = "あたま"
 $abc[2] = "からだ"
 $abc[3] = "あし"
 というように、番号ごとに別の値を記録できます。
 これを利用して、エンカウント用のモンスターのイベントごとに、個別の値を設定します。
 セルフスイッチの変数版のような感じですね。

 復活までの時間を記録するのは、$taiki[@event_id]という配列変数です。
 @event_idは、イベントIDが入っている変数です。ですから、モンスターのイベントのIDが、3なら、$taiki[@event_id]は、$taiki[3]と同じということになります。
 これで、イベントのIDに応じて、別々の値を記録できる変数ができます。
 

◆実際にイベントを設定する
 下図のように、設定しました。

▼エンカウントイベント 1ページ目


 トリガーが「イベントから接触」ですので、接触したらバトルが開始されます。
 勝ったら不透明度を下げて消します。
 次に、配列変数の設定をします。

if $taiki == nil #変数がnilなら、配列が設定されていないので
$taiki = []    #こうして、配列変数として設定してやります
end

sec = Graphics.frame_count/Graphics.frame_rate #現在のプレイ時間を秒単位で取得します。
$taiki[@event_id] = 50 + rand(30) + sec     #現在のプレイ時間に、50と乱数を足し、配列変数に記録します。
最後に、セルフスイッチをONにして、2ページ目に切り替えます。

▼エンカウントイベント 2ページ目


 2ページ目のグラフィックは、設定してないように見えますが、スライムのグラフィックが設定してあります。不透明度が0なので、見えないだけです。
 このページは、並列処理で常に時間を監視し続けます。
 
 1行目で、現在のプレイ時間を取得しています。

 次のスクリプト、

if $taiki == nil
$taiki = []
$taiki[@event_id] = 0
end

 これは、セーブしてゲームを終了し、ロードして再開した時のための処理です。ゲームを終了すると、変数の値がnilに戻ってしまうので、もしnilになっていたら、変数の値を0にします。(つまりロード直後、すべてのモンスターは復活することになります)

 次の条件分岐で、$taiki[@event_id]の値と比較します。
 $taiki[@event_id]には、プレイ時間+数十秒が設定してありますので、最初は、$taiki[@event_id]の値の方が大きいですが、時間が経過すると、そのうち現在のプレイ時間が追い抜きます。
 その時、条件分岐の中の処理が実行されます。
 不透明度を上げて、姿を現し、セルフスイッチをOFFにして、1ページ目に戻します。



◆動作確認
 実際に、このスライムに接触して、戦闘を行ってみましょう。そして、数十秒待って、復活するか確認しましょう。


◆他のモンスターも設定する
 他のモンスターも、同じように設定します。
 移動速度や、自律行動などを変えて、色んなパターンを作ってみましょう。


Lv4のまとめ

 これで、「RPGの作り方 Lv4」は、終わりです。
 今回は、スクリプトを使ってみました。ちょっとややこしい部分もありますが、高度な処理が出来ますので、是非活用していきたいですね。

 次回は、もう少し複雑なエンカウントシステムを作りたいと思います。

 ここまで作った分を、下記からダウンロードできます。

 サンプルゲーム「test4.exe」346KB



Last Updated : 2004-10-19

Copyright © 2004 noziko irie. All rights reserved.
http://gcg.sakura.ne.jp/tt/tt_top.htm