發(fā)布時(shí)間:2023-11-27 12:17:49 瀏覽量:113次
作者 | huangjianke
責(zé)編 | 伍杏玲
出品 | CSDN(ID:CSDNnews)
【CSDN 編者按】據(jù)微信最新數(shù)據(jù),微信小游戲累計(jì)注冊(cè)用戶(hù)量已突破10億。那么初學(xué)者如何開(kāi)發(fā)一款好玩又燒腦的微信小游戲呢?本文作者將詳細(xì)為大家講解。
“啟邏輯之高妙,因想象而自由?!睂盈B拼圖Plus是一款需要空間想象力和邏輯推理能力完美結(jié)合的微信小游戲,偶消奇不消,在簡(jiǎn)單的游戲規(guī)則下卻有著無(wú)數(shù)種可能性,需要你充分發(fā)揮想象力去探索,看似簡(jiǎn)單卻具有極大的挑戰(zhàn)性和趣味性,Talk is cheap. Show me the code!
層疊拼圖Plus微信小游戲采用JavaScript+Canvas實(shí)現(xiàn),沒(méi)有使用任何游戲引擎,對(duì)于初學(xué)者來(lái)說(shuō),也比較容易入門(mén)。下面是小游戲頁(yè)面:
繪圖模糊的原因知道了,在微信小游戲里面又該如何解決呢?
可以看到,我們先通過(guò) wx
.getSystemInfoSync.pixelRatio 獲取設(shè)備的像素比ratio,然后將在屏 Canvas 的寬度和高度按照所獲取的像素比ratio進(jìn)行放大,在繪制文字、圖片的時(shí)候,坐標(biāo)點(diǎn) x、y 和所要繪制圖形的 width、height均需要按照像素比 ratio 進(jìn)行縮放,這樣我們就可以清晰的在高清屏中繪制想要的文字、圖片。
可參考微信官方縮放策略調(diào)整
另外,需要注意的是,這里的 canvas 是由 weapp-adapter 預(yù)先調(diào)用 wx.createCanvas 創(chuàng)建一個(gè)上屏 Canvas,并暴露為一個(gè)全局變量 canvas。
在游戲畫(huà)布內(nèi),我們以左上角為坐標(biāo)原點(diǎn) {x: 0, y: 0} ,一個(gè)多邊形包含多個(gè)單位長(zhǎng)度的平面坐標(biāo)點(diǎn),如:[{ x: 1, y: 3 }, { x: 5, y: 3 }, { x: 3, y: 5 }] 表示為一個(gè)三角形的區(qū)域,需要注意的是,x、y 并不是真實(shí)的平面坐標(biāo)值,而是通過(guò)屏幕寬度計(jì)算出來(lái)的單位長(zhǎng)度,在畫(huà)布內(nèi)的真實(shí)坐標(biāo)值則為 {x: x * itemWidth, y: y * itemWidth} 。
繪制多邊形代碼實(shí)現(xiàn)如下:
使用:
效果如下圖:
CanvasRenderingContext2D其他使用方法可參考:CanvasRenderingContext2D API 列表
有經(jīng)驗(yàn)的同學(xué),也許一眼就發(fā)現(xiàn)了,1 + 1 = 0 剛好符合通過(guò)異或運(yùn)算得出的結(jié)果。當(dāng)然,細(xì)心的同學(xué)也可能已經(jīng)發(fā)現(xiàn),上文有一句特殊的代碼:
this.ctx.globalCompositeOperation = 'xor',也正是通過(guò)設(shè)置 CanvasContext 的 globalCompositeOperation 屬性值為 xor 便實(shí)現(xiàn)了「偶消奇不消」的神奇效果。
globalCompositeOperation 是指 在繪制新形狀時(shí)應(yīng)用的合成操作的類(lèi)型,其他效果可參考:globalCompositeOperation 示例
講到這里,我們已經(jīng)知道如何在Canvas畫(huà)布內(nèi)繪制出偶消奇不消效果的層疊圖形了,接下來(lái)我們來(lái)看下玩家如何移動(dòng)選中的圖形。我們發(fā)現(xiàn)繪制出的圖形對(duì)象并沒(méi)有提供點(diǎn)擊事件綁定之類(lèi)的操作,那又如何判斷玩家選中了哪個(gè)圖形呢?這里我們就需要去實(shí)現(xiàn)如何判斷玩家觸摸事件的x,y坐標(biāo)在哪個(gè)多邊形圖形內(nèi)部區(qū)域,從而判斷出玩家選中的是哪一個(gè)多邊形圖形。
判斷一個(gè)點(diǎn)是否在任意多邊形內(nèi)部有多種方法,比如:
射線法
面積判別法
叉乘判別法
回轉(zhuǎn)數(shù)法
...
在層疊拼圖Plus小游戲內(nèi),采用的是回轉(zhuǎn)數(shù)法來(lái)判斷玩家觸摸點(diǎn)是否在多邊形內(nèi)部?;剞D(zhuǎn)數(shù)是拓?fù)鋵W(xué)中的一個(gè)基本概念,具有很重要的性質(zhì)和用途。當(dāng)然,展開(kāi)討論回轉(zhuǎn)數(shù)的概念并不在該文的討論范圍內(nèi),我們僅需了解一個(gè)概念:當(dāng)回轉(zhuǎn)數(shù)為 0 時(shí),點(diǎn)在閉合曲線外部。
圖源:http://www.html-js.com/article/1538
上面面這張圖動(dòng)態(tài)演示了回轉(zhuǎn)數(shù)的概念:圖中紅色曲線關(guān)于點(diǎn)(人所在位置)的回轉(zhuǎn)數(shù)為 2。
對(duì)于給定的點(diǎn)和多邊形,回轉(zhuǎn)數(shù)應(yīng)該怎么計(jì)算呢?
用線段分別連接點(diǎn)和多邊形的全部頂點(diǎn)
圖源:http://www.html-js.com/article/1538
計(jì)算所有點(diǎn)與相鄰頂點(diǎn)連線的夾角
圖源:http://www.html-js.com/article/1538
計(jì)算所有夾角和。注意每個(gè)夾角都是有方向的,所以有可能是負(fù)值
圖源:http://www.html-js.com/article/1538
最后根據(jù)角度累加值計(jì)算回轉(zhuǎn)數(shù)。360°(2π)相當(dāng)于一次回轉(zhuǎn)。
在使用 JavaScript 實(shí)現(xiàn)時(shí),需要注意以下問(wèn)題:
JavaScript 的數(shù)只有 64 位雙精度浮點(diǎn)這一種。對(duì)于三角函數(shù)產(chǎn)生的無(wú)理數(shù),浮點(diǎn)數(shù)計(jì)算不可避免會(huì)造成一些誤差,因此在最后計(jì)算回轉(zhuǎn)數(shù)需要做取整操作。
通常情況下,平面直角坐標(biāo)系內(nèi)一個(gè)角的取值范圍是 -π 到 π 這個(gè)區(qū)間,這也是 JavaScript 三角函數(shù) Math.atan2 返回值的范圍。但 JavaScript 并不能直接計(jì)算任意兩條線的夾角,我們只能先計(jì)算兩條線與 x 正軸夾角,再取兩者差值。這個(gè)差值的結(jié)果就有可能超出 -π 到 π 這個(gè)區(qū)間,因此我們還需要處理差值超出取值區(qū)間的情況。
代碼實(shí)現(xiàn):
通過(guò)前面的介紹我們可以知道,判斷游戲結(jié)果是否正確其實(shí)就是比對(duì)玩家組合圖形的 xor 結(jié)果與目標(biāo)圖形的 xor 結(jié)果。那么如何求多個(gè)多邊形 xor 的結(jié)果呢?polygon-clipping 正是為此而生的。它不僅支持 xor 操作,還有其他的比如:union, intersection, difference 等操作。在層疊拼圖Plus游戲內(nèi)通過(guò) polygon-clipping 又是怎樣實(shí)現(xiàn)游戲結(jié)果判斷的呢?
目標(biāo)圖形
多邊形平面坐標(biāo)點(diǎn)集合:
獲取 多個(gè)多邊形 xor 結(jié)果:
xor結(jié)果:
同理計(jì)算出玩家操作圖形的xor結(jié)果進(jìn)行比對(duì)即可得出答案正確與否。
需要注意的是,獲取玩家的 xor 結(jié)果并不能直接拿來(lái)與目標(biāo)圖形xor 結(jié)果進(jìn)行比較,我們需要將xor 的結(jié)果以左上角為參考點(diǎn)將圖形平移至原點(diǎn)內(nèi),然后再進(jìn)行比較,如果結(jié)果一致,則代表玩家答案正確。
在看本章節(jié)內(nèi)容之前,建議先瀏覽一遍排行榜相關(guān)的官方文檔:好友排行榜、關(guān)系鏈數(shù)據(jù),以便對(duì)相關(guān)內(nèi)容有個(gè)大概的了解。
開(kāi)放數(shù)據(jù)域
開(kāi)放數(shù)據(jù)域是一個(gè)封閉、獨(dú)立的 JavaScript 作用域。要讓代碼運(yùn)行在開(kāi)放數(shù)據(jù)域,需要在 game.json 中添加配置項(xiàng) openDataContext 指定開(kāi)放數(shù)據(jù)域的代碼目錄。添加該配置項(xiàng)表示小游戲啟用了開(kāi)放數(shù)據(jù)域,這將會(huì)導(dǎo)致一些限制。
在游戲內(nèi)使用 wx.setUserCloudStorage(obj) 對(duì)玩家游戲數(shù)據(jù)進(jìn)行托管。
在開(kāi)放數(shù)據(jù)域內(nèi)使用 wx.getFriendCloudStorage(obj)拉取當(dāng)前用戶(hù)所有同玩好友的托管數(shù)據(jù)
展示關(guān)系鏈數(shù)據(jù)
如果想要展示通過(guò)關(guān)系鏈 API 獲取到的用戶(hù)數(shù)據(jù),如繪制排行榜等業(yè)務(wù)場(chǎng)景,需要將排行榜繪制到 sharedCanvas 上,再在主域?qū)?sharedCanvas 渲染上屏。
sharedCanvas 是主域和開(kāi)放數(shù)據(jù)域都可以訪問(wèn)的一個(gè)離屏畫(huà)布。在開(kāi)放數(shù)據(jù)域調(diào)用 wx.getSharedCanvas 將返回 sharedCanvas。
在主域中可以通過(guò)開(kāi)放數(shù)據(jù)域?qū)嵗L問(wèn) sharedCanvas,通過(guò) drawImage 方法可以將 sharedCanvas 繪制到上屏畫(huà)布。
sharedCanvas 本質(zhì)上也是一個(gè)離屏 Canvas,而重設(shè) Canvas 的寬高會(huì)清空 Canvas 上的內(nèi)容。所以要通知開(kāi)放數(shù)據(jù)域去重繪 sharedCanvas。
需要注意的是:sharedCanvas 的寬高只能在主域設(shè)置,不能在開(kāi)放數(shù)據(jù)域中設(shè)置。
一款能讓人心情愉悅的游戲,性能問(wèn)題必然不能成為絆腳石。那么可以從哪些方面對(duì)游戲進(jìn)行性能優(yōu)化呢?
在層疊拼圖Plus小游戲內(nèi),針對(duì)需要大量使用且繪圖繁復(fù)的靜態(tài)場(chǎng)景,都是使用離屏 Canvas進(jìn)行繪制的,如首頁(yè)網(wǎng)格背景、關(guān)卡列表、排名列表等。在微信內(nèi) wx.createCanvas 首次調(diào)用創(chuàng)建的是顯示在屏幕上的畫(huà)布,之后調(diào)用創(chuàng)建的都是離屏畫(huà)布。初始化時(shí)將靜態(tài)場(chǎng)景繪制完備,需要時(shí)直接拷貝離屏Canvas的圖像即可。Canvas 繪制本身就是不斷的更新幀從而達(dá)到動(dòng)畫(huà)的效果,通過(guò)使用離屏 Canvas,就大大減少了一些靜態(tài)內(nèi)容在上屏Canvas的繪制,從而提升了繪制性能。
內(nèi)存優(yōu)化
玩家在游戲過(guò)程中拖動(dòng)方塊的移動(dòng)其實(shí)就是不斷更新多邊形圖形的坐標(biāo)信息,然后不斷的清空畫(huà)布再重新繪制,可以想象,這個(gè)繪制是非常頻繁的,按照普通的做法就需要不斷去創(chuàng)建多個(gè)新的 Block 對(duì)象。針對(duì)游戲中需要頻繁更新的對(duì)象,我們可以通過(guò)使用對(duì)象池的方法進(jìn)行優(yōu)化,對(duì)象池維護(hù)一個(gè)裝著空閑對(duì)象的池子,如果需要對(duì)象的時(shí)候,不是直接new,而是從對(duì)象池中取出,如果對(duì)象池中沒(méi)有空閑對(duì)象,則新建一個(gè)空閑對(duì)象,層疊拼圖Plus小游戲內(nèi)使用的是官方demo內(nèi)已經(jīng)實(shí)現(xiàn)的對(duì)象池類(lèi),實(shí)現(xiàn)如下:
垃圾回收
小游戲中,JavaScript 中的每一個(gè) Canvas 或 Image 對(duì)象都會(huì)有一個(gè)客戶(hù)端層的實(shí)際紋理儲(chǔ)存,實(shí)際紋理儲(chǔ)存中存放著 Canvas、Image 的真實(shí)紋理,通常會(huì)占用相當(dāng)一部分內(nèi)存。
每個(gè)客戶(hù)端實(shí)際紋理儲(chǔ)存的回收時(shí)機(jī)依賴(lài)于 JavaScript 中的 Canvas、Image 對(duì)象回收。在 JavaScript 的 Canvas、Image 對(duì)象被回收之前,客戶(hù)端對(duì)應(yīng)的實(shí)際紋理儲(chǔ)存不會(huì)被回收。通過(guò)調(diào)用 wx.triggerGC 方法,可以加快觸發(fā) JavaScriptCore Garbage Collection(垃圾回收),從而觸發(fā) JavaScript 中沒(méi)有引用的 Canvas、Image 回收,釋放對(duì)應(yīng)的實(shí)際紋理儲(chǔ)存。
但 GC 具體觸發(fā)時(shí)機(jī)還要取決于 JavaScriptCore 自身機(jī)制,并不能保證調(diào)用 wx.triggerGC 能馬上觸發(fā)回收,層疊拼圖Plus小游戲在每局游戲開(kāi)始或結(jié)束都會(huì)觸發(fā)一下,及時(shí)回收內(nèi)存垃圾,以保證最良好的游戲體驗(yàn)。
對(duì)于游戲來(lái)說(shuō),每幀 16ms 是極其寶貴的,如果有一些可以異步處理的任務(wù),可以放置于 Worker 中運(yùn)行,待運(yùn)行結(jié)束后,再把結(jié)果返回到主線程。Worker 運(yùn)行于一個(gè)單獨(dú)的全局上下文與線程中,不能直接調(diào)用主線程的方法,Worker 也不具備渲染的能力。Worker與主線程之間的數(shù)據(jù)傳輸,雙方使用 Worker.postMessage 來(lái)發(fā)送數(shù)據(jù),Worker.onMessage 來(lái)接收數(shù)據(jù),傳輸?shù)臄?shù)據(jù)并不是直接共享,而是被復(fù)制的。
需要注意的是:Worker 最大并發(fā)數(shù)量限制為 1 個(gè),創(chuàng)建下一個(gè)前請(qǐng)用 Worker.terminate 結(jié)束當(dāng)前 Worker
其他 Worker
相關(guān)的內(nèi)容請(qǐng)參考微信官方文檔:多線程 Worker
短短的一篇文章,定不能將層疊拼圖Plus小游戲的前前后后講明白講透徹。其實(shí)最讓人心累的還是軟著的申請(qǐng)過(guò)程,由于各種原因前前后后花了將近三個(gè)月的時(shí)間,后續(xù)可以給大家分享軟著申請(qǐng)相關(guān)的內(nèi)容,希望可以幫助到需要的童鞋。
江湖不遠(yuǎn),我們游戲里見(jiàn)!
作者簡(jiǎn)介:huangjianke,高級(jí)iOS開(kāi)發(fā)/前端開(kāi)發(fā)工程師,五年開(kāi)發(fā)經(jīng)驗(yàn)。
需要體驗(yàn)小游戲的童鞋可在微信小程序搜索層疊拼圖Plus。
【END】
熱門(mén)資訊
探討游戲引擎的文章,介紹了10款游戲引擎及其代表作品,涵蓋了RAGE Engine、Naughty Dog Game Engine、The Dead Engine、Cry Engine、Avalanche Engine、Anvil Engine、IW Engine、Frostbite Engine、Creation引擎、Unreal Engine等引擎。借此分析引出了游戲設(shè)計(jì)領(lǐng)域和數(shù)字藝術(shù)教育的重要性,歡迎點(diǎn)擊咨詢(xún)報(bào)名。
2. 手機(jī)游戲如何開(kāi)發(fā)(如何制作傳奇手游,都需要準(zhǔn)備些什么?)
?如何制作傳奇手游,都需要準(zhǔn)備些什么?提到傳奇手游相信大家都不陌生,他是許多80、90后的回憶;從起初的端游到現(xiàn)在的手游,說(shuō)明時(shí)代在進(jìn)步游戲在更新,更趨于方便化移動(dòng)化。而如果我們想要制作一款傳奇手游的
3. B站視頻剪輯軟件「必剪」:免費(fèi)、炫酷特效,小白必備工具
B站視頻剪輯軟件「必剪」,完全免費(fèi)、一鍵制作炫酷特效,適合新手小白??靵?lái)試試!
4. Steam值得入手的武俠游戲盤(pán)點(diǎn),各具特色的快意江湖
游戲中玩家將面臨武俠人生的掙扎抉擇,戰(zhàn)或降?殺或放?每個(gè)抉定都將觸發(fā)更多愛(ài)恨糾葛的精彩奇遇?!短烀嬗肪哂卸嗑€劇情多結(jié)局,不限主線發(fā)展,高自由...
5. Bigtime加密游戲經(jīng)濟(jì)體系揭秘,不同玩家角色的經(jīng)濟(jì)活動(dòng)
Bigtime加密游戲經(jīng)濟(jì)模型分析,探討游戲經(jīng)濟(jì)特點(diǎn),幫助玩家更全面了解這款GameFi產(chǎn)品。
6. 3D動(dòng)漫建模全過(guò)程,不是一般人能學(xué)的會(huì)的,會(huì)的多不是人?
步驟01:面部,頸部,身體在一起這次我不準(zhǔn)備設(shè)計(jì)圖片,我從雕刻進(jìn)入。這一次,它將是一種純粹關(guān)注建模而非整體繪畫(huà)的形式。像往常一樣,我從Sphere創(chuàng)建它...
7. 3D動(dòng)畫(huà)軟件你知道幾個(gè)?3ds Max、Blender、Maya、Houdini大比拼
當(dāng)提到3D動(dòng)畫(huà)軟件或動(dòng)畫(huà)工具時(shí),指的是數(shù)字內(nèi)容創(chuàng)建工具。它是用于造型、建模以及繪制3D美術(shù)動(dòng)畫(huà)的軟件程序。但是,在3D動(dòng)畫(huà)軟件中還包含了其他類(lèi)型的...
8. 開(kāi)發(fā)三昧游戲叫什么(三昧動(dòng)漫)
?三昧動(dòng)漫對(duì)于著名ARPG游戲《巫師》系列,最近CD Projekt 的高層回應(yīng)并不會(huì)推出《巫師4》。因?yàn)椤段讕煛废盗性诓邉澋臅r(shí)候一直定位在“三部曲”的故事框架,所以在游戲的出品上不可能出現(xiàn)《巫師4》
9. 3D打印技巧揭秘!Cura設(shè)置讓你的模型更堅(jiān)固
想讓你的3D打印模型更堅(jiān)固?不妨嘗試一下Cura參數(shù)設(shè)置和設(shè)計(jì)技巧,讓你輕松掌握!
10. Unity3D入門(mén):手把手帶你開(kāi)發(fā)一款坦克大戰(zhàn)的游戲
Unity工程創(chuàng)建完成后如圖所示: 接下來(lái)應(yīng)該導(dǎo)入此項(xiàng)目所需的Unity Package文件,要用到的Unity package文件大家可以去Unity3D的官方網(wǎng)站下載(地址:ht...
最新文章
同學(xué)您好!