切換
舊版
前往
大廳
主題

RM MV學習筆記(2) 創建新的視窗

路漫行 | 2018-01-17 16:17:57 | 巴幣 10 | 人氣 1829


上篇未說完的部分,要如何創建一個新的視窗呢?

那我們現在就來把標題視窗變成兩個吧。

打開自建的Scene_Title_new.js,如果已經改到面目全非的話,可以把全部內容清空,再重新把rpg_scenes.js裡面的Scene_Title()全部再重貼一次。在練習階段經常會改壞掉,所以要習慣重貼。

然後我們再去rpg_windows.js 裡面找Window_Gold() 全段貼到裡面,並且放在Scene_Title()的上面。

為什麼要選Window_Gold()呢?因為他最短...

再來我們需要做兩件事情:
(1)在場景內初始化Window_Gold()
(2)在場景內創建Window_Gold()


首先在Scene_Title_new.js裡面找到這段,新增藍字的部分

Scene_Title.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.createBackground();
    this.createForeground();
    this.createWindowLayer();
    this.createCommandWindow();
    this.createGoldWindow();//初始化Window_Gold()
};

然後再找個空白的地方加上以下內容:
//創建Window_Gold()
Scene_Title.prototype.createGoldWindow = function() {
    this._goldWindow = new Window_Gold();
    this.addWindow(this._goldWindow);
};

展示一下結果:


嘩,畫面上多了一個視窗了

可是現在碰到了另一個問題,如果我針對Window_Gold()去修改,比如增加文字,增加圖片改變透明度等等,遊戲裡狀態欄的那個Window_Gold也會跟著變動,他們兩個是一致的。

所以我們必須修改我們自己的視窗,給他一個新的名字。

就叫做Window_Wand()好了,到自建的Scene_Title_new.js裡面,把Window_Gold通通改成Window_Wand。

我是說這些:


這邊改完之後,Scene_Title的地方也要改:


首先找到這段,修改藍字的部分
Scene_Title.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.createBackground();
    this.createForeground();
    this.createWindowLayer();
    this.createCommandWindow();
    this.createWandWindow();
};

然後再找個空白的地方加上這段,黃標是最重要的一行:

Scene_Title.prototype.createWandWindow = function() {
    this._wandWindow = new Window_Wand();
    this.addWindow(this._wandWindow);
};
如此存檔後測試,雖然看起來跟先前一樣,但已經是不一樣的Window了。

現在我們有兩個視窗,層級由上到下分別為:
   
Window_Wand
   ↓
this._wandWindow


Window_Gold現在我們已經不需要了,所以不用管他,就看Window_Wand以及this._wandWindow這兩個就好。

如果我們在Window_Wand做變動,比如說更改大小、Skin、透明度等等,會立即反應在this._wandWindow上,但若在this._wandWindow裡做改變,不會影響到Window_WandWindow_Wand可以多個場景共用,但this._wandWindow只能在目前的場景上使用。


好吧,這段我也寫到我不知道我在寫什麼,直接進行下一段好了,我想要在我的視窗裡顯示一段文字,應該怎麼做呢?

Window_Wand()去,先來看看裡面裡面到底有些甚麼東西:

Window_Wand.prototype = Object.create(Window_Base.prototype);
Window_Wand.prototype.constructor = Window_Wand;

Window_Wand.prototype.initialize = function(x, y) {
    var width = this.windowWidth();
    var height = this.windowHeight();
    Window_Base.prototype.initialize.call(this, x, y, width, height);
    this.refresh();
};

以上是宣告,表示他是Window_Base來的,這個Window_Base是所有視窗的基底不能亂改。

藍字的部分設定了兩個變數,分別決定這個視窗的寬跟高。那寬跟高究竟是多少呢?

//回傳寬度為240
Window_Wand.prototype.windowWidth = function() {
    return 240;
};

//回傳高度為this.fittingHeight(1)
Window_Wand.prototype.windowHeight = function() {
    return this.fittingHeight(1);
};

this.fittingHeight(1) 是什麼意思?其實就是行數的,比如說改成this.fittingHeight(4)看看結果:

嘩,變成四行了。

再來看看下面這段:

Window_Wand.prototype.refresh = function() {
    var x = this.textPadding();  //設定變數x
    var width = this.contents.width - this.textPadding() * 2;  //設定變數width
    this.contents.clear();  //清空畫面
    this.drawCurrencyValue(this.value(), this.currencyUnit(), x, 0, width);  //顯示金錢跟錢的單位
};

解說一下drawCurrencyValue(),這個函式的功能用來顯示 數值+單位 。那為什麼我在Window_Wand裡面找找不到drawCurrencyValue()這個函式呢?

因為他寫在Window_Base裡面,而Window_Wand是繼承了Window_Base,所以才可以使用Window_Base裡面設定好的函式。


我們可以看一下Window_Base裡面怎麼設定drawCurrencyValue()

Window_Base.prototype.drawCurrencyValue = function(value, unit, x, y, width) {
    var unitWidth = Math.min(80, this.textWidth(unit));//宣告變數unitWidth,用來設定單位的寬
    this.resetTextColor();//重設所有文字顏色,預設是白色
    this.drawText(value, x, y, width - unitWidth - 6, 'right');//顯示錢的值,並且靠右對齊
    this.changeTextColor(this.systemColor());//變更文字顏色為系統色,預設是淡藍色
    this.drawText(unit, x + width - unitWidth, y, unitWidth, 'right'); //顯示單位,並且靠右對齊
};

