【RPG Maker MV插件編程】【實例教程2】制作一個啟動畫面

作者: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();
};
  1. DataManager.isBattleTest() 檢測當前是否為進行戰斗測試,如果是就進入戰斗場景,比如在 數據庫-敵群 界面進行戰斗測試時;
  2. DataManager.isEventTest() 檢測當前是否為事件測試,如果是則進入當前的游戲地圖界面,比如在編輯事件時進行事件內容的測試時。
  3. 除此之外, else 部份就是正常啟動游戲時要進入的場景的選擇,可以在這里創建并進入我們的啟動畫面場景。

這里 SceneManager.goto(Scene_Title) 方法用于進入標題畫面。從這里可以看出,RMMV在開始游戲時默認是直接進入標題畫面的,所以很簡單,只要將這里的 SceneManager.goto(Scene_Title) 改成進入我們的啟動畫面即可,如:SceneManager.goto(Scene_Splash)(假設我們的啟動畫面場景類叫做Scene_Splash),再由啟動畫面進入標題畫面,為此就來創建我們的啟動畫面的場景類。

創建啟動畫面的場景類

要創建一個新的場景類,最簡單的做法是改一個現有的場景類。場景類有很多,包括:Scene_Base,Scene_Boot,Scene_BattleScene_Debug,Scene_Equip,Scene_FileScene_GameEnd,Scene_Gameover,Scene_ItemBase,Scene_Item,Scene_Load,Scene_MapScene_MenuBase,Scene_MenuScene_Name,Scene_Options,Scene_SaveScene_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.widthGraphics.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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容