激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢電話:400-810-1418 服務(wù)與監(jiān)督電話:400-810-1418轉(zhuǎn)接2

javascript可以開發(fā)游戲嗎(如何用 JavaScript+Canvas 開發(fā)一款超級燒腦小游戲?)

發(fā)布時間:2023-11-27 20:22:35 瀏覽量:108次

?如何用 JavaScript+Canvas 開發(fā)一款超級燒腦小游戲?

javascript可以開發(fā)游戲嗎(如何用 JavaScript+Canvas 開發(fā)一款超級燒腦小游戲?)

作者 | huangjianke

責編 | 伍杏玲

出品 | CSDN(ID:CSDNnews)

【CSDN 編者按】據(jù)微信最新數(shù)據(jù),微信小游戲累計注冊用戶量已突破10億。那么初學者如何開發(fā)一款好玩又燒腦的微信小游戲呢?本文作者將詳細為大家講解。

“啟邏輯之高妙,因想象而自由。”層疊拼圖Plus是一款需要空間想象力和邏輯推理能力完美結(jié)合的微信小游戲,偶消奇不消,在簡單的游戲規(guī)則下卻有著無數(shù)種可能性,需要你充分發(fā)揮想象力去探索,看似簡單卻具有極大的挑戰(zhàn)性和趣味性,Talk is cheap. Show me the code!

層疊拼圖Plus微信小游戲采用JavaScript+Canvas實現(xiàn),沒有使用任何游戲引擎,對于初學者來說,也比較容易入門。下面是小游戲頁面:

繪圖模糊的原因知道了,在微信小游戲里面又該如何解決呢?

可以看到,我們先通過 wx
.getSystemInfoSync.pixelRatio 獲取設(shè)備的像素比ratio,然后將在屏 Canvas 的寬度和高度按照所獲取的像素比ratio進行放大,在繪制文字、圖片的時候,坐標點 x、y 和所要繪制圖形的 width、height均需要按照像素比 ratio 進行縮放,這樣我們就可以清晰的在高清屏中繪制想要的文字、圖片。

可參考微信官方縮放策略調(diào)整

另外,需要注意的是,這里的 canvas 是由 weapp-adapter 預先調(diào)用 wx.createCanvas 創(chuàng)建一個上屏 Canvas,并暴露為一個全局變量 canvas。

在游戲畫布內(nèi),我們以左上角為坐標原點 {x: 0, y: 0} ,一個多邊形包含多個單位長度的平面坐標點,如:[{ x: 1, y: 3 }, { x: 5, y: 3 }, { x: 3, y: 5 }] 表示為一個三角形的區(qū)域,需要注意的是,x、y 并不是真實的平面坐標值,而是通過屏幕寬度計算出來的單位長度,在畫布內(nèi)的真實坐標值則為 {x: x * itemWidth, y: y * itemWidth} 。

繪制多邊形代碼實現(xiàn)如下:

使用:

效果如下圖:

CanvasRenderingContext2D其他使用方法可參考:CanvasRenderingContext2D API 列表

有經(jīng)驗的同學,也許一眼就發(fā)現(xiàn)了,1 + 1 = 0 剛好符合通過異或運算得出的結(jié)果。當然,細心的同學也可能已經(jīng)發(fā)現(xiàn),上文有一句特殊的代碼:
this.ctx.globalCompositeOperation = 'xor',也正是通過設(shè)置 CanvasContext 的 globalCompositeOperation 屬性值為 xor 便實現(xiàn)了「偶消奇不消」的神奇效果。

globalCompositeOperation 是指 在繪制新形狀時應(yīng)用的合成操作的類型,其他效果可參考:globalCompositeOperation 示例

講到這里,我們已經(jīng)知道如何在Canvas畫布內(nèi)繪制出偶消奇不消效果的層疊圖形了,接下來我們來看下玩家如何移動選中的圖形。我們發(fā)現(xiàn)繪制出的圖形對象并沒有提供點擊事件綁定之類的操作,那又如何判斷玩家選中了哪個圖形呢?這里我們就需要去實現(xiàn)如何判斷玩家觸摸事件的x,y坐標在哪個多邊形圖形內(nèi)部區(qū)域,從而判斷出玩家選中的是哪一個多邊形圖形。

判斷一個點是否在任意多邊形內(nèi)部有多種方法,比如:

  • 射線法

  • 面積判別法

  • 叉乘判別法

  • 回轉(zhuǎn)數(shù)法

  • ...

在層疊拼圖Plus小游戲內(nèi),采用的是回轉(zhuǎn)數(shù)法來判斷玩家觸摸點是否在多邊形內(nèi)部?;剞D(zhuǎn)數(shù)是拓撲學中的一個基本概念,具有很重要的性質(zhì)和用途。當然,展開討論回轉(zhuǎn)數(shù)的概念并不在該文的討論范圍內(nèi),我們僅需了解一個概念:當回轉(zhuǎn)數(shù)為 0 時,點在閉合曲線外部。

