「EnDlEss DREamER」ブログ

最近はunity5メインで活動中。以前はツクールRGSSネタなど。

§ RGSS講座09「Win32API」RGSS・RUBYバージョン

騒音の研究所 様 Win32API解説
http://blog.livedoor.jp/htmltag/archives/51109509.html

RUBYリファレンス
http://webcache.googleusercontent.com/search?q=cache:aL0CLtw13Y0J:www.ruby-lang.org/ja/old-man/html/Win32API.html+&cd=1&hl=ja&ct=clnk&gl=jp

Win32API一覧
http://codepanic.itigo.jp/win32.html

レジストリ関連
http://www.kt.rim.or.jp/~yuta/prog/win32/Registry/index.html

pack unpack
http://webcache.googleusercontent.com/search?q=cache:g30MRaYNYG0J:www.ruby-lang.org/ja/old-man/html/pack_A5C6A5F3A5D7A5ECA1BCA5C8CAB8BBFACEF3.html+&cd=3&hl=ja&ct=clnk&gl=jp



1.使い方


a = Win32API.new('dll名', '関数名', 引数, 戻り値)
a.call(引数)


という形で使う。

で、皆さんが戸惑う「引数」「戻り値」の「型」というのがある。

p : ポインタ(文字列も)
i : 整数(int)
l : 数値(long)ハンドルなども。
v : void


というのが引数・戻り値の基本。

a = Win32API.new('GuruGuruSMF4', 'GGS4CloseDevice', 'v', 'v')
a.call()


guruguruSMFモジュールで使っているAPI呼び出しの一例。
引数がvoid型なのでvを指定している。
返り値もvoidなので何も値は返ってこない。

a = Win32API.new("GuruGuruSMF4", "GGS4Stop", 'i', 'v')
a.call(1000)


これは、GuruGuruSMF4.dllの中のGGS4Stopという関数の引数がiを指定している。
コールする時に引数に1000を渡す。
この関数の引数は音楽を停止してフェードアウトする時間(ミリ秒)で1秒かけてフェードアウトする。




2.ポインタを渡す


引数はstrとかdwordとかなんだかint型とかあるけど、それっぽいのを指定してやるといい。
文字列は全てポインタ。

で、たまに出てくる「ポインタの領域を確保する」ということ。
引数に渡した領域にWin32APiでコールした関数がその引数に値を格納して返す。
ということをやっている。


a = Win32API.new("GuruGuruSMF4", "GGS4GetPlayerStatus", 'pi','v')
status_size = (1.size) * 5 # int型のサイズ
status_value = "\0" * 256 # ポインタ領域確保
a.call(status_value, status_size)
result = status_value.unpack("I5")
return result



上から順に解説。
GGS4GetPlayerStatus関数はポインタの領域とサイズの2つを引数にしていて
返り値はvoid・・・つまり返り値はない。
status_sizeはGGS4GetPlayerStatusの引数で構造体の要素の数。ようは配列の数。
status_value がポインタの領域を確保している。
で、コールをする。
status_value.unpack("I5")はWin32APIの実行によってstatus_valueに格納された値を変換しています。
この場合は、構造体の要素がint型の要素が5つなので"I5"という指定になっています。
resultには配列で値が格納されています。
これでRUBYで使えるようになります。

引数に何かの値が格納されて返る場合の関数はこうした方がいいと思います。



3.文字コード


何かのファイルを読み込んでメモリに保存する。
なんていう関数が結構あります。
そういった場合に陥りやすい罠。
それが文字コードです。

RGSSはUTF-8・ユニコードです。
Win32APIで入れる場合は「シフトJIS」なのです。
でないと読み込み時にエラーを吐きます。
変換するにはどうすればいいか??

RGSSにはNKFがあります。
なので・・・

str = NKF::nkf("-s", text)

でシフトJISに変換されます。
ちなみにUTF-8に変換の場合は・・・

str = NKF::nkf("-w8", text)

です。


