異名在一個遊戲項目中遇到一個比較有意思的問題,在遊戲的玩法設定中,當怪物在消失的時候會爆出一箇中文字,這個效果在部分機型上會出現亂碼符號css
顯示亂碼的緣由
一開始還覺得是字符太多了,char
的紋理不夠用了,還嘗試過手動調用遊戲引擎的cc.Label.clearCharCache
去清除;後來才認識到是生僻字的問題,這得從字符編碼提及,Unicode
爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言、跨平臺進行文本轉換、處理的要求,其中:前端
❝❞
3400~4dffh
:是中日韓認同表意文字擴充a區,總計收容6,582箇中日韓漢字4e00~9fffh
:是中日韓認同表意文字區,總計收容20,902箇中日韓漢字web
一般狀況下,咱們平常所用到的中日韓非符號字符都會落在3400-9fff
這個編碼區間,所以當咱們須要判斷某一個字符是不是屬於漢字的時候,就能夠經過查看它的的Unicode
編碼是否落在這個區間,咱們寫一個正則去檢查一下上面兩個字符👇:瀏覽器
能夠看到第二個字它並不處於經常使用漢字的編碼區間,它是生僻字,生僻字的使用頻率很低,咱們平常高頻用的的漢字其實也就是幾千個而已。字體公司設計漢字字體的成本比較高,由於若是要設計一款英文字體,那就只要設計26個字母就能夠組合出全部的單詞了,而每個漢字則幾乎都須要人工去作造型,生僻字的造字性價比可見有多低,能夠說每一款漢字字體都是收錄殘缺,缺多缺乏而已。因此這就解析了爲啥在華爲的手機上爲啥看到的是亂碼而在蘋果手機上卻能正常顯示該字符,由於他們的系統字體庫不一樣,華爲的字體庫沒有錄用這個生僻字性能優化
解決方法
在前端要解決生僻字的顯示問題能夠利用css的font-family
的字體備選機制,能夠把這個生僻字單獨作成一個字體文件,而後經過@font-face
嵌入,而後在須要的地方引用,瀏覽器在解析文字的時候會逐字匹配,當字體上沒有這個字符的時候就會在備用的字體上選擇,從而可以讓咱們的生僻字被顯示出來,通常生成單字體文件有這幾種方式:微信
字體切割
若是你缺失的還不算太生僻,可能在某些字體庫中收錄了這個字,那就能夠經過字蛛或者fontmin
這些字體提取方案把這個字單獨提取出來,做爲單字體文件引用app
icon font
讓設計師單獨針對這個生僻字作設計而後生成icon font,能夠直接上傳阿里的iconfont,而後再下載代碼,默認會給到Unicode
、Font class
、Symbol
三種引用方式async
專用的字體信息網站
有一個日本的字體信息網站glyphwiki.org
,支持檢索,甚至能夠經過偏旁部首拼湊生僻字,也很是方便編輯器
位圖字體
固然在遊戲中,更常見的方式是使用位圖字體,位圖字體由 fnt 格式的字體文件和一張png
圖片組成,fnt
文件提供了對每個字符小圖的索引,這種格式的字體能夠由專門的軟件生成,異名用的是shoebox
。由於位圖字體是一個符號和圖片的索引文件,因此咱們能夠把某個場景下具備特點的字體都單獨作設計,固然也能夠應用在生僻字的顯示中:性能
這個也是異名最終使用的方案,你永遠不知道你的下一個遊戲背景設定是什麼,萬一是山海經裏面的遠古神獸或者是像異名這種學科遊戲裏面的奇葩新造字,或者可以給你們帶來一點參考。
不可靠的String.length
以上就把需求解決完了,可是異名在踩坑的過程當中還發現一個有趣的事情:
字符串的length屬性是多麼的不可靠!並且更有意思的是,String.length
的長度不是2嗎,可是若是你用不一樣的方式去遍歷,你還會發現一些更神奇的事情:
異名看到這個執行結果的時候是挺驚訝,並且這個怪異表現可能還會和咱們的平常工做產生交集。相對於漢字,咱們更常常遇到的問題多是emoji
,好比某天產品經理有個需求,用戶的姓名輸入框要作一個長度限制,長度不能超過十,你說簡單啊,利用length作一下校驗,長度超過十的就攔截了。而後測試同窗,啪啪啪輸入五個💩...
這個需求相信大部分前端都有遇到過,用length去判斷是不可靠的,爲何呢?由於在字符編碼上,有好幾種方式能夠用來表達字符:
💩能夠是一個字符,可是也能夠用兩個字符來表達,因此你就不能奢望String.length
能給到你一個可靠的結果了。這個時候咱們回頭看一眼MDN上對String.length
的描述,你就會發現人家一開始就說了,我不可靠...
那有沒有一種可靠的方法可以準確統計字符串的長度呢,我上面舉了Array.from
的例子,它正確返回了字符的長度,可是它也只是一個有缺陷的方案,它對某些字符有效
有興趣的同窗能夠點擊原文跳轉,在原文那裏,異名貼了兩篇參考文章,他們進行了更深刻的研究
本文分享自微信公衆號 - 異名(async-code)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。