2024-08-04|閱讀時間 ‧ 約 13 分鐘

GameMaker|Script Function 腳本函式|程式基礎

這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。有了這些概念,各位會更容易理解,要如何設計程式碼。

本篇教學所使用的系統是Windows 10,如果有按鍵相關的說明,會用Windows的系統來解釋。如果你用的是Mac系統,再麻煩自行換成相對應的按鍵。


前置知識


在學習本篇內容之前,最好具備以下的前置知識,以免看不懂這篇教學的內容。


Script的簡介


Script是一種資產(Asset),他跟物件(Object)一樣,能夠放置程式碼。

Script有個特色,就是他會在所有的實體生成之前,就先運行過自身的程式碼。

因此,Script就很適合定義函式(Function),或是定義全域變數(Global Variable)。


建立Script的方法,就跟其他的資產一樣。另外,Script也是一個很簡單的資產,裡面除了用來寫程式的頁面,也沒有其他的參數設定了。

Script點開後的樣子


使用函式(或全域變數)的注意事項


這邊要來解釋,為何Script的這個特色,導致他適合用來放置函式。

首先,如果我們要使用函式,就一定要先定義過函式,我們才能使用。我們之所以可以使用Runtime Function,那是因為GameMaker已經幫我們定義過了。

假設在還沒定義函式之前,就呼叫函式的話,那程式就會跳出「函式尚未定義」的錯誤(全域變數也有類似的狀況)。

基於上述的原因,就導致了Script,很適合拿來定義函式和全域變數。


定義全域變數


定義全域變數的方法,我們已經在變數範圍的教學中提過,差別只是把全域變數,放在Script裡面而已。

如果想要方便管理,可以考慮用一個Script檔案,來放置所有的全域變數。當然,你也可以拆成更多的Script,來進行更細的分類。

用Script來管理全域變數


定義函式


從函式的教學中,我們已經知道,函式可以分成「有無回傳數值」和「有無輸入參數」的類型。

這邊將用三個簡單的範例,來解釋要如何在Script上面,定義函式。


🔸有回傳/無參數


當滑鼠的左鍵按下,就會跳出一個視窗,顯示函式的回傳結果。效果就像下面這張GIF:

「有回傳/無參數」的範例


接著,我們來展示這個範例的程式碼,如果各位有具備,這篇教學的前置知識,我想應該很快就能理解,要如何定義和使用函式。

以下是Script裡面的程式碼:

function number_plus_ten() {
//此函式,最終會回傳數值100的實數資料
var number = 90 ;
number = number + 10 ;
return number ;
}


接著是Object裡面的Create和Step:

//這段是Create的Event
//將variable_number,設定成函式回傳的資料,也就是100
variable_number = number_plus_ten() ;

//這段是Step的Event
//如果滑鼠的左鍵點下
if (mouse_check_button_pressed(mb_left)) {
//string()可以把variable_number裡的資料,轉換成字串
//顯示variable_number裡面的數值
show_message(string(variable_number)) ;
}


最後,附上範例設定的截圖:


🔸有回傳/有參數


在上個範例中,回傳的數值固定是100(90+10),這不是個很實用的函式,比較實用的函式,應該是能輸入一個參數,然後回傳參數+10的數值回來。

因此接下來,我們要把函式,改良成能輸入參數的樣子:

「有回傳/有參數」的範例


以下是Script裡面的程式碼:

function input_plus_ten(instance_input) {
//instance_input表示輸入的參數
//此函式,最終會回傳,輸入參數+10的實數資料
var input = instance_input ;
input = input + 10 ;
return input ;
}


接著是Object裡面的Create和Step:

//這段是Create的Event
//將input_number,設定成40
//將input_number當成參數,放進函式當中
//output_number將會被設定成50
input_number = 40 ;
output_number = input_plus_ten(input_number) ;

//這段是Step的Event
//如果滑鼠的左鍵點下
if (mouse_check_button_pressed(mb_left)) {
//string()可以把variable_number裡的資料,轉換成字串
//顯示output_number裡面的數值
show_message(string(output_number)) ;
}