NKF変換一覧。

-j JISコードを出力する。
-e EUCコードを出力する。
-s シフトJISコードを出力する。
-w -w8[0] -w16[BL][0] Unicode を出力する。
-w -w80 UTF8コードを出力する。(BOM無し)
-w8 UTF8コードを出力する。
-w16 -w16B0 UTF16コードを出力する。(Big Endian / BOM無し)
-w16B UTF16コードを出力する。(Big Endian / BOM有り)
-w16L UTF16コードを出力す る。 (Little Endian / BOM有り)
-w16L0 UTF16コードを出力する。(Little Endian / BOM無し)


4.最後に


Win32APIはRGSSで唯一外部DLLを読めます。
が、呼び出せるだけでそれをCみたく組み込んで使えるわけではないので
自分でラッパーを作成する必要があります。
今回のguruguruSMFもググってRUBY用のラッパーがあったので完成しましたが
結構、面倒な作業です。
若干のCとか型とかどーとかの知識が必要になってきます。
DLLを自作される方は神ですね。
私には全くできません。
今回は、特に2と3辺りの解説で苦労したのでやってみました。
何かの参考になればと思います。


2013/02/08/Fri 00:22:59  RGSS講座/CM:0/TB:0/

§ 「RGSS2 Playerは動作を停止しました」対策

「ハードウェアDEP」が原因です。
なんて言ってるけど、解決しないことの方がほとんど。

http://tkool.jp/support/faq/general/dep.html


ググったら別の解決方法があり、試した結果よかったので皆さんも苦しんでいたらお試しアレ。



古いバージョンのエディタ(1.00とか1.01)で作られたゲーム「RGSS200J.dll」のエラー落ちを回避するには
ゲームのプロジェクト内にある「Game.ini」をテキストエディタで開く。
すると次のような内容が記述されている。


[Game]
RTP=RPGVX
Library=RGSS200J.dll
Scripts=Data\Scripts.rvdata
Title=Project5


この「Library=RGSS200J.dll」を「Library=RGSS202J.dll」に変更する。
因みにこのファイルはRTPをインストールすると

「C:Program Files\Common Files\Enterbrain\RGSS2\RPGVX」

に作成されるのでちゃんと自分のPCに「最新版のRTP」がインストールされていることが前提。
古いRTPでもエラー落ちが予想されるので、既にRTPあっても最新版を一応入れておく。
ちなみに今のツクールVXのバージョンは「1.02」が最新版。
プロジェクト内の「Game.ini」の「Library=RGSS202J.dll」に変更する。
落ちる場合はこの方法を試してみて下さい。


強制終了の原因の一つを発見!
Spriteを「2重に解放(dispose)」するような処理を行うと落ちます。
ヘルプでは「何もしない」って書いてあるんですけどね。





2011/09/05/Mon 18:09:43  RGSS講座/CM:2/TB:0/

§ RGSS講座08「競合対策」

久しぶりのRGSS講座~~~♪
基本的な所は全部やっちゃってるんで、皆さんが素材を導入して一番苦労するところ・・・

「競合」

について解説したいと思います。



一言で「競合」と言っても原因は沢山あります。

http://www5f.biglobe.ne.jp/~delusion/index.html

「Delusional Field」様の所にある「RGSSエラー対策」で基本的なエラーが解説されています。

http://wiki.quiet-labs.net/

「静寂の研究所」様の「エラーメッセージ改良」を利用すると更にエラーの原因が追及しやすくなります。



・再定義について

大抵は「alias(エイリアス)」を使って再定義します。正確には「別名定義」といいます。

class Item

 def self.hoge
  'hoge'
 end

 class << self
  alias :fuga :hoge
 end

end


Item.hoge # => hoge
Item.fuga # => hoge



