GML 學習手記(GML概況二)

變數和變數範圍

這次這篇手記,繼續接上一篇。本篇手記主要講的是GML中的變數。就像別的編譯器一樣,GML也是使用變數來作為最基本的單元來進行之後一系列的編譯過程。變數用於存儲設備內存中的信息,以供之後(或現在)使用。這些變數將會被賦予一系列的名稱,方便我們在函數和程序中引用他們。還有就是上一篇所說的變數可以存儲一個值,也可以是一個字元串。我們使用變數來存儲一個值,並把他們用在一個或多個的程序或是函數中。

現在,我們來思考一個變數"pi",這是一個現實世界就存在的一個變數,並且它的值就是3.1415926(etc...)。當大家提起"pi"的時候,很容易就會讓人想起3.1415926(etc...)。所以,在編程中,把一個變數命名會方便很多,如果變數的值發生了變化,我們不需要在程序中逐個進行修改,因為變數的名稱是不會改變的。還有需要注意的是,在命名的過程中需要遵守一定的規則,在GML中變數的名稱必須要以字母開頭,變數名稱只能包含字母、數字和下劃線"_",並且變數名稱的最大長度為64個符號。在編譯的過程當中,我們需要先「聲明」一個變數,我們才能在後邊的編譯過程中使用它。簡單的來說,就是我們事先告訴計算機我們想要用這個名稱,讓計算機在內存中為我們分配一個地方,在這個地方我們可以存儲我們想要的值。

在GML中,有四種主要的變數類別,每個類別都有自己的適用範圍(可以理解為它的操作的範圍或是定義域),下面就是這些變數類別以及它們的範圍:

  • instance(實例變數):這是最常見的變數,並在實例中定義。這是實例所特有的,並且可以用於任何event(事件)和該實例中的審核函數。(感覺這一段我有點翻譯錯誤。。。。。。)
  • local(局部變數):這類變數在定義時,必須使用"var"函數來聲明這些變數。局部變數只對創建它的event(事件)script(腳本)有效。所以,GMS在創建這類變數之後,會在event(事件)持續的時間範圍內使用這個變數,但是當這個event(事件)結束之後,GMS將會「忘記」這個變數。因此,在之後你再次使用這個變數時,將會出現一個"unknown variable"(位置變數)的錯誤。
  • global(全局變數):全局變數是屬於遊戲世界的一種變數,並不是實例。它必須優先設置為全局變數。但在此之後,任何實例都可以檢查或修改它的變數,並且無論哪一個實例或是程序對其進行操作,它的值都將反映對這個變數的最後操作。
  • built in variables(內置變數):這類變數十分特殊,它們是遊戲世界中「內置」room(場景)object(對象)的一類變數。他們可以是實例,也可以是全局變數(但不是局部變數)。

需要說明的是我在變數範圍中加粗的room(場景)object(對象)event(事件)script(腳本),這些東西是GMS中的各項操作界面。

接下來,就按照上面的順序來講一下這幾類變數。


1、Instance Variables(實例變數)

一個實例變數的範圍取決於創建它的實例。實例變數由object(對象)中的實例所創建。實例變數在該實例中被認為是唯一的,即在同一個object(對象)中,許多不同的實例可以擁有相同的一個變數,但是這些變數可以擁有不同的值,因為這些變數對於他們各自的實例來說都是唯一的。下面就是創建實例變數的例子:

potions = 12;life = 100;name = "Jock MacSweeney";strength = 5.5;armour = -2;

我們只需要給出一個名稱和一個值(可以是一個數,也可以是字元串)就可以來設置一個變數。接下來,我們就可以在需要用到它的object(對象)的實例中使用它。而且,在之後我們可以用多種方法修正這個變數的值。比如,在一些event(事件)中讓變數"life"(生命)減去一定的值:

life -= 5 + armour;

現在變數"life"(生命)就等於97。(接下來的一段話我翻譯了好久,有好多修飾詞,我的天,廢話賊多,看得我好累,我就說一下重點)設置一個變數的好處是當我們需要修改其中的值時,只需要在一個地方修改即可,也容易我們糾錯,讓編譯的過程變得更加靈活。

需要注意的是,GMS內置了許多實例變數名稱,所以當我們在命名變數的名稱的時候,我們需要避免與這些內置的變數名稱相衝突。但是,這也很容易發現,因為在編譯器中他們會顯示不同的顏色,並且在自動完成欄中也會顯示出來。


2、Local Variables(局部變數)

局部變數是我們為特定的事件所創建的一個變數,當這個事件結束時,這個局部變數將會被丟棄。這可以使得我們的代碼庫保持乾淨整潔,保持內存空間的優化,以最優的方式處理問題。且我們在命名局部變數的時候,要注意變數名稱是否與對象中的實例變數的名稱有衝突,同時還要確保不與事件之外的其他變數名稱相衝突。下面是聲明局部變數的例子:

