魔劍工舖

關於部落格
RPG製作大師XP腳本為主要更新

RPG製作大師VX腳本為其次更新

RPG製作大師VX_Ace目前不考慮

RPG製作大師MV腳本完全沒打算

留言完建議重新整理看看是否顯示

目前不處理本舖外腳本的相關問題

其他相關事項請觀看規定注意事項

本舖未來的經營計畫與VA的支援




var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-37462754-1']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

  • 296198

    累積人氣

  • 10

    今日人氣

    0

    訂閱人氣

基本函數教學


定義函數
一打開腳本,可會看到很多藍色def的字樣到處都是
寫法和條件分歧類似,def右邊設定函數名稱,接著下一行開始到這個函數的end 
都是該函數的執行內容(可以想成是公共事件中的事件執行內容也不為過)
也可以說大部分腳本都是透過函數來組成,呼叫來呼叫去的~~寫法就像這樣: 
def 函數名稱
  執行內容
end
函數名稱通常可以隨意自定,可英文也可以,用中文也無所謂
基本上函數名稱的命名規則和局部變量的命名規則是差不多的
開頭小寫英文或任意全型符號或_符號或是中文字,開頭名稱決定好後
和變量一樣,後面限制就變少了,如可以用半型數字之類的...
通常函數內的執行內容通常不會真的執行(但會開始遊戲時確認是否有錯誤腳本寫法)
只有在你呼叫的這個函數的時候,則函數中的執行內容才會開始執行
隨然剛剛說了會檢查是否有腳本錯誤寫法,但要檢查過一次後該函數才有辦法執行  
 
呼叫函數
呼叫函數的方式很簡單,就是打出函數的名稱,不加任何內容即可呼叫
def sword_boss
  p 123
end
sword_boss
#=> 123
執行後會跑出一個小窗口顯示123,如果把第4行給刪掉後就什麼事情也不會發生了
上面說過,沒呼叫這個函數,通常是不會去實際執行函數中的腳本的
此外名稱必須完全符合,打成『sword_bosss』或是『sword_bos』可能因找不到該函數....
觸發NameError異常,也就是找不到函數的意思!!
 
函數的執行流程
這個在畫面運行說明有提過,當呼叫一個函數後,則呼叫的函數執行完的時候
接著會執行哪裡??,這個就和用事件呼叫公共事件的特性一樣了!!
也就是當你呼叫函數時,當那函數執行完了之後
就會回到呼叫該函數的那行腳本繼續開始往下執行
def sword_boss
  p 2
end
p 1
sword_boss
p 3
執行後會依順序跑出3個小窗口,分別顯示1,再來是2,接下來是3
 
返回值
通常...函數執行結束後,會採用最後的值作為該函數的返回值
如果都沒有值的話,則通常是返回nil這個值,但究竟什麼是返回呢??
看看以下範例吧!!
def sword_boss
  505
  128
  762
end
p sword_boss #=> 762

def sword_boss
end
p sword_boss #=> nil

def sword_boss
  a = 5
  b = 14
  a + b
end
p sword_boss
#=> 19
從以上範例可以看出
你呼叫函數的那個腳本可以說是視同為該方法最後執行到的值
所以...依第一個範例還說『p sword_boss』和『p 762』是一樣的
這就是所謂的返回,將方法執行最後的值傳回給呼叫函數的腳本!!
此外通常是先計算好後在返回,所以第3個範例是先計算完『a + b』
也就是5+14,獲得的答案19後在返回到呼叫的函數之中
 
函數與局部變量的分辨
可能有些人有疑問了,只要打出函數的名稱就可以呼叫該函數
那假設有個局部變量和函數同名會有什麼結果呢??
def sword_boss
  100
end
sword_boss = 12
p sword_boss #=> 12(依上面說過的返回值,原本因該為顯示100)
def sword_boss
  p 123