というように「Itemクラス」の「hoge」メソッドをエイリアスすると「fuga」が使えるようになります。
実行結果が「同じ」と言うのには理由があります。
エイリアスを実行すると「別名定義」の名の通り、別の名前でメソッドを作り何かをしたいのですが
「元の名前」メソッドは「保持されている」ので、新たに別名で定義するときに
元のメソッド名を新たなメソッド内で使用することで、元のメソッドの記述が実行されます。
平たく言えば、スーパークラスの同じ名前のメソッドを実行したいときの「super」のメソッドと似てます。



 #--------------------------------------------------------------------------
 # ● 終了処理
 #--------------------------------------------------------------------------
 alias ed_battle_layout_terminate terminate
 def terminate
  format_battler
  $ed_battle_layout_surprise = nil
  dipose_enemy_hp
  if $ed_rgss2["ed_active_time_battle"]
   dipose_enemy_atb
  end
  ed_battle_layout_terminate
 end


これは「バトルレイアウト変更:scene」の記述の一部です。
これもエイリアスを使って定義しています。
「terminate」メソッドを「ed_battle_layout_terminate」という名前で別名定義しています。
なにやら少々記述がありますが省略。
最後に「ed_battle_layout_terminate」というエイリアスしたメソッドを記述しています。
これは「元のメソッド」つまり「terminate」メソッドを実行しているのです。
そうすることで、わざわざコピー&ペーストしなくてもこの記述一つで変更内容を実行しつつ
元のメソッドの働きも行うことが出来ます。


ですが、実はそこに罠も潜んでいます。
元のメソッドが実行されるので、記述内容によっては変更しても元のメソッドで値が元に戻ってしまう。
または、追加したメソッドや値が元のメソッドには存在しない為にエラーが発生する。
などなど、エイリアスは決して万能ではないのです。



そこで「本当の再定義」を使用したりします。
「本当の再定義」とは、元のメソッド名と同じ名前でまた作ること。
そうした場合、元のメソッドは同じ名前で作った時点で無関係となります。
ツクールの場合は、「上にあるスクリプト」より「下にあるスクリプト」が優先されるので
先のバトルレイアウト変更の例の場合は「Scene_Battleクラス」と「バトルレイアウト変更:scene」が関係しており
エイリアスを使わない場合はScene_Battleの「terminate」の記述をコピー&ペーストする必要があります。
なぜならば、Scene_Battleのメソッドはバトルレイアウト変更:sceneのメソッドの時点で無効化されるからです。


使い道としては、元のメソッドの記述の途中で処理を別に行いたい、追加したいなどなど
エイリアスで語った「罠」を回避する場合に使ったりします。



・競合とは?

上記で語った「再定義」で何らかのメソッドが値を失い「nil」となりエラーを吐く場合が多いです。
ツクールでは色んなサイト様から様々な素材を導入するわけですが
よく「導入位置」を指定している場合があります。
それは、素材により「再定義」しているヶ所が多いとか「本当の再定義」で素材導入位置までの
メソッドが無効化されてしまうから上部にとかで指定している場合があるのです。

例として「バトルレイアウト変更」を導入したとします。
次に「バトルレイアウト変更:extension」を導入したとします。
extensionの導入位置は「「scene」の直下に。」なので、通常はバトルレイアウト変更:sceneの真下に入れます。
これをバトルレイアウト変更よりも上に入れるとエラーを吐きます。
なぜならば、バトルレイアウト変更で定義されていないメソッドや値を実行しようとするからです。
更に「戦闘キーアクション追加」を導入する場合は「バトルレイアウト変更及びextensionよりも下」なので
それらよりも下に導入すると動作します。

実はこれらのスクリプトは「def execute_action_skill」が共通して「本当の再定義」が行われています。
上記3素材を「A」とします。
別素材を「B」としたときに、「def execute_action_skill」がエイリアスで再定義されている場合の
素材導入位置は何処になるでしょうか??

正解は「Aの下」になります。
Aで再定義が行われてAまでの「def execute_action_skill」の記述が無効化されます。
なのでAより上にBを導入してもAの素材で無効化されます。