var i = 0;repeat (10) { inventory[i] = 0; i+=1;

上面的代碼用"i"這個變數來初始化一個數組。

下面還有一個例子:

var xx,yy;xx = x - 32 +irandom(64);yy = y - 32 +irandom(64);instance_create(xx, yy, obj_blood);

上面的代碼使用了局部變數來存儲隨機坐標,之後又使用這些坐標來創建實例。在這個例子中,我們使用的一些變數不是完全必要的,但是為了方便閱讀和使用,還是使用了他們。下面的例子中,我們將做的更詳細:

instance_create(x - 32 + irandom(64), y - 32 + irandom(64), obj_guts);

還有需要注意的是,局部變數對於使用它們的event(事件)來說是唯一的,所以我們可以用"with()"函數讓這些變數來改變或設置其他的實例。

var num = instance_number(obj_Enemy);with (obj_Enemy) { if num>10 instance_destroy(); }

上面的變數告訴我們,只要在同一個代碼塊當中,局部變數就可以在任何object(對象)中使用。


3、Global Variables(全局變數)

當一個變數被聲明為全局變數時,它便不屬於任何的實例,但是可以被訪問。與局部變數一樣的是全局變數需要聲明,但不相同的是,全局變數將被以一直保存在內存中,直到遊戲結束。舉個例子,我們可以創建一個全局變數來記錄玩家的子彈擁有數量,然後在遊戲的不同時候改變這個變數。全局變數不屬於任何一個特定的實例,但是它可以訪問、修改和使用所有實例。 並且,對這類變數的任何修改都是「全局的」,即使用該變數的所有實例都將受到改變。下面舉個栗子:

global.food = 5;

我們用global.來聲明變數"food",並且告訴GameMaker這是一個全局變數。現在,任何實例都可以任意使用和改變這個變數,並且所有其他實例都將「看到」這個變數。例如,我們可以有這樣一個event(事件):

global.food +=1;

或者還有這樣:

draw_text(32, 32, "food = " + string(global.food));

需要注意的是不要將全局變數命名為任何實例變數,因為這樣會出現許多難以調試的BUG!一般來說,我們需要一個腳本在遊戲的一開始就聲明所有的全局變數。這樣方便我們去參考和檢查這些變數。

我們也可以通過globavar來聲明全局變數,就像使用var來聲明局部變數一樣。但是,它只包含先後兼容性,所以不建議在新項目中使用,以後的GMS可能不再支持它。

同樣的,GMS內置了許多全局變數,這也是我們需要注意的,識別方法與上面的實例變數一樣。這些內置的全局變數大多是十分具體的,只在少數情況下會使用到他們。具體例子如下:

(1)health(血量)

這個內置的全局變數通常用於玩家的血量,但是僅僅只是通常,你也可以把它用做別的用途。下面是一個例子:

if place_meeting(x, y, obj_Enemy) { health -= 10; if health <= 0 instance_destroy(); }

上述的代碼用於檢查當前的實例是否與對象"obj_Enemy"有碰撞,如果有的話health將減去10,如果health的值小於或等於0的話,破壞當前實例。

(2)lives(生命值)

這個內置變數通常用於玩家的生命值(就是血量減到0了就會扣1生命值),嗯,也是通常,所以還是可以拿來做其他用途。下面還是例子:

if place_meeting(x, y, obj_Enemy_Bullet) { health -= 10; if health <= 0 lives -=1; }

上述代碼當檢測到health小於等於0的時候,lives減去1。

(3)score(分數)

這個內置變數通常用於分數,還是通常,仍然可以用作他用。下面是最後一個例子:

if place_meeting(x, y, obj_Bullet) { score += 10; instance_destroy(); }

上述代碼先是檢查當前實例是否與對象obj_Bullet是否有碰撞,如果有的話,分數加10並且自行銷毀當前實例。Bullet是子彈的意思。


專有名詞中英互譯

Devices 設備

Refer 參考,引用

Valid 有效的

Scope 範圍

Categories 種類,類別

Reach 範圍

Defined 定義

Script 腳本

Reflect 反映

Objects 對象

Numeric 數值的

Modified 修正的

Description 類型

Accessed 訪問

Initialize 初始化

Array 數組

Coordinates 協調

推薦閱讀:

使用Unity2017開發MTV:一個Timeline和Cinemacine的實踐
遊戲性能優化(1)-why & benchmark
在GMS2中製作對話系統(1/2)
KBEngine遊戲伺服器(二)——運行Unity的Demo

TAG:遊戲開發 | 獨立遊戲 | GameMakerStudio |