這是範例設定的截圖:


這種類型的函式,有很多的使用場景,例如:可以用來製作「計算傷害值」的函式,輸入的參數,就是攻擊方的攻擊力,以及受擊方的防禦力。


🔸無回傳/直接運行


無回傳數值的函式,也是一個很常用的程式,這邊我們準備了,一個相關的範例。

這個範例的效果是,當滑鼠的左鍵按下時,隨機改變方塊的座標位置;當滑鼠的右鍵按下時,將方塊的座標設定成(0, 0)。效果就像下面這張GIF:

「無回傳/直接運行」的範例


以下是Script裡面的程式碼:

function random_xy() {
//隨機改變座標的位置,但不會超出畫面
randomise() ;
id.x = irandom_range( 0 , room_width - sprite_get_width(0) ) ;
id.y = irandom_range( 0 , room_height - sprite_get_height(0) ) ;
}

function set_xy( _x , _y ) {
//_x和_y為輸入的參數
//將座標設定成輸入的參數
id.x = _x ;
id.y = _y ;
}


接著是Object裡面的Create和Step:

//這段是Create的Event
//隨機改變block的位置,但不會超出畫面
random_xy() ;

//設定set的座標數值
set_x = 0 ;
set_y = 0 ;

//這段是Step的Event
//如果滑鼠的左鍵點下
if (mouse_check_button_pressed(mb_left)) {
//隨機改變座標的位置,但不會超出畫面
random_xy() ;
}

//如果滑鼠的右鍵點下
if (mouse_check_button_pressed(mb_right)) {
//將座標移動到set的位置
set_xy( set_x , set_y ) ;
}


這是範例設定的截圖:


在這個範例中,我們能發現,在一個Script裡面,能夠同時定義多個函式,如果有需要,也可以同時定義全域變數,就看每個人的使用習慣而定。


什麼是宣告


這邊要來解釋,為何在「有回傳/無參數」的範例中,number要被設定成局部變數。

而在解釋之前,我們要先理解一個新的專有名詞:宣告。


宣告的意思,是告訴電腦,請準備一個空間(通常是記憶體),我們需要存放一些東西。

在一些程式語言中,宣告和賦值的動作,是要分開執行的。但在GameMaker當中,宣告這個動作,幾乎是被忽略掉的,在說明書當中,也沒有特別的說明。

例如:當我們「第一次」對「新的變數」,來進行賦值時,其實就是執行了「宣告」的動作(宣告完順便賦值的意思)。

各位只要記住一點,當我們發動宣告的動作時,電腦就會占用掉一些記憶體。


局部變數的應用


假設範例中的number,改成了實體變數(Instance Variable),那會發生什麼事呢?

function number_plus_ten() {
//改成實體變數的樣子
number = 90 ;
number = number + 10 ;
return number ;
}


首先,函式會把number理解成,這是實體裡面的一個變數,因此第一動作,是先搜索實體裡的程式碼,看看這個變數,有沒有被「宣告」過。

假設有找到,那函式就只會執行「賦值」的動作,也就是把數值重新設定成90,這樣子的流程,並不會額外的佔用記憶體。

但如果沒找到的話呢?那麼函式就會理解成:「需要宣告一個新的變數」,在宣告完之後,程式依然會順利執行,但在記憶體當中,就會出現「垃圾變數」。


「宣告新的變數」並不會改變「實體裡面的程式碼」,換句話說,程式碼裡面不會因此多了一行「number = 90」的宣告。

因此,當我們再次使用函式時,就會「又」產生新的變數,而不是進行賦值的動作。

如果一直重複呼叫這種函式的話,最後就會跳出「記憶體不足」的相關錯誤。


這就是為什麼,我們要在這裡,使用局部變數的原因。

每當使用函式時,函式就會宣告一個新的變數,在用完函式之後,這個變數就會從記憶體中被刪除,這樣就不會產生垃圾變數。




🔔如果內容對你有幫助,可以按個喜歡,這樣就能讓更多人,接觸到這些棒棒的內容🔔


✨祝各位也能開心的做出好遊戲✨

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.