end
sword_boss = 5
# 什麼事情都沒發生
第1個範例中測試結果不是獲得100,而是獲得12
但是這樣並不代表函數的執行內容變成12喔
實際上是被認定為局部變量而不採用呼叫函數的動作
也就是說當你代入數值時,那段函數名稱就不能拿來呼叫函數了!!
只能當成變量使用,由於該名稱被當成變量了
所以範例2實際上沒有去呼叫函數,所以沒有跑出寫著123的小窗口
簡單來說只要名稱沒有代入過任何東西,才會視同是呼叫函數的指令
所以有時候看腳本時,可以看看該函數執行內容上面是否有代入的動作判斷是否是變量
如果再函數中沒發現代入的動作,那很有可能是呼叫函數了
此外...如果該函數名稱已被當成是局部變量,又想再呼叫該函數的話
則可以在左邊添加『self.』,這樣就會一律呼叫該函數,不會被當成變量
def sword_boss
  12
end
sword_boss = 35
p sword_boss #=> 35
p self.sword_boss
#=> 12
 
中斷函數
如果你想要有像事件 [中斷事件處理] 之類的腳本的話
確實是有個可以立刻中斷該函數的指令,可以使用腳本『return』來中斷
def sword_boss
  p 1
  return
  p 2
end
sword_boss
執行後只會跑出一個窗口顯示1,也就是說腳本沒有執行到『p 2』這行腳本
也就是被『return』中斷而提早結束了這個函數所致
可能有人會想,放這個有啥意義??一放後『return』下面的腳本不是都沒用了?
這時就可以善用條件分歧決定是否要執行,可以達成依照條件決定是否繼續執行的效果
此外...由於函數被『return』給中斷了,所以返回值通常是nil
這時其實可以在『return』右邊添加返回值,像這樣『return 』即可
def sword_boss
  1
  return 3
  2
end
p sword_boss
#=> 3
 
定義的位置
函數有個特性,那就是該類(classend 的範圍為類)或是模塊(moduleend 的範圍為模塊)中
你在哪個類或是模塊中呼叫某個函數時,則那個呼叫的函數必須也是同個類或是模塊(以下只稱類)
所以不能夠呼叫不同的類的函數,所以只要類不相同,有相同名稱的函數存在也是可行的!!
class Sword_Class
  def initialize
    sword_boss
  end
  def sword_boss
    p 123
  end
end
Sword_Class.new
#=> 123
腳本『類名稱.new』為呼叫類的方式,呼叫了類之後,會自動去執行該類的initialize函數
所以可以看出流程了吧,呼叫類 → 自動執行initialize函數 → 執行sword_boss函數 → p 123
為何這樣寫??難道在類裡面但在函數範圍外面不能呼叫該類的函數嗎??沒錯
class Sword_Class
  def sword_boss
    p 123
  end
  sword_boss # NameError
end
這樣會觸發找不到該函數的NameError異常......
總之要呼叫該類的函數,則必須在該類的函數中進行呼叫!!
此外...如果函數是定義在外面的話,通常隨便你怎麼呼叫都行了!!,如下
def sword_boss
  p 123
end
class Sword_Class
  sword_boss #=> 123(在類裡,但不再函數裡,會自動執行1次)
end
def sword_boss
  p 123
end

class Sword_Class
  def initialize
    sword_boss
  end
end
Sword_Class.new
#=> 123
 
呼叫函數(類與模塊)
上面剛剛說到,只能在同個類的函數中呼叫這個類中的其他函數
那是否有辦法在除了這個類以外的地方進行呼叫呢??
如果想要這麼做的話,就必須在產生這個類,然後可以在呼叫這個類的腳本中
最右邊加個 . 符號,接著在指令該類的函數名稱即可
class Sword_Class
  def sword_boss
    p 123
  end
end
Sword_Class.new.sword_boss
#=> 123
其實範例最後一行腳本,new其實是一種類的函數,呼叫類都必須加上『.new』
也就是呼叫new函數(這函數也是在內部中定義的,也是腳本編輯器裡找不到的!!)
當生成一個類之後,才呼叫sword_boss方法才顯示出123這個小窗口
這種最右邊添加『.函數名稱』也是一種函數的呼叫方式之一
用於類與模塊中的函數進行呼叫的動作
此外...類是能存入在變量中的,因該說Ruby(RGSS採用的程式語言)幾乎看到的東西都是類
數字是類、數組是類、字符串也是類,到處看到的東西都是類...
所以當我們代入某數值時,也可以說是代入一個數值的類!!
這些類都是在內部類裡面的(總之不再腳本編輯器裡就對了...,寫法也看不到,除非........)
假設將一個類代入到某變量之時,那要如何去呼叫這個類中的方法呢??
class Sword_Class
  def sword_boss
    p 123
  end
