【解決済み】初期ステートのスクリプトについて

アバター
ONOZUKA
記事: 63
登録日時: 2015年11月11日(水) 13:31
お住まい: 幻想郷
連絡を取る:

【解決済み】初期ステートのスクリプトについて

投稿記事by ONOZUKA » 2016年9月05日(月) 06:17

戦闘開始時からステートを付加するアクターを作りたいです。
アクターのメモ欄に<初期ステート:1>のように表記して、ID1のステートを付加する
というスクリプトを試しに作ってみたのですが、どこか間違いはないでしょうか?

コード: 全て選択

class RPG::BaseItem
 def initial_state
  return @initial_state if !@initial_state.nil?
  @initial_state = (note =~ /^<初期ステート:/ ? true : false)
  @state_id = (note =~ /\d/)
 end
end

class Game_BattlerBase
 alias initial_state_refresh refresh
  def refresh
   initial_state_refresh
   if initial_state?
   add_state(@state_id) : remove_state(@state_id)
   end
  end
  def initial_state?
   feature_objects.any?{|a|a.initial_state}
  end
end
最後に編集したユーザー ONOZUKA on 2016年9月08日(木) 02:27 [ 編集 1 回目 ]

=============================================================================
RPGツクールVXACEでゲームを作っているはずです!
HP:http://tenkoma.info Twitter:https://twitter.com/ONOZUKA7
=============================================================================
faida
記事: 272
登録日時: 2015年12月17日(木) 16:44

Re: 初期ステートのスクリプトについて

投稿記事by faida » 2016年9月05日(月) 19:31

要点だけいくつか。
・メモの読み込みが機能していません。

コード: 全て選択

class RPG::BaseItem
 def initial_state
  return @initial_state if !@initial_state.nil?
  @initial_state = (note =~ /^<初期ステート:/ ? true : false) # <= メモ欄の読み込みが尻切れ
  @state_id = (note =~ /\d/) # <= これだとメモ欄に適当に書いた数字1文字分(15とやっても1か5)を読んでしまう
 end
end
ステートIDを外部に読み出す方法がなくなっていますし、(色々思いついたのですが詳細はともかく)誤作動のもととなります。

・refreshというメソッドはhp/mpの変更が起こるたびに呼び出されるので、初期ステートという性質上適切な場所ではありません。
また、@state_idは(説明を省きますが)メモ欄を読み込めばどこからでも取り出せるもの、というわけではないので、いつ呼び出してもカラです。

おそらくこうするのが適切ではないか、と思います。

コード: 全て選択

class RPG::BaseItem
 def initial_state_id
  return @initial_state_id if @initial_state_id
    @initial_state_id = (note =~ /^<初期ステート:(\d+)>/ ? $1.to_i : 0)
 end
end

class Game_BattlerBase
  def initial_state_ids # 複数装備などを考えて配列にしています
   feature_objects.collect{|a|a.initial_state_id}.select{|i|i != 0} # 0を除く
  end
end
あとは「戦闘開始」で全体検索(Ctrl+Shift+F)すれば多分大丈夫だと思います。多分。
まぁこれだとステートの複数指定に対応していないのでアレですが、問題はないでしょう。
不明点等ございましたらどうぞ。
------------------------------------------------------------------
自作の(改造でない)スクリプト、プラグイン素材に
関しては、リードミーもしくは作中に
「faida」と記名していただければ
利用可能です。
アバター
ONOZUKA
記事: 63
登録日時: 2015年11月11日(水) 13:31
お住まい: 幻想郷
連絡を取る:

Re: 初期ステートのスクリプトについて

投稿記事by ONOZUKA » 2016年9月06日(火) 03:49

仮に<初期ステート:1,2,3,4,5,6>や<初期ステート:1,2>などといった場合、
抜粋個数を可変にすることはできるのでしょうか?

