iOS彈幕(原始碼)實現原理解析

發表於2016-03-15
  最近,讀完今年的第三本書《大話移動APP測試 Android與iOS》,在讀到陳曄前輩改變中國測試行業的決心時,內心無比激動,作為一名初生的開發人員,我可能還無法理解測試行業的本質,但他那份通過分享改變現狀的決心我深感共鳴。在此為每一位願分享願奉獻的朋友點個贊!

  彈幕,國內流行於視訊網站A站和B站。網上關於彈幕的實現方法有很多,目前Android平臺已經有比較成熟的解決方案DanmakuFlameMaster 。而iOS平臺尚無比較成熟的開源庫,在借鑑DanmakuFlameMaster的實現思想後,特分享iOS平臺彈幕解決方案HJDanmakuDemo。本文將介紹彈幕的大致實現原理。

看過DanmakuFlameMaster原始碼的朋友都知道,彈幕實現主要需要解決以下幾個問題

  1. 彈幕繪製方式
  2. 彈幕時間控制
  3. 彈幕碰撞檢測原理
  4. 彈幕暫停及恢復

本文主要從以上4個方面介紹彈幕的詳細實現原理。首先是彈幕繪製方式,在DanmakuFlameMaster庫中,它主要通過view的自定義draw一幀一幀的繪製來完成彈幕的顯示,這種方式最大的問題在於效能以及動畫的不流暢。彈幕流暢的前提要求每秒繪製的幀數在30幀以上,而移動裝置效能千差萬別,當同一時刻需要繪製大量彈幕的時候,對於低端裝置就會出現卡幀不流暢的情況,這會大大降低使用者的體驗。因此,在本專案中放棄採用自定義繪製幀的方式,而是採用系統動畫的方式來實現彈幕文字的滾動。

其次,就是彈幕時間的控制。由於採用系統動畫的方式,所以不需要時刻計算每一個彈幕的顯示時間以及其X座標(假設彈幕橫向滾動),我們需要做的就是在彈幕需要出現的時候建立它,然後設定彈幕存活的時間,剩餘滾動動畫交給系統負責,當然,彈幕剩餘時間需要我們來更新。本專案中,建立了一個0.5s間隔的定時器,主要負責建立新的彈幕並更新已顯示彈幕的剩餘時間,也就是說0.5s執行一次計算,如果需要,可以將重新整理間隔設定成5s或者更長。

然後,就是彈幕碰撞檢測的問題。碰撞檢測主要難點在於檢測橫向滾動彈幕之間的碰撞,彈幕存活時間由其顯示時間和存活長短決定,因此,彈幕之間是否碰撞只需檢測開始和消失是否碰撞即可。

最後,彈幕的暫停及恢復。由於彈幕滾動採用系統動畫,所以在解決彈幕暫停前需要先了解系統動畫的實現原理,有興趣的朋友可以參考動畫解釋這篇文章,在此就不做過多介紹。暫停的基本原理就是通過view的presentationLayer獲取物件的當前座標並賦給其frame,然後移除layer動畫,考慮到緩衝,可以在當前座標基礎上-1

有興趣的童鞋可以下載HJDanmakuDemo檢視具體使用方法,有什麼疑問可以在後面留言。 如果你喜歡,希望能在github上為本demo點上一讚,感謝你的來訪!

相關文章