end
a = Sword_Class.new
a.sword_boss
#=> 123
其實這個和直接用『Sword_Class.new.sword_boss』差異不大,但這都是產生新生成的新類
所以該類的資料都會重製為全新的,不想這樣的話就將類存到變量中就可以重複使用了
呼叫函數也也只要對存入該類的變量右邊附加『.函數名稱』即可呼叫變量中的類的函數
 
寫入函數
以上說的全都是讀取類型的函數,也就是直接輸入函數名稱即可呼叫該函數
寫入函數和讀取函數的用法不同,寫入函數則是使用代入的方式進行呼叫函數的動作
如果是直接輸入函數的名稱是無法呼叫的,會跑出找不到的錯誤訊息(會視為不同函數)
寫入函數的定義方式,就是在函數名稱右邊添加『=(量名稱)』
當定義為寫入函數之時,則必須使用和變量相同的方式進行呼叫!
此外呼叫時,呼叫的腳本左邊必須添加『self.』才可,不然會被當成是局部變量進行代入
如果是使用在右邊添加『.函數名稱』的呼叫方式的話,則寫入函數的呼叫不需要添加『self.』
def sword_boss=(a)
  p a + 30
end
self.sword_boss = 100 #=> 130
class Sword_Class
  def sword_boss=(a)
    p a - 5
  end
end
Sword_Class.new.sword_boss = 35
#=> 30
順便題一下,在定義實例變數的文章中,有介紹可讀、可寫、可讀寫的腳本
實際上那3個腳本嚴格來說是產生寫入函數或讀取函數的簡寫而已
以下的寫法其實效果是一樣的!!
# attr_writer     :變量名稱(只可寫)
def 變量名稱=(變量名稱)
  @變量名稱 = 變量名稱
end
# attr_reader     :變量名稱(只可讀)
def 變量名稱
  變量名稱
end
# attr_accessor :變量名稱(可寫可讀)
def 變量名稱=(變量名稱)
  @變量名稱 = 變量名稱
end
def 變量名稱
  變量名稱
end
由於呼叫的函數不同(視為不同函數),所以這是定義實例變數的寫入函數嘗試讀取會出錯的原因
順便提醒一下,寫入函數沒有返回值可以使用,就算使用『return 』也一樣沒有
硬p出來的話,也只能p出你剛剛代入的值而已,但該函數還是有照常執行
def sword_boss=(as)
  p 123 # 確認函數是否有成功執行用
  456
end
p self.sword_boss = 10 # 先出現123,在出現10 
def sword_boss=(as)
  return 555
end
p self.sword_boss = 10
#=> 10
 
參數
局部變量有著同個函數才有效的特性,當這個函數執行完後
這個局部變量也會跟著消失變為無定義的狀態
有時候我們可能想把一個值傳到某個函數中來使用
用其他種類的變量雖然能解決這問題(如:全局變量)
不過用多了往往會造成混亂,所以我們可以設個參數來將數值傳遞到該函數之中
參數的定義方式很簡單,只要在讀取函數的函數名稱右邊添加( )然後在框裡指定變量名即可
然後呼叫該函數的時候,也要在右邊加上( )並輸入要傳遞到該函數的值
def sword_boss(a)
  p a
end
sword_boss(155)
#=> 155
def sword_boss(a, b, c)
  p a + b - c
end
sword_boss(12, 5, 6)
#=> 11
sword_boss(7, 9, 3) #=>13
範例1執行後,會將155這個值存到局部變量a中,所以範例第2行實際執行了『p 155』
如果要傳遞2個以上的參數,可參考範例2,只要在函數名稱右邊的( )在添加1個變量名稱
每個參數的變量名稱必須要使用小逗號 , 來進行分開,呼叫函數的腳本也要這樣做才行
此外要注意一點,當你指定了需要的參數數量之後
則呼叫函數的腳本,也必須要傳遞對應數量的值過去
多一個或少一個參數都不行,傳遞數量一定要剛好,不然會觸發ArgumentError異常 
def sword_boss(a, b, c)
  p a + b - c
end
sword_boss(10) # ArgumentError: 參數需要3個你卻只給了1個
def sword_boss
  p 123
end
sword_boss(10, true)  # ArgumentError: 參數需要0個你卻只給了2個
 