では「B」でも「本当の再定義」が行われた場合はどうすればいいのか?
それはBの「def execute_action_skill」内でAの「def execute_action_skill」の記述をコピー&ペーストする。
そうすることで、AがBで無効化されてもBの中でAの内容が記述されていればエラーは出ません。



というように「導入する素材」「どの部分を再定義しているのか?」というのを理解することで
導入位置を変更するだけで解決するのか、エラーが出た場合には他に導入している素材と
共通するメソッドを見つけ出し、どの素材の、どのメソッドでエラーが出るのかを発見することが出来ます。

ツクールは「Vocab」から順に下に実行して「Main」で最終的な動作をします。
逆に言うと「Main」までは「下準備」なので、ゲームは動いていません。


・F12リセットエラー

「F12」をゲーム中に押すとリセットされます。
通常は大した気にならないのですが「RPGモジュール」などをエイリアスする場合に絡んできます。
普通に実行してウィンドウごと消せばうまく実行するが、F12でリセット後だとなぜかエラーが出る。
と言う場合に「unless $@」を入れると上手く動きます。

「$@」は例外情報を格納する変数で、F12を押すと例外が発生したことになっているみたいです。
一度しか実行しないはずのものを値が保持されたまま再度実行されてエラーが発生するとか
requireのように一度しか実行されず、リセットした場合は実行されないなど
リセットしたらどっかでエラーが起こった場合に利用するとリセットエラーを回避できます。

詳しくは「http://piscis.shime-saba.com/index.html」にて解説されています。




長々と語りましたが、競合は何かと面倒です。
単純な素材なら競合は少ないでしょうが、複雑な素材を複数導入する場合には覚悟が必要です。
競合解決の第一歩は「導入位置」
次に「どのクラス」「どのメソッド」を利用しているのか?
というのを調べて、またはテストプレイしてから競合対策していく必要があります。

私の場合は「自分の素材同士の競合」は解決してからUPするようにしていますが
数多くあるサイト様のスクリプト素材の競合までは面倒みれません。
なぜなら、導入する素材によって競合ヶ所など星の数だけ発生する可能性があるからです。

この解説がスクリプト導入の際に役立てればと思いますm(__)m








2011/07/08/Fri 20:34:35  RGSS講座/CM:0/TB:0/

§ RGSS講座07「複数画像ファイルの合成方法」

今回の講座は講座と言うよりもRGSSテクニックというような感じでしょうか。
RGSSの仕様上、こういった機能があれば便利だし出来るのに・・・
というような事を無理矢理やってしまおうというド忘れ防止メモも含みのネタ。


・前置き

今回は複数画像ファイルの合成方法ということで画像を扱うネタ。
通常画像をゲーム画面に表示するには「Spriteクラス作成」 → 「sprite.bitmap = bitmap.new」
などをやって「スプライトを作成してから」「スプライトに使用する画像をロード」という手順です。
RGSSの仕様上「bitmapクラスには1つの画像しか指定できない」というものがあります。

いや、もしかしたら数多の素材屋さんで公開してらっしゃる「bitmapクラス拡張」の素材で簡単にどうにかなるかも知れません。
俺の場合は「ググるのに疲れた」という理由で断念しました。
ともあれ、今回はこの「画像ファイルを1つしか使えないbitmapクラス」をいじることなく画面に重ねて表示します。


・方法

bitmapクラスはどうやっても1つの画像しか表示されないため、残された手段は・・・「Sprite」となります。
ウィンドウやアニメーションも複数のスプライトから構成されています。

今回は「Sprite_Battler」を重ねて表示しようと思います。
このクラスは通常「敵キャラ」のみを表示します。
うちの「バトルレイアウト変更」ではサイドビューもやるのでアクターも歩行グラを使って表示します。

通常、このクラスは「self.bitmap」でクラス自体に画像データをロードさせて表示しています。
対してこのクラスのスーパークラス「Sprite_Base」はアニメーションの表示を行なっています。
ベースクラスでは「self.bitmap」というものは存在しません。

