遊戲的第一個版本開發於14年,瀏覽器端使用html+css+js,服務端使用asp+php,通訊採用ajax,資料儲存使用access+mySql。不過由於一些問題(當時還不會用node,用asp寫複雜的邏輯真的會寫吐;當時對canvas寫的也少,dom渲染很容易達到效能瓶頸),已經廢棄。後來用canvas重製了一版。
本文主要和大家介紹了javascript高仿熱血傳奇遊戲的實現代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下,希望能幫助到大家。
1.開發前的準備
為什麼要用Javascript實現一款比較複雜的PC端遊戲
1.js實作PC端網遊是可行的。隨著PC、手機硬體配置的升級和瀏覽器的更新換代,以及H5各種庫的發展,js實現一款網遊的難度越來越低。這裡的難度主要是兩方面:瀏覽器的效能;js程式碼是否足夠易於擴展,以滿足於一款邏輯極其複雜的遊戲的迭代。
2.現階段的js遊戲裡,很少有規模較大的可供參考。涉及到多人連線、服務端資料儲存、複雜互動的遊戲,大多數(幾乎全部)都是用flash開發的。但是flash畢竟在衰落,而js發展迅速,而且只要有瀏覽器就可以運作。
為什麼選擇了一款2001年的熱血傳奇遊戲
#第一個原因是對舊遊戲的情懷; 當然更重要的另一個原因是,別的遊戲要嘛我不會玩、要嘛我會玩但沒有素材(圖片、音效等)。花很大精力去收集一個遊戲的地圖、人物怪物模型、物品和裝備圖,然後去處理、解析一遍再用於js開發,我覺得是浪費時間。
由於我以前蒐集了一些傳奇遊戲的素材,並且幸運地找到了提取熱血傳奇客戶端資源檔案的方法( github位址 ),所以可以直接開始寫碼,省去了一些準備時間。
可能的困難
1.瀏覽器的運作效能:這應該是最困難的一點。假如遊戲要維持40幀,那麼每幀只有25ms的時間留給js計算。且由於渲染通常比計算耗性能,實際上留給js的時間只有10毫秒左右。
2.防作弊:如何避免使用者直接呼叫介面或竄改網路請求資料?由於目標是用js實現比較複雜的遊戲,並且任何網路遊戲都需要考慮這一點,一定會有相對成熟的方案。此處不是本文重點。
2.整體設計
瀏覽器端
畫面渲染使用canvas。
比起dom(p)+css,canvas可以處理比較複雜的場景渲染和事件管理,例如下面這個場景,涉及了四張圖片:玩家、動物、地上的物品、最下層的地圖圖片。 (實際上還有地上的影子,滑鼠指向人物、動物、物品時出現的對應名稱,以及地面上的陰影。為了方便讀懂,先不考慮這麼多內容。)
這時,如果希望實現「點擊動物、攻擊動物;點擊物品、撿起物品」的效果,那麼需要對動物和物品進行事件監聽。如果採用dom的方式,那麼會出現幾點難於處理的問題:
a.渲染的順序和事件處理的順序不同(有時候z-index小的需要先處理事件),需要額外處理。例如這個上面的例子裡:點擊怪物、點擊物品的時候也容易點到人物,那麼需要給人物做「點擊事件穿透」的處理。而且事件處理的順序不固定:假如我有一個技能(例如遊戲裡的治療)需要點人物才可以釋放,那麼這時人物又需要有事件監聽。所以一個元素是否需要處理事件、處理事件的先後,是隨著遊戲狀態的不同而改變的,而 dom的事件綁定已經無法滿足需求 。
b.有關聯的元素很難放在同一個dom節點中:例如玩家的模型、玩家的名字和玩家身上的技能畫效,理想情況下是放在一個
或< ;section> 容器裡,方便管理(這樣幾個元素的定位就可以繼承父元素,不用分別處理位置了)。但是這樣,z-index會很難處理。例如玩家A在玩家B的上面,那麼A會被B遮擋,因此需要A的z-index小一些,但是又需要讓玩家A的名字不會被B的名字或影子遮擋,就無法實現。簡單說, dom結構的可維護性會犧牲畫面所展示的效果,反之亦然 。
c.效能問題。即使犧牲了效果,用dom渲染,勢必出現很多嵌套關係,所有元素的style都在頻繁變化,連續觸發瀏覽器的repaint甚至reflow。
canvas渲染邏輯與專案邏輯分離
如果將canvas的各種渲染操作(如 drawImage 、 fillText 等)與專案程式碼放在一起,那麼勢必會導致專案後期無法維護。翻了一下幾款現有的canvas庫,結合vue的資料綁定+調試工具的方式,搞了一個全新的canvas庫Easycanvas( github地址),並且像vue一樣支持透過一個插件來調試canvas中的元素。
這樣,整個遊戲的渲染部分就容易很多,只需要管理遊戲當前的狀態、並且根據服務端從socket傳回來的資料去更新資料就可以。 「資料的變化造成視圖的變化」這個環節由Easycanvas負責 。例如下圖的玩家包裹物品的實現,我們只需要給出包裹容器的位置、背包裡每個元素的排布規則,然後將每個包裹的物品綁定到一個array上,然後去管理這個array即可(資料映射到畫面的過程由Easycanvas負責)。
例如,5行8列共40個物品的樣式可以透過以下的形式傳遞給Easycanvas(index為物品索引,物品x方向間距36, y方向間距32)。而這個邏輯是一成不變的,無論物品的陣列怎樣變化、包裹被拖曳到什麼位置,每個物品的相對位置都是固定的。至於canvas上的渲染則完全不需要專案本身來考慮,所以可維護性較好。
style: { tw: 30, th: 30, tx: function () { return 40 + index % 8 * 36; }, ty: function () { return 31 + Math.floor(index / 8) * 32; } }
canvas分層渲染
#假設:遊戲需要保持40幀,瀏覽器寬800高600,面積48萬(後面稱48萬為1個螢幕面積)。
如果用同一個canvas來呈現,那麼這個canvas的幀數40,每秒至少需要繪製40個螢幕面積。但是同一個座標點很可能出現多個元素重疊的情況,例如底部的UI、血條、按鈕就是重疊放置,他們又共同遮擋了場景地圖。所以這些加在一起,每秒瀏覽器的繪製量很容易達到100個螢幕面積以上。
這個繪製是很難優化的,因為整個canvas畫布的任何一個地方都在進行視圖的更新:可能是玩家和動物的移動、可能是按鈕的特效、可能是某個技能效果的變化。這樣的話,即使玩家不動,由於衣服「隨風飄飄」的效果(其實是精靈動畫播放到下一張圖),或者是地面上出現了一瓶藥水,都要引起整個canvas的重繪。因為 遊戲中幾乎不可能出現某一幀的畫面與上一幀毫無區別的情況,即使是遊戲畫面的一個局部,也很難保持不變 。整個遊戲的畫面永遠在更新。
因為 遊戲中幾乎不可能出現某一幀的畫面與上一幀毫無區別的情況 ,畫面永遠在更新。
因此,這次我採用了3個canvas重疊排布的方式。由於Easycanvas的事件處理支援傳遞,因此即使點到了最上面的canvas,如果沒有任何元素結束了某一次點擊,後面的canvas也可以接到這次事件。 3個canvas分別負責UI、地面(地圖)、精靈(人物、動物、技能特效等):
這樣分層的好處是,每層最大幀數可以根據需要來調整:
例如UI層,因為很多UI平時是不動的,即使動也不會需要太精密的繪製,所以可以適當降低幀數,例如降低到20 。這樣假如玩家的體力從100降到20,那麼可以在50ms內更新視圖,而50ms的切換是玩家感覺不出來的。因為像體力這種 UI層資料的變化很難在很短的時間內連續變化多次,而50ms的延遲是人很難感知的,所以不需要頻繁的繪製 。假如我們每秒節約了20幀,那麼很可能可以節省10個螢幕面積的繪製。
再如地面,只有玩家移動的時候,地圖才會改變。這樣,如果玩家不動,那麼每個畫面可以省去1個螢幕面積。由於需要確保玩家移動時的流暢感,地面的最大幀數不宜太低。假如地面為30幀,那麼玩家不動時,每秒就可以節約30個螢幕面積的繪製(這個項目中,地圖是幾乎繪滿螢幕的)。而且其它玩家、動物的移動不會改變地面,也不需要重繪地面這一層。
精靈層最大幀數不能降低,這層會展示遊戲的人物動作等核心部分,所以最大幀數設定為40.
#這樣,每秒繪製的面積,玩家移動時可能是80~100個螢幕面積,而玩家不移動時可能只有50個螢幕面積。遊戲中,玩家停下來打怪、打字、整理物品、釋放技能都是站立不動的,因此 大量的時間裡都不會觸發地面的繪製,對性能的節約很大 。
伺服器端
#由於目標是js實作一款多人網遊,所以服務端使用Node,使用socket與瀏覽器通訊。這樣做還有一個好處,就是一些 公用的邏輯可以在兩端重複使用 ,例如判斷地圖上某個座標點是否有障礙物。
Node端的玩家、場景等遊戲相關資料全部儲存與記憶體中,定期同步至檔案。每次Node服務啟動時,將資料從檔案讀取至記憶體。這樣可以玩家較多時,文件讀寫的頻率成指數上升,進而引發的效能問題。 (後來為了提高穩定,為檔案讀寫增加了一個緩衝,「記憶體-檔案-備份」的方式,以免讀寫過程中伺服器重新啟動導致的檔案損壞)。
Node端分介面、資料、實例等多層。 「介面」負責和瀏覽器端互動。 「數據」是一些靜態數據,例如某個藥品的名稱和效果、某個怪物的速度和體力,是遊戲規則的一部分。 「實例」是遊戲中的當前狀態,例如某個玩家身上的藥品,就是「藥品數據」的一個實例。再舉個例子,「鹿的實例」擁有「目前血量」這個屬性,鹿A可能是10,鹿B可能是14,而「鹿」本身只有「初始血量」。
3.場景地圖的實作
地圖場景
#下面開始介紹地圖場景部分,仍然是依賴 Easycanvas 來渲染。
思考
由於玩家是永遠固定在螢幕中心的,所以玩家的移動,其實就是地圖的移動。例如玩家像左跑,地圖就向右平移即可。剛才已經提到,玩家處於3個canvas中的中間一層,而地圖屬於底層,因此玩家一定遮住地圖。
這樣看起來是合理的,但是假如地圖中有一棵樹,那麼「玩家的層次始終高於樹」就不對了。這時,有2種大的解決方案:
地圖分層,「地面」與「地上」拆開。將玩家處於兩層之間,例如下圖,左邊是地上、右邊是地面,然後重疊繪製,把人物夾在中間:
##
下面開始正題。
實作
我找了一個朋友幫我匯出熱血傳奇客戶端中「比奇省」的地圖,寬33600、高22400,是我電腦的幾百倍大。為了避免電腦爆炸,需要拆分成多塊載入。由於傳奇的最小單元是48x32,我們以480x320將地圖拆成了4900(70x70)個圖片檔。 canvas的尺寸我們設定為800x600,這樣玩家只需要載入3x3共9張圖片就可以鋪滿整個畫布。 800/480=1.67,那為什麼不是2x2?因為有可能玩家目前的位置剛好導致有的圖片只展示了一部分。如下圖:
以上是javascript高仿熱血傳奇遊戲程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

記事本++7.3.1
好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3漢化版
中文版,非常好用

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能