默認參數(預設參數)
和參數差不多,只不過呼叫時可以不必一定要給出參數不可
要指定默認參數,只要在函數名稱指定的參數的變量名稱右邊添加 = 符號
然後再指定預設的值,像這樣『 = 』,當沒有給出這個參數時,就會採用設定的值
def sword_boss(a, b = 5)
  p a + b
end
sword_boss(5, 8) #=> 13
sword_boss(5)
#=> 10
def sword_boss(a = 10, b = 5)
  p a + b
end
sword_boss
#=> 15
範例1中,第4行的呼叫方式給了2個參數,所以變量a為5;變量b為8
而第5行只給了1個參數,所以變量a為5;變量b由於沒有傳遞的參數
所以採用預設值5,所以變量b則為5
這樣的話,所需參數就可以想成是需要1個或2個
所以參數傳遞1個或2個時不會觸發ArgumentError異常 
但是給0個或3個以上照樣會觸發ArgumentError異常 
如果像範例2這樣連第1個參數也是默認參數的話,則也可以不給參數也沒關係了!!
此外要注意一點,當指定默認參數時,則右邊的參數則一律要設為默認參數
不然會觸發SyntaxError異常 
def sword_boss(a = 5, b) # SyntaxError
  p a + b
end
 
多重參數
以上教的參數的數量都有限制,一旦超出或是過少就會觸發ArgumentError異常 
假設可以提供的參數沒有數量上的限制,那要怎麼辦??
怎不可能設好幾百個默認參數吧?!這樣太麻煩了,這時可以用多重參數
只要在參數的變量名稱左邊添加 * 符號就行了,這樣參數給多少都沒問題
會以數組的形式將所有參數存到指定的變量中
def sword_boss(*a)
  p a #=> [12, 88, 55, nil, 11, [12], 5222]
end
sword_boss(12, 88, 55, nil, 11, [12], 5222)
def sword_boss(a, b, *c)
  p a #=> 12
  p b #=> 88
  p c #=> [55, 0, 11, 12, 5222]
end
sword_boss(12, 88, 55, 0, 11, 12, 5222)
# 註:需要2個以上的參數,不給參數或只給1個會錯誤
def sword_boss(*a)
  p a #=> []
end
sword_boss
當指定多重參數之時,要給多少參數都行,沒有參數上限的限制,不給參數也行
也可以想像成是加了『= []』的默認參數也不為過~~
但要注意,多重參數只能放置在參數的最右邊,不然的話當然就出錯
如果有用塊參數(等會說到)的話,則塊參數優先在最右邊,多重參數則在倒數第2個
 
塊參數(選代器)
說起來很複雜,先了解一下塊的特性再來了解定義方式好了
[55, 12, 78].each do |a|
  p a
end

[55, 12, 78].each{|a| p a}
範例1和範例2執行結果相同,先跑出小窗口顯示55,再來顯示12,接著顯示78
其實以上兩個範例是一樣的,只是寫法的不同而已!!
each是數組類定義的代塊函數,功能是循環doend或是{}範圍的腳本內容
(選代器的 do{ 相同;end} 相同,這樣想像因該就不難理解了才是...)
該函數的作用為該數組的數量為循環的次數,每次循環依順序返回數組中的值
這返回的值可以使用『|變量名稱|』進行獲取
想要用塊的參數,則必須在參數的變量名稱左邊添加 & 符號
則這個變量就會存入內部的Proc類(這類的功用說來複雜,反正現在沒必要了解...)
然後在將該參數的變量執行call函數來執行1次呼叫該函數的塊的執行內容 
def sword_boss(&a)
  a.call(5)
  a.call(75)
  a.call(98)
  a.call(32)
end
sword_boss{|s| p s}

def sword_boss(&a)
  a.call(5)
  a.call(75)
  a.call(98)
  a.call(32)
end
sword_boss do |s|
  p s
end
執行後會出現四個小窗口分別顯示5、75、98、32
兩個範例都是一樣的,只是寫法的不同而已,用哪個寫法都可以
當我們呼叫sword_boss函數之後,這個時候呼叫函數的腳本的塊還不會執行
當因參數而存入Proc類的變量執行了call函數時
會將call函數的值傳到呼叫該函數的腳本的 | 符號包圍住的變量中
這個時候才會執行 doend 或是 {} 中的腳本內容
每執行一次那變量的call函數1次,則選代器就會執行一次
所以範例中實際上執行了『p s』4次(因為有4個a.call)
如果希望一次返回2個以上的值,則call的參數數量可以增加
def sword_boss(&a)
  a.call(7, 13)