ではどうやってるか??

答えはセルデータ15個分のスプライトを作成してインスタンス変数の配列に追加。
アップデートする時に作成した15個分のループを行ないその中にインスタンス変数の配列からからローカル変数に格納。
そこでデータベースの設定に応じてローカルスプライトに画像を設定→更新。という手順。

つまり「クラス内に別途スプライトを作成して表示している」ということです。



これを応用してSprite_Battlerクラスを考えてみる。
歩行グラを2つ重ねて表示してみる。
「initialize」メソッドに「重ねる個数分のスプライトを作成」する。

@battler_sprites = [] # スプライト格納用配列
for i in 0..1
# この場合は2つの画像を重ねたいのでこういった指定
@battler_sprites[i] = Sprite.new(self.viewport)
end



インスタンスにスプライトを格納したら、その後大事なことは「self.bitmap」には「空のbitmap」を入れておくこと。

self.bitmap = Bitmap.new(32, 32)

アクターの歩行グラを使用するとしてサイズは「32*32」なので画像を指定せずにビットマップを入れないと
アニメーション表示などで座標がズレるので忘れずに設定。
次に、2つのスプライト「@battler_sprites[0]」と「@battler_sprites[1]」にビットマップを設定してやる。

@battler_sprites[0].bitmap = Cache.character(@battler_name)

これは歩行グラを読み込んで作成したスプライトのビットマップに使用する画像を設定する。
その後、2つのスプライトの原点座標「oxとoy」に本体の原点座標「self.oxとself.oy」設定。
この場合は歩行グラを2つ重ねるので一通りの座標は全部同じにする。
なので他の「x,y,width,height」に始まって「mirror,visible」なども同じく設定。
動く場合はアップデートメソッドに入れておく。

src_rectなどの設定は今回は割愛。
平たく言えば「sprite.bitmap」は画像全部。「sprite.src_rect」は画像の中の表示する範囲指定。

今回は「歩行グラ」を自動でサイズ取得して配列で返すメソッドを記載。
使う場合は「Game_Actor」か「Game_Battler」クラスに「battler_name」の「アクセサ」を用意するのを忘れずに。

  #--------------------------------------------------------------------------
  # ● バトラーグラフィックのサイズ取得
  #--------------------------------------------------------------------------
  def battler_bitmap(battler)
    sign = battler.battler_name[/^[\!\$]./]
    if battler.is_a?(Game_Actor)
      a_bitmap = Cache.character(battler.battler_name)
      if sign != nil and sign.include?('$')
        battler_width = a_bitmap.width / 3
        battler_height = a_bitmap.height / 4
      else
        battler_width = a_bitmap.width / 12
        battler_height = a_bitmap.height / 8
      end
    elsif battler.is_a?(Game_Enemy)
      e_bitmap = Cache.battler(battler.battler_name, battler.battler_hue)
      if sign != nil and sign.include?('$')
        # 歩行キャラ使用のバトラーの処理
        battler_width = e_bitmap.width / 3
        battler_height = e_bitmap.height / 4
      else
        battler_width = e_bitmap.width
        battler_height = e_bitmap.height
      end
    end
    # 値は配列で返す
    battler_size = [battler_width, battler_height]
    return battler_size
  end


この手順でスプライトは重ねて表示されるようになります。
つまり・・・


「Sprite_Battler」自体は「大枠」で「背景」
内部に作られた2つのスプライトは「表示要素」ということである。
それぞれ制作者側によって使う画像や用途が違うので座標設定や描画範囲についてはかなり変わると思うけど
内部に別のスプライトを作成して、それ自体のスプライトを背景として使うことで複数の画像を表示します。
これなら設定は面倒かも知れませんが仕組み自体は難しくないのでやってみてはいかがでしょうか?






2010/04/24/Sat 03:37:43  RGSS講座/CM:0/TB:0/

§ RGSS講座06「メモ欄と正規表現」

・メモ欄の取得