圖源:http://www.html-js.com/article/1538

上面面這張圖動態(tài)演示了回轉(zhuǎn)數(shù)的概念:圖中紅色曲線關(guān)于點(人所在位置)的回轉(zhuǎn)數(shù)為 2。

對于給定的點和多邊形,回轉(zhuǎn)數(shù)應(yīng)該怎么計算呢?

  • 用線段分別連接點和多邊形的全部頂點

圖源:http://www.html-js.com/article/1538

  • 計算所有點與相鄰頂點連線的夾角

圖源:http://www.html-js.com/article/1538

  • 計算所有夾角和。注意每個夾角都是有方向的,所以有可能是負值

圖源:http://www.html-js.com/article/1538

最后根據(jù)角度累加值計算回轉(zhuǎn)數(shù)。360°(2π)相當于一次回轉(zhuǎn)。

在使用 JavaScript 實現(xiàn)時,需要注意以下問題:

  • JavaScript 的數(shù)只有 64 位雙精度浮點這一種。對于三角函數(shù)產(chǎn)生的無理數(shù),浮點數(shù)計算不可避免會造成一些誤差,因此在最后計算回轉(zhuǎn)數(shù)需要做取整操作。

  • 通常情況下,平面直角坐標系內(nèi)一個角的取值范圍是 -π 到 π 這個區(qū)間,這也是 JavaScript 三角函數(shù) Math.atan2 返回值的范圍。但 JavaScript 并不能直接計算任意兩條線的夾角,我們只能先計算兩條線與 x 正軸夾角,再取兩者差值。這個差值的結(jié)果就有可能超出 -π 到 π 這個區(qū)間,因此我們還需要處理差值超出取值區(qū)間的情況。

代碼實現(xiàn):

javascript可以開發(fā)游戲嗎(如何用 JavaScript+Canvas 開發(fā)一款超級燒腦小游戲?)

通過前面的介紹我們可以知道,判斷游戲結(jié)果是否正確其實就是比對玩家組合圖形的 xor 結(jié)果與目標圖形的 xor 結(jié)果。那么如何求多個多邊形 xor 的結(jié)果呢?polygon-clipping 正是為此而生的。它不僅支持 xor 操作,還有其他的比如:union, intersection, difference 等操作。在層疊拼圖Plus游戲內(nèi)通過 polygon-clipping 又是怎樣實現(xiàn)游戲結(jié)果判斷的呢?

  • 目標圖形

多邊形平面坐標點集合:

獲取 多個多邊形 xor 結(jié)果:

xor結(jié)果:

同理計算出玩家操作圖形的xor結(jié)果進行比對即可得出答案正確與否。

需要注意的是,獲取玩家的 xor 結(jié)果并不能直接拿來與目標圖形xor 結(jié)果進行比較,我們需要將xor 的結(jié)果以左上角為參考點將圖形平移至原點內(nèi),然后再進行比較,如果結(jié)果一致,則代表玩家答案正確。

在看本章節(jié)內(nèi)容之前,建議先瀏覽一遍排行榜相關(guān)的官方文檔:好友排行榜、關(guān)系鏈數(shù)據(jù),以便對相關(guān)內(nèi)容有個大概的了解。

  • 開放數(shù)據(jù)域

開放數(shù)據(jù)域是一個封閉、獨立的 JavaScript 作用域。要讓代碼運行在開放數(shù)據(jù)域,需要在 game.json 中添加配置項 openDataContext 指定開放數(shù)據(jù)域的代碼目錄。添加該配置項表示小游戲啟用了開放數(shù)據(jù)域,這將會導致一些限制。

  • 在游戲內(nèi)使用 wx.setUserCloudStorage(obj) 對玩家游戲數(shù)據(jù)進行托管。

  • 在開放數(shù)據(jù)域內(nèi)使用 wx.getFriendCloudStorage(obj)拉取當前用戶所有同玩好友的托管數(shù)據(jù)

  • 展示關(guān)系鏈數(shù)據(jù)

如果想要展示通過關(guān)系鏈 API 獲取到的用戶數(shù)據(jù),如繪制排行榜等業(yè)務(wù)場景,需要將排行榜繪制到 sharedCanvas 上,再在主域?qū)?sharedCanvas 渲染上屏。

sharedCanvas 是主域和開放數(shù)據(jù)域都可以訪問的一個離屏畫布。在開放數(shù)據(jù)域調(diào)用 wx.getSharedCanvas 將返回 sharedCanvas。

在主域中可以通過開放數(shù)據(jù)域?qū)嵗L問 sharedCanvas,通過 drawImage 方法可以將 sharedCanvas 繪制到上屏畫布。