当初はステートを1個だけ付加することを考えてました。
先の返信コードを少し変えるだけで済むのでしたら、
後々のスクリプト制作において勉強になると考えたので、
ぜひとも教えてくださると助かります。

コード: 全て選択

@initial_state_id = (note =~ /^<初期ステート:(\d+)>/ ? $1.to_i : 0)
#(\d+)を個数分だけ用意する必要があるのでしょうか?
=============================================================================
RPGツクールVXACEでゲームを作っているはずです!
HP:http://tenkoma.info Twitter:https://twitter.com/ONOZUKA7
=============================================================================
faida
記事: 272
登録日時: 2015年12月17日(木) 16:44

Re: 初期ステートのスクリプトについて

投稿記事by faida » 2016年9月06日(火) 12:19

抜粋個数を可変にするのは少しだけ複雑になります。

コード: 全て選択

class RPG::BaseItem
 def initial_state_ids
  return @initial_state_ids if @initial_state_ids
  if note =~ /^<初期ステート:(\d+(?:\s*\,\s*\d+)*)>/
    @initial_state_ids = $1.split(",").map{|s|s.to_i}
 end
end

class Game_BattlerBase
  def initial_state_ids
   feature_objects.collect{|a|a.initial_state_ids}.flatten.uniq.select{|i|i != 0}
  end
end
splitというのは文字列を区切り文字で分けた配列にするということです。
なので、"<初期ステート:1,2,3,4,5,6>"から["1","2","3","4","5","6"]が作れます。
mapとは配列を評価した内容で置き換えるということです。
["1","2","3","4","5","6"]から[1,2,3,4,5,6]とするのに必要になります。

また、実際に読み込むときは配列だらけになっているので
(例:<初期ステート:1,2,3,4><初期ステート:3,4,5><初期ステート:8>の3つを持つ装備をしていると
feature_objects.collect{|a|a.initial_state_ids}で取得できるのは [[1,2,3,4],[3,4,5],[8]] となります)
flattenで配列の中の配列を全部平坦化して([[1,2,3,4],[3,4,5],[8]] => [1,2,3,4,3,4,5,8])
uniqで重複を消すと使いやすいと思います([1,2,3,4,3,4,5,8] => [1,2,3,4,5,8])。

メモ欄の読み込みですが、私はどちらかというと以下の方法を使っている場合が多いです。

コード: 全て選択

class RPG::BaseItem
 def initial_state_ids
  return @initial_state_ids if @initial_state_ids
  if note =~ /^<初期ステート:(\d+(?:\s*\,\s*\d+)*)>/
    @initial_state_ids = eval("["+$1+"]")
 end
end
まぁ無理矢理感が溢れていますが。
------------------------------------------------------------------
自作の(改造でない)スクリプト、プラグイン素材に
関しては、リードミーもしくは作中に
「faida」と記名していただければ
利用可能です。
アバター
ONOZUKA
記事: 63
登録日時: 2015年11月11日(水) 13:31
お住まい: 幻想郷
連絡を取る:

Re: 初期ステートのスクリプトについて

投稿記事by ONOZUKA » 2016年9月08日(木) 02:27

split,map,uniq,flattenの処理内容について詳しく理解することができました。
正規表現というのが自分はいささか不慣れでして、既存のコードを読解する能力がありませんでした。
それゆえ、こうやって詳細に説明をくださるのは助かりました。ありがとうございます。

やり方は一通りでないというのがこの分野においては言えると思いますが、
自分の場合はループ構文などの初歩的な構造しか知り得ませんので、
ツクールの動作においてどの処理が一番軽いのかという判断については、
やはり経験者の方の研鑽された知識には及ばないと考えています。
ですので、一例がこうして示してもらえるだけありがたいです。
=============================================================================
RPGツクールVXACEでゲームを作っているはずです!
HP:http://tenkoma.info Twitter:https://twitter.com/ONOZUKA7
=============================================================================

“VX / Ace:質問” へ戻る