ツクールのヘルプで「note」で検索すると「RPG::BaseItem」「RPG::Enemy」「RPG::State」の3つが出ます。
コレって言うのはつまり「スキル」「アイテム」「武器」「防具」「敵キャラ」「ステート」の設定項目ですね。
実際の記述では・・・

item = @item.note

となります。

メモ欄は言うまでもなく「文字列」なので「Stringクラス」です。
で、皆さんが気になるのは「どうやってメモ欄の文字を取得させるか?」ということですね。
その辺りが次の項目となります。


・正規表現(Rage_xp)

説明が難しいのですが「文字列クラスの一つ」という感覚で覚えればいいと思います。正確には違うのですが細かいことはまぁ・・・

正規表現は

「/」で始まり「/」で終わります。

str = "あいう"

if /(あいう)/ =~ str
 処理
end


「=~」「正規表現 =~ 文字列」でマッチするかどうか調べるメソッドです。

(あいう)のように()でくくっているのは「グループ化」というもので、「あいう」の3文字にマッチします。

str = "あいう"
rage = "あいう"

if /#{rage}/ =~ str
 処理
end


上記例文で出てくる「/#{rage}/」があります。
「//」は先に説明した通り、正規表現に必要な始まりと終わりです。
「rage」には文字列「あいう」が格納されています。
「#{}」は「正規表現の中で変数を使う」為の記述です。
他にも色々あるのですが、参考書なりヘルプなりを参照して調べるといいでしょう。
あとでも必要箇所は説明していきます。


・メモ欄から取得してマッチさせる

こっからが本番です。


#==============================================================================
# ■ Scene_Battle
#------------------------------------------------------------------------------
#  バトル画面の処理を行うクラスです。
#==============================================================================

class Scene_Battle < Scene_Base

