iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 24
0
Software Development

從讀遊戲原始碼學做連線遊戲系列 第 24

Day 24 - 實作練習 - 架構客戶端

伺服器的部分我們已經有一個大概的雛形可以使用,所以我們先切換到客戶端把遊戲的操作設計進去。雖然可以直接繼續把伺服器開發完畢,不過能看到專案動起來也是很重要的。

這次我們會使用 RPG Maker MV 來當做基底,這樣可以省下一些我們去建構一個最基本運行遊戲的時間,可以透過 MV 的 Plugin 機制來做覆蓋修改。

因為 RPG Maker MV 單價大約 1,200 台幣,但是有時候特價只要 300 多,可以在有特價的時候在進行購買。另外 MV 的 Plugin 系統其實很不好寫,可以考慮自己搭個 Webpack 之類的塞進去。

新增專案

總之先隨意的開啟一個新的 RPG Maker 遊戲專案,其他都不需要設定。

https://ithelp.ithome.com.tw/upload/images/20191008/20065771W4ptUdYIlQ.png

接下來我們打開專案目錄,在這個目錄下開啟 Web Server 方便我們除錯。

cd ~/Desktop/SimpleRPG-Client
ruby -run -e httpd .

然後打開瀏覽器看看 http://localhost:8080 是不是已經出現可以運行的遊戲。

抓取座標

當我們看到遊戲後,第一部需要的是讓玩家的操作可以被我們抓取,用來判斷玩家想要移動的位置。在 RPG Maker MV 版本為了配合使用手機的玩家,已經內建支援點擊指定坐標,我們就利用這個機制來製作出可以在畫面上點擊移動的功能。

切換到 js/plugins 這個目錄下,我們所有的擴充都會需要在這個目錄下新增檔案來處理。

在 RPG Maker MV 裡面大部分的畫面都是透過 Scene_Map 這個物件來管理的,我們先先增一個 SimpleRPG_Map.js 作為我們自己版本的 Scene_Map 透過覆蓋屬性的方式將原本的點擊移動功能擷取下來。

//=============================================================================
// SimpleRPG_Map.js
//=============================================================================

/*:
 * @plugindesc Scene_Map Override
 * @author Aotokitsuruya
 */

//=============================================================================
// SimpleRPG_Map.js
//=============================================================================

/*:
 * @plugindesc Map Handler
 * @author Aotokitsuruya
 */

(function() {
  // Handling TouchInput
  Scene_Map.prototype.processMapTouch = function() {
    if (TouchInput.isTriggered() || this._touchCount > 0) {
      if (TouchInput.isPressed()) {
        if (this._touchCount === 0 || this._touchCount >= 15) {
          var x = $gameMap.canvasToMapX(TouchInput.x);
          var y = $gameMap.canvasToMapY(TouchInput.y);
          // $gameTemp.setDestination(x, y);
          console.log(x, y)
        }
        this._touchCount++;
      } else {
        this._touchCount = 0;
      }
    }
  };
}());

上面這段程式碼是在 js/rpg_scenes.js 裡面找到的,我們只做了一個簡單的修改就是將 $gameTemp.setDestination(x, y) 註解掉,並替換成 console.log 來顯示抓取到的座標。

接著我們點開插件管理器,然後在空白處連續點擊兩下打開新增的視窗,把 SimpleRPG_Map 選擇後套用,然後確保整個專案有存檔。

https://ithelp.ithome.com.tw/upload/images/20191009/20065771xrb4gnD8bx.png

單純套用插件不一定會實際套用,要確實的把專案存檔後重新整理才會套用新的設定。

此時遊戲上我們不管怎樣點擊地圖上的任何位置,都無法再讓角色移動。

回傳伺服器

前一篇文章已經能從伺服器來回傳移動指令,在這邊我們只需要簡單的插入 WebSocket 的語法就能夠讓角色繼續動起來,不過是由伺服器來告訴我們角色該怎麼動作。

(function() {
  var socket = new WebSocket('ws://localhost:9292');
  socket.onmessage = function(event) {
    var data = JSON.parse(event.data);
    $gameTemp.setDestination.apply($gameTemp, data['parameters']);
  }

  // Handling TouchInput
  Scene_Map.prototype.processMapTouch = function() {
    if (TouchInput.isTriggered() || this._touchCount > 0) {
      if (TouchInput.isPressed()) {
        if (this._touchCount === 0 || this._touchCount >= 15) {
          var x = $gameMap.canvasToMapX(TouchInput.x);
          var y = $gameMap.canvasToMapY(TouchInput.y);
          // $gameTemp.setDestination(x, y);
          socket.send(JSON.stringify({ command: 'move', parameters: [x, y] }));
        }
        this._touchCount++;
      } else {
        this._touchCount = 0;
      }
    }
  };
}());

我們在這邊做了一些簡單的修改,首先是把原本的 console.log 替換成用 WebSocket 發送指令。而在收到訊息(onmessage)階段則是將指令解析出來,並且作為將參數 [x, y] 傳給原本 RPG Maker MV 內建的 setDestination 方法。如此一來就等同於原本實作的版本,不過我們可以試著修改伺服器上的回傳數值來改變玩家點擊得到的結果。

從這兩段 JavaScript 可以看出來 RPG Maker MV 要維護插件是很麻煩的一件事情,除了要依照官方建議使用 ES5 之外,我們也很難將相關的功能整合成一個模組,必須非常零碎的組織才能將整個遊戲架構出來。

我的個人部落格是弦而時習之平常會把自己發現的一些新技巧紀錄在上面,也歡迎大家來逛逛。


上一篇
Day 23 - 實作練習 - 指令執行
下一篇
Day - 25. 實作練習 - 連線池
系列文
從讀遊戲原始碼學做連線遊戲33

尚未有邦友留言

立即登入留言