作者:Mandarava(鰻駝螺)
微博:@鰻駝螺pro
啟動畫面是游戲開始時,在進入標題畫面前的一個顯示畫面,通常用于展示游戲開發商的Logo。RMMV自帶一個官方啟動畫面插件 MadeWithMv,可以設定自己的啟動圖,一般來說,這個插件足夠使用。本文介紹如何制作類似的一個啟動畫面插件。
首先,新建一個名為 MND_Splash.js 的文件放到 js/plugins 目錄下,并在RMMV中安裝該插件。
從哪里開始?
游戲在啟動時,Scene_Boot
類用于初始化整個游戲,而 Scene_Boot.prototype.start
方法是場景開始時的處理方法。啟動畫面是游戲啟動時的第一個“場景”,所以要創建啟動畫面,就應該在 start
方法中創建。來看一下 start
原始方法的實現:
Scene_Boot.prototype.start = function() {
Scene_Base.prototype.start.call(this);
SoundManager.preloadImportantSounds();
if (DataManager.isBattleTest()) {
DataManager.setupBattleTest();
SceneManager.goto(Scene_Battle);
} else if (DataManager.isEventTest()) {
DataManager.setupEventTest();
SceneManager.goto(Scene_Map);
} else {
this.checkPlayerLocation();
DataManager.setupNewGame();
SceneManager.goto(Scene_Title);
Window_TitleCommand.initCommandPosition();
}
this.updateDocumentTitle();
};
-
DataManager.isBattleTest()
檢測當前是否為進行戰斗測試,如果是就進入戰斗場景,比如在 數據庫-敵群 界面進行戰斗測試時; -
DataManager.isEventTest()
檢測當前是否為事件測試,如果是則進入當前的游戲地圖界面,比如在編輯事件時進行事件內容的測試時。 - 除此之外,
else
部份就是正常啟動游戲時要進入的場景的選擇,可以在這里創建并進入我們的啟動畫面場景。
這里 SceneManager.goto(Scene_Title)
方法用于進入標題畫面。從這里可以看出,RMMV在開始游戲時默認是直接進入標題畫面的,所以很簡單,只要將這里的 SceneManager.goto(Scene_Title)
改成進入我們的啟動畫面即可,如:SceneManager.goto(Scene_Splash)
(假設我們的啟動畫面場景類叫做Scene_Splash
),再由啟動畫面進入標題畫面,為此就來創建我們的啟動畫面的場景類。
創建啟動畫面的場景類
要創建一個新的場景類,最簡單的做法是改一個現有的場景類。場景類有很多,包括:Scene_Base
,Scene_Boot
,Scene_Battle
,Scene_Debug
,Scene_Equip
,Scene_File
,Scene_GameEnd
,Scene_Gameover
,Scene_ItemBase
,Scene_Item
,Scene_Load
,Scene_Map
,Scene_MenuBase
,Scene_Menu
,Scene_Name
,Scene_Options
,Scene_Save
,Scene_Shop
,Scene_Skill
,Scene_Status
,Scene_Title
。分析一下這些場景類的實現,確定哪些方法需要,最后把我們要用到的方法拷貝到 MND_Splash.js
中,我們的場景類命名為:Scene_Splash
。最后我們需要的方法包括以下幾個:構建器部分、Scene_Splash.prototype.create
方法、Scene_Splash.prototype.start
方法、Scene_Splash.prototype.stop
方法、Scene_Splash.prototype.terminate
方法、Scene_Splash.prototype.update
方法等(當然除了構建器部分外,其它方法都是可選的)。下面就在Scene_Splash
類中重寫這些方法。
構建器部分
Scene_Base
類是所有Scene
類的基類,我們要創建的類Scene_Splash
實際比較簡單,所以只需要直接繼承Scene_Base
類就可以了。下面是Scene_Splash
的構建器及初始化代碼:
function Scene_Splash() {
this.initialize.apply(this, arguments);
}
Scene_Splash.prototype = Object.create(Scene_Base.prototype);
Scene_Splash.prototype.constructor = Scene_Splash;
Scene_Splash.prototype.initialize = function() {
Scene_Base.prototype.initialize.call(this);
};
Scene_Splash.prototype.create方法
該方法是在場景創建時要執行的處理,在這里創建組件并將它們加入渲染隊列中。所以,我們可以在這里添加要顯示logo圖片。假設我們的Logo圖片放在 img/system/MyLogo.png
,那么該方法的重寫實現如下:
Scene_Splash.prototype.create = function() {
Scene_Base.prototype.create.call(this);
this.logo=new Sprite();
this.logo.bitmap=ImageManager.loadSystem("MyLogo");
this.addChild(this.logo);
};
Scene_Base.prototype.create.call(this);
這個是調用基類(父類)的同名方法,因為我們這里是重寫基類的該方法,你需要讓基類中的操作也執行一下(除非你明確不想執行;即使現在基類的該方法沒有執行任何操作,為了以后的兼容,比如官方在未來的某個版本添加了操作,也應該用調用基類的實現)。this.logo
就是用于顯示我們的Logo圖片的精靈對象,使用場景的 addChild()
方法可以將精靈加入到場景。在這里我們并沒有為精靈設置顯示座標,因為此時的Logo圖片還沒有加載完畢,讀取到的圖片尺寸高寬都是0,如果你需要根據圖片的高寬為其定位,那么,這個定位處理應該放到 start
方法中去。
Scene_Splash.prototype.start方法
該方法是場景啟動時要執行的處理。這里用 startFadeIn(duration, white)
方法讓場景出現淡入效果。同時將logo圖片顯示到場景正中間。
Scene_Splash.prototype.start = function() {
Scene_Base.prototype.start.call(this);
this.startFadeIn(this.slowFadeSpeed(), false);
//將this.logo定位到場景的正中(由于沒有使用logo的尺寸來定位,所以下面這段代碼放到 create 方法中也是沒問題的)
this.logo.anchor.x=0.5;
this.logo.anchor.y=0.5;
this.logo.x=Graphics.width/2;
this.logo.y=Graphics.height/2;
};
Graphics.width
和 Graphics.height
用于獲取游戲屏幕的寬高尺寸。這里將logo精靈的錨點設置到其正中心,再將其坐標設置到屏幕正中心,這樣就能讓精靈呈現在屏幕中心。
Scene_Splash.prototype.stop方法
該方法是場景停止時要執行的處理。這里用一個 fadeOutAll
淡出效果,淡出畫面及所有背景音樂、音效。
Scene_Splash.prototype.stop = function() {
Scene_Base.prototype.stop.call(this);
this.fadeOutAll();
};
Scene_Splash.prototype.terminate方法
該方法是在切換到其它場景時終止當前場景的處理。假如你在啟動畫面中添加了背景音樂,那么可以在這里終止背景音樂或音效的播放。
Scene_Splash.prototype.terminate = function() {
Scene_Base.prototype.terminate.call(this);
AudioManager.stopAll();
};
Scene_Splash.prototype.update方法
該方法是每幀運行一次的更新處理,可以在該方法中檢測是否需要切換到其它場景、要切換到哪個場景等。(當然,如果你要實現動態logo,那么也可以在這里更新logo動畫。)
現在,我們想在啟動畫面停留90幀,90幀后自動切換到標題畫面。那么代碼如下:
Scene_Splash.prototype.update = function() {
this._wait = this._wait || 0;//如果this._wait尚未定義,則定義并賦值為0;當然,這個_wait的定義代碼最好放到構建器或create方法中進行
if(this._wait>=0) {
if (this._wait >= 90) {
SceneManager.goto(Scene_Title);
this._wait = -1;//讓_wait=-1確保90幀后這段代碼不會再被運行,否則會出現一直要goto卻goto不了的情形
} else {
this._wait++;
}
}
Scene_Base.prototype.update.call(this);
};
如果同時想在玩家點擊啟動畫面或按下確定鍵后立即切換到標題畫面而不用再等待完90幀,可以改為以下代碼:
Scene_Splash.prototype.update = function() {
if (this.isActive() && !this.isBusy() && (Input.isTriggered('ok') || TouchInput.isTriggered())) {//新增
SceneManager.goto(Scene_Title);
return;
}
if (this._wait == undefined) { this._wait = 0; }
if (this._wait >= 0) {
if (this._wait >= 90) {
SceneManager.goto(Scene_Title);
this._wait = -1
} else {
this._wait++;
}
}
Scene_Base.prototype.update.call(this);
};
Input.isTriggered('ok')
用于檢測玩家是否按下了確定鍵,TouchInput.isTriggered()
用于檢測玩家是否點擊了屏幕,如果按下了確定鍵或點擊了屏幕,則進入標題界面。
至此,一個啟動畫面的插件就完成了,完整代碼如下:
Scene_Boot.prototype.start = function() {
Scene_Base.prototype.start.call(this);
SoundManager.preloadImportantSounds();
if (DataManager.isBattleTest()) {
DataManager.setupBattleTest();
SceneManager.goto(Scene_Battle);
} else if (DataManager.isEventTest()) {
DataManager.setupEventTest();
SceneManager.goto(Scene_Map);
} else {
this.checkPlayerLocation();
DataManager.setupNewGame();
SceneManager.goto(Scene_Splash);
Window_TitleCommand.initCommandPosition();
}
this.updateDocumentTitle();
};
function Scene_Splash() {
this.initialize.apply(this, arguments);
}
Scene_Splash.prototype = Object.create(Scene_Base.prototype);
Scene_Splash.prototype.constructor = Scene_Splash;
Scene_Splash.prototype.initialize = function() {
Scene_Base.prototype.initialize.call(this);
};
Scene_Splash.prototype.create = function() {
Scene_Base.prototype.create.call(this);
this._wait = 0;
this.logo=new Sprite();
this.logo.bitmap=ImageManager.loadSystem("MyLogo");
this.addChild(this.logo);
};
Scene_Splash.prototype.start = function() {
Scene_Base.prototype.start.call(this);
this.startFadeIn(this.slowFadeSpeed(), false);
this.logo.anchor.x=0.5;
this.logo.anchor.y=0.5;
this.logo.x=Graphics.width/2;
this.logo.y=Graphics.height/2;
};
Scene_Splash.prototype.update = function() {
if (this.isActive() && !this.isBusy() && (Input.isTriggered('ok') || TouchInput.isTriggered())) {
SceneManager.goto(Scene_Title);
return;
}
this._wait = this._wait || 0;
if (this._wait >= 0) {
if (this._wait >= 90) {
SceneManager.goto(Scene_Title);
this._wait = -1
} else {
this._wait++;
}
}
Scene_Base.prototype.update.call(this);
};
Scene_Splash.prototype.stop = function() {
Scene_Base.prototype.stop.call(this);
this.fadeOutAll();
};
Scene_Splash.prototype.terminate = function() {
Scene_Base.prototype.terminate.call(this);
AudioManager.stopAll();
};
可以改進的地方:啟動圖的圖片、等待時間這二項可以做成插件參數,以便可以自由設置。有關如何實現插件參數,請參考我的另一篇教程:【RPG Maker MV插件編程】【實例教程1】怎樣編寫一個插件?。
by: Mandarava(鰻駝螺) 2017.06.14