sharedCanvas 本質(zhì)上也是一個離屏 Canvas,而重設(shè) Canvas 的寬高會清空 Canvas 上的內(nèi)容。所以要通知開放數(shù)據(jù)域去重繪 sharedCanvas。

需要注意的是:sharedCanvas 的寬高只能在主域設(shè)置,不能在開放數(shù)據(jù)域中設(shè)置。

一款能讓人心情愉悅的游戲,性能問題必然不能成為絆腳石。那么可以從哪些方面對游戲進行性能優(yōu)化呢?

在層疊拼圖Plus小游戲內(nèi),針對需要大量使用且繪圖繁復的靜態(tài)場景,都是使用離屏 Canvas進行繪制的,如首頁網(wǎng)格背景、關(guān)卡列表、排名列表等。在微信內(nèi) wx.createCanvas 首次調(diào)用創(chuàng)建的是顯示在屏幕上的畫布,之后調(diào)用創(chuàng)建的都是離屏畫布。初始化時將靜態(tài)場景繪制完備,需要時直接拷貝離屏Canvas的圖像即可。Canvas 繪制本身就是不斷的更新幀從而達到動畫的效果,通過使用離屏 Canvas,就大大減少了一些靜態(tài)內(nèi)容在上屏Canvas的繪制,從而提升了繪制性能。

內(nèi)存優(yōu)化

玩家在游戲過程中拖動方塊的移動其實就是不斷更新多邊形圖形的坐標信息,然后不斷的清空畫布再重新繪制,可以想象,這個繪制是非常頻繁的,按照普通的做法就需要不斷去創(chuàng)建多個新的 Block 對象。針對游戲中需要頻繁更新的對象,我們可以通過使用對象池的方法進行優(yōu)化,對象池維護一個裝著空閑對象的池子,如果需要對象的時候,不是直接new,而是從對象池中取出,如果對象池中沒有空閑對象,則新建一個空閑對象,層疊拼圖Plus小游戲內(nèi)使用的是官方demo內(nèi)已經(jīng)實現(xiàn)的對象池類,實現(xiàn)如下:

垃圾回收

小游戲中,JavaScript 中的每一個 Canvas 或 Image 對象都會有一個客戶端層的實際紋理儲存,實際紋理儲存中存放著 Canvas、Image 的真實紋理,通常會占用相當一部分內(nèi)存。

每個客戶端實際紋理儲存的回收時機依賴于 JavaScript 中的 Canvas、Image 對象回收。在 JavaScript 的 Canvas、Image 對象被回收之前,客戶端對應(yīng)的實際紋理儲存不會被回收。通過調(diào)用 wx.triggerGC 方法,可以加快觸發(fā) JavaScriptCore Garbage Collection(垃圾回收),從而觸發(fā) JavaScript 中沒有引用的 Canvas、Image 回收,釋放對應(yīng)的實際紋理儲存。

但 GC 具體觸發(fā)時機還要取決于 JavaScriptCore 自身機制,并不能保證調(diào)用 wx.triggerGC 能馬上觸發(fā)回收,層疊拼圖Plus小游戲在每局游戲開始或結(jié)束都會觸發(fā)一下,及時回收內(nèi)存垃圾,以保證最良好的游戲體驗。

對于游戲來說,每幀 16ms 是極其寶貴的,如果有一些可以異步處理的任務(wù),可以放置于 Worker 中運行,待運行結(jié)束后,再把結(jié)果返回到主線程。Worker 運行于一個單獨的全局上下文與線程中,不能直接調(diào)用主線程的方法,Worker 也不具備渲染的能力。Worker與主線程之間的數(shù)據(jù)傳輸,雙方使用 Worker.postMessage 來發(fā)送數(shù)據(jù),Worker.onMessage 來接收數(shù)據(jù),傳輸?shù)臄?shù)據(jù)并不是直接共享,而是被復制的。

需要注意的是:Worker 最大并發(fā)數(shù)量限制為 1 個,創(chuàng)建下一個前請用 Worker.terminate 結(jié)束當前 Worker

其他 Worker相關(guān)的內(nèi)容請參考微信官方文檔:多線程 Worker

短短的一篇文章,定不能將層疊拼圖Plus小游戲的前前后后講明白講透徹。其實最讓人心累的還是軟著的申請過程,由于各種原因前前后后花了將近三個月的時間,后續(xù)可以給大家分享軟著申請相關(guān)的內(nèi)容,希望可以幫助到需要的童鞋。

江湖不遠,我們游戲里見!

作者簡介:huangjianke,高級iOS開發(fā)/前端開發(fā)工程師,五年開發(fā)經(jīng)驗。

需要體驗小游戲的童鞋可在微信小程序搜索層疊拼圖Plus。

【END】

javascript可以開發(fā)游戲嗎(如何用 JavaScript+Canvas 開發(fā)一款超級燒腦小游戲?)

熱門課程推薦

熱門資訊

請綁定手機號

x

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯(lián)系,請保持電話暢通!
確定