字好多喔看不懂怎麼辦,沒關係啦drawCurrencyValue()裡面的內容也不是很重要,畢竟也沒有要去改他,我們只要知道有這麼一個東西存在就好了。我們只需要關注如何使用他!

來看原生程式的這一行:
this.drawCurrencyValue(this.value(), this.currencyUnit(), x, 0, width);  

翻譯一下:
this.drawCurrencyValue(  , 單位, 位置x,  位置y,  寬度);  

隨便改一下試試看:
this.drawCurrencyValue(10000, "元", x, 0, width);

結果如下:

不過這個10000元是我們寫死的,是假的,再來我們要看看要怎樣顯示遊戲裡的錢,我們先把this.value()this.currencyUnit()放回原本的位置上,然後看看下面這個函式:

//回傳隊伍持有的金錢給value()
Window_Wand.prototype.value = function() {
    return $gameParty.gold();
};

//回傳系統設定裡面的金錢單位給currencyUnit()
Window_Wand.prototype.currencyUnit = function() {
    return TextManager.currencyUnit;
};

如果想要顯示資料庫裡面其他欄位,可以去改value(),或是自己新增一個value2()。只要把黃標的部分換掉即可,像是第一個角色的HP好了:

Window_Wand.prototype.value = function() {
    return $gameActors._data[1].hp;
};

就變成這樣了:


這時就要驗證一下第一個角色的HP是不是真的450,可以在執行測試的時候按下F8,呼叫控制台視窗:


在控制台的輸入地方貼上$gameActors._data[1].hp
驗證1:

驗證2:


現在我們正確的叫到第一個角色的HP了,這邊可以再說明一下,所有$開頭的都是資料庫內預先設定好的全域變數,也可以直接在控制台內呼叫出變數內容。

控制台內可顯示所有的資料庫變數,

我目前還沒整理好全部的屬性對應,但是有幾份文件可以互相參照,比如說幫助文件最下面的JS庫中,前面有~符號的就是相關物件,用item舉例,item這個物件由上表知開頭是$dataitems[編號]

我們想知道編號1號的item是什麼名字,可以這樣輸入:$dataItems[1].name

他就會回傳藥水,這樣可以驗證我們的資料庫專用變數名稱有沒有打對。

.name是$dataItems的屬性,一個內建的item會有這些屬性,可以用$dataItems[編號].屬性,去看他們的內容。

參考資料:中文的Item屬性表
好多喔 ...其實也不會全部都用到啦...還是回到我們的視窗上吧,Window_Base裡面也提供了非常多預先寫好的函式,不想使用drawCurrencyValue()的話,也有更簡單的drawText()可以用。

回到refresh來:

Window_Wand.prototype.refresh = function() {
    var x = this.textPadding();  
    var width = this.contents.width - this.textPadding() * 2;  
    this.contents.clear();  
    this.drawCurrencyValue(this.value(), this.currencyUnit(), x, 0, width);  
};

黃底的部分,直接換成:

this.drawText(this.value(),  x, 0, width);  

結果如下:


也可以寫成:
this.drawText( "主角的HP = " + this.value(),  x, 0, width);  

結果如下:



也可以寫成:
this.drawText( $dataActors[1].name + '的HP' ,  x, 0, width);  


一個drawText只能有一個變數丟在裡面,所以想要同時寫 角色名字 跟 HP 的話,要分成兩段來寫:

this.drawText( $dataActors[1].name + '的HP' ,  x, 0, width);  
this.drawText(this.value(),  x, 0, width);  

這時候就必須更改顯示位置,如果要同一行顯示,可以改x,如果要換行可以改y
先改第二行的x看看:

this.drawText( $dataActors[1].name + '的HP' ,  x, 0, width);  
this.drawText(this.value(), 150 , 0, width);  




再試試看改y:

this.drawText( $dataActors[1].name + '的HP' ,  x, 0, width);  
this.drawText(this.value(), 150 , this.lineHeight() , width);  

this.lineHeight() 就是當前文字欄高的意思,如果要去第三行的話,可以這樣寫:

this.drawText(this.value(), 150 , this.lineHeight() * 2 , width);  


至於width (文字寬度)有沒有用呢?如果有要改變文字對齊方式的話,寬度就很重要了,目前文字寬度會直接抓視窗的寬度扣掉內距,所以暫時不用更改width,我們可以直接去改對齊,像這樣:
this.drawText( $dataActors[1].name + '的HP' ,  x, 0, width , 'right');  


對齊方式有三種,'left' 、'center' 、 'right' 要用字串

如果我想要顯示主角的頭、等級、HP的血條、那些東西呢?

太多了啦,下...下回吧



等等等等,還沒結束,還有最後一個函式沒說明:

Window_Wand.prototype.open = function() {
    this.refresh();
    Window_Base.prototype.open.call(this);
};

//當視窗open的時候,去反複執行refresh

才能確保refresh裡面的東西立即更新,好的,本回真的結束了。


送禮物贊助創作者 !
0
留言

創作回應

更多創作