#--------------------------------------------------------------------------
# ● スキルアニメのメモ欄取得
#--------------------------------------------------------------------------
def skill_anime_memo(skill)
 skill_note = []
 a = skill.note.scan(/<#{COUNTINUITY_ANIME_MEMO}[::](\d+(?:[ ]*,[ ]*\d+)*)>/)
 unless a == [] and a.empty?
  $1.scan(/\d+/).each { |num|
  skill_note.push(num.to_i)}
  @skill_continuity_anime = skill_note
 else
  @skill_continuity_anime = []
 end
end


「連続アニメーション」の記述の一部を出してみました。
このメソッドは「skill_anime_memo」というメソッドで引数に「skill」を取得するようにしています。
この実行元が「execute_action_skill」メソッドで「skill = @active_battler.action.skill」がメソッド内に
記述されて「skill」に攻撃者の使用スキルが格納されます。それを引数として「skill_anime_memo」を実行しています。


a = skill.note.scan(/<#{COUNTINUITY_ANIME_MEMO}[::](\d+(?:[ ]*,[ ]*\d+)*)>/)


が引数「skill」のメモ欄を取得してマッチしています。
このスクリプトでは「<連続アニメ:10,20,30>」とメモ欄に記述して連続でアニメーションを表示します。
まず「.scan(正規表現)メソッド」は文字列を正規表現で検索してマッチした部分を「配列」で返します。
「/」で始まるのは説明した通り。
次の「<」は単なる文字でメモ欄記述の「< 内容 >」の両端ですね。
「#{COUNTINUITY_ANIME_MEMO}」も説明した通り正規表現内での変数使用です。
この「COUNTINUITY_ANIME_MEMO」は定数で「連続アニメ」の文字列が格納されています。
「[::]」で「[ ]」はマッチさせたい文字の集合で、この場合は「半角のコロン」と「全角のコロン」をマッチさせています。
ここまででメモ欄の「<連続アニメ:」までの説明が終わりました。



次に数字のマッチを行ないます。
「()」は先に説明した通り「グループ化」で括弧内にマッチしないといけません。
「\d+」というのは「\d」で「0~9の数字にマッチ」して「+」は「1回以上の繰り返し」という意味です。
これで「何桁もの整数」にマッチするようになります。
「(?: )」「後方参照を伴わないグループ化」「$1」などに入らない「単なるグループ化」の為の記述です。
「[ ]*」は半角スペースの文字列と「*」が「0回以上の繰り返し」で「,(カンマ)」は文字通りカンマの文字。
でまた「[ ]*」で半角スペースのマッチを行ない、「\d+」で数字のマッチを行ないます。
「(?: )」の終わりに「*」を付けることで「(?: )」の「0回以上の繰り返し」にマッチさせています。
そして「[::]」の直後の「(\d+(?: )*」の「*」の後に「)」を付けて「(\d+(?: )*)」となり
「[::]」以降の括弧のグループ部分が終わります。
この括弧では「\d+」最初のグループの中「繰り返しマッチ」させる「(?:)」のグループが内包されています。
既にグループの中のグループなので「後方参照しない単純なグループ化」ということなのです。
で、最後に忘れずに「>」を入れて「/」で正規表現を終えています。

つまり

<連続アニメ:(100( , 999)*)>

という表現となり「(, 999)」の部分は「0回以上の繰り返し」で単なるグループ化により最初の「100」の部分以降は
いくら付け足してもいいということになります。
なので「<連続アニメ:100,999>」とメモ欄に表記すれば「skill_anime_memo」でマッチするというわけです。
いくらでも付け足して良いので「<連続アニメ:1,2,3,4,5,6,7,8,9,10,11,12,13・・・>」でもマッチします。



・後方参照

先の説明でメモ欄の文字をメソッド内でマッチさせて結果を「a」という変数の中に「配列」として格納されました。

unless a == [] and a.empty?

で「a」の配列が「[]」空っぽなのか「empty?」配列の要素数が「0」のとき真を返すメソッドで「true」なのか?
を判断しているのですが「if」ではなく「unless」なのでこの場合は逆の意味で
「配列が空っぽでなく、配列の要素が0ではない場合」に次の処理へと移ります。
unlessの先にあるのが「$1」というのがあるのですがこれはヘルプから抜粋で
「最後に成功したパターンマッチで n 番目の括弧にマッチした値が格納されます。該当する括弧がなければ nil が入っています」
マッチに成功したなん番目の括弧がこの「$1」で、この場合は「1番目の括弧」にマッチした値が格納されています。
つまり「(100,999)」の部分が「文字列」で格納されています。

  $1.scan(/\d+/).each { |num|
  skill_note.push(num.to_i)}
  @skill_continuity_anime = skill_note


$1の中に格納されている文字列をさらに正規表現でマッチをしていきます。
この場合は「\d+」だけなので数字だけにマッチするようにしています。
「scan」メソッドはマッチした結果を「配列」で格納します。
その配列を「each」メソッドでさらにブロック評価を行ない個別に処理していきます。
「skill_note」はローカル変数で最初に「skill_note = []」で空の配列を作成してます。
eachによる評価結果を「skill_note」に追加しているのですが「to_i」メソッドで「文字列」を「整数」に変換しています。
メモ欄からの取得は「文字列」による取得なので「"1"」のように1という文字で格納されているのを数字に変換します。

@skill_continuity_anime = skill_note

で追加し終わったskill_noteをインスタンス変数に入れてます。
これによってScene_Battleクラス内でアニメーションの表示に使えるようになります。


・おわりに

この正規表現はかなり面倒な部分で色々とややこしいです。
ヘルプや辞書を引っ張りながら、他の人のスクリプトではどういった記述をしているかなど
調べながらやっていくといいです。

http://www.rubular.com/

ではサイト上で正規表現の記述が正しいかどうかをマッチングしてくれます。





2010/03/14/Sun 15:28:44  RGSS講座/CM:1/TB:0/
MAIN / NEXT
copyright © 2006 「EnDlEss DREamER」ブログ. All Rights Reserved.
Template by TAE-3rd☆テンプレート工房