end
sword_boss{|s| p s} #=> [7, 13](只設1個返回變量的話,會將全參數已數組形式傳回)
sword_boss{|s, v| p s
#=> 7
                                 p v} #=> 13
這樣說可能還是比較難理解,可以把塊想成是個 defend小型函數 
(以下內容中 塊 指的就是 doend 或是 {}
在看看以下範例吧: 
def sword_boss(&a)
  a.call(45)
  a.call(12)
  a.call(72)
end
sword_boss do |s|
  p s
  p true
end
執行的流程是這樣的:呼叫sword_boss函數 → 因『a.call(45)』執行塊 →
傳遞45到變量s中(被 | 包圍住的變量) → 小窗口顯示 45 → 小窗口顯示 true →
回到剛執行的『a.call(45)』繼續往下執行 → 因『a.call(12)』執行塊 →
傳遞12到變量s中 → 小窗口顯示 12 → 小窗口顯示 true →
回到剛執行的『a.call(12)』繼續往下執行 → 因『a.call(72)』執行塊 →
傳遞72到變量s中 → 小窗口顯示 72 → 小窗口顯示 true →
回到剛執行的『a.call(72)』繼續往下執行 → 函數結束 → 返回呼叫函數的腳本繼續往下執行
 
所以小窗口總共依順序顯示了:45、true、12、true、75、true
可以說是互相呼叫的關係,呼叫函數後,該函數又呼叫了它的塊!!
我的廢話:話說當初我認為這個是我永遠都理解不了的深奧東西,現在....也沒說懂很多(其實)  
 
其他定義法 
[ ] 
class Sword_Class
  def [](a)
    p a #=> 100
  end
end
Sword_Class.new[100]

class Sword_Class
  def [](a, b, c)
    p a #=> 100
    p b #=> 52
    p c #=> 128
  end
end
Sword_Class.new[100, 52, 128]
函數名稱『[](變量名稱)』定義的函數必須要像指定數組第幾個單元的方式來呼叫
簡單來說也可以說是把把 ( 改成 [ ,而 ) 改成 ] 來進行表示,不可以省略
 
[ ]=
class Sword_Class
  def []=(a)
    p a #=> 10
  end
end
Sword_Class.new[] = 10

class Sword_Class
  def []=(a, b)
    p a #=> 82
    p b #=> 10
  end
end
Sword_Class.new[82] = 10

class Sword_Class
  def []=(a, b, c, d)
    p a #=> 82
    p b #=> 22
    p c #=> 4
    p d #=> 10
  end
end
Sword_Class.new[82, 22, 4] = 10
這個可以說是定義剛剛介紹的[ ]的寫入版本!!
範例1中,指定1個參數,則呼叫的腳本[ ]不須指定,直接代入即可,不然觸發錯誤
當參數所需數量有2個以上之時,則除了最後1個參數以外
其他的參數都必須在[ ]中指定,而最後一個參數則必須用代入的方式指定才行
 
其他
class Sword_Class
  def +(a)
    p a #=> 50
  end
end
Sword_Class.new + 50

class Sword_Class
  def -(a)
    p a #=> 32
  end
end
Sword_Class.new - 32

class Sword_Class
  def *(a)
    p a #=> 5
  end
end
Sword_Class.new * 5

class Sword_Class
  def /(a)
    p a #=> 32
  end
end
Sword_Class.new / 32

class Sword_Class
  def &(a)
    p a #=> 76
  end
end
Sword_Class.new & 76

class Sword_Class
  def **(a)
    p a #=> 1195
  end
end
Sword_Class.new ** 1195

class Sword_Class
  def ==(a)
    p a #=> 800
  end
end
Sword_Class.new == 800

class Sword_Class
  def >=(a)
    p a #=> 391
  end
end
Sword_Class.new >= 391
含有<=、<、>....等等有的沒的符號也能夠定義成函數,但必非全部
有些定義上還是會出錯,例如:++、!=...之類的...
相簿設定
標籤設定
相簿狀態