今天的任務是給2048加上動畫。別看用js的transition就搞定的事情,用GDI來實現是有難度的。git
雖然代碼抄自gabrielecirulli/2048: A small clone of 1024 (https://play.google.com/store/apps/details?id=com.veewo.a1024) ,可是將js代碼用lua去實現仍是多費了點工夫。固然二者都是動態語言,坑比較少。github
如今來說下2048是怎樣實現的。算法
首先,咱們看界面,它就是個4x4的方塊,顯而易見,用4x4數組或1x16數組就能搞定。那麼數組裏面存什麼呢?咱們分析2048中的數值:空方格、2的冪次數值方塊,就兩種。解決方案是隻要存int——空方格對應0;2的冪就對應它的冪。因此:空=0,2=1,以此類推,2048=11。所以數據結構很是簡單,隨便用僞代碼表示:[2048-Table] = array<int>(4x4)。數組
知道了數據結構,那麼接下來就是算法,這是難的部分。數據結構
算法須要解決一些問題:app
下面解決主要問題。框架
1、判斷是否要合併模塊化
假如當前按下Left鍵,方塊向左移動,假如某行是「2-2-4-4」,那麼結果是「4-8-0-0」,由於只須要合併相鄰的方塊;如果「2-2-2-2」,結果是「4-4-0-0」,不會是「8-0-0-0」,這是由算法決定的。函數
那麼問題變簡單了,正如memcpy所作的,若是memcpy(src,dst),其中src和dst有交界部分。若src在dst前面,那麼應該從後向前複製,反之是從前向後。佈局
同理,方向爲Left時,對於「2-2-4-4」,是從左向右遍歷,先肯定「2-2」,將其換爲4,變成「4-0-4-4」,而後處理右邊兩個4。此時,左起第一個4其實已經合併過了,將其排除,因此當前只要處理「0-4-4」,那麼再將當中的4移至最左,成爲「4-0-4」,再處理第二個4,因爲第一個4還沒有合併過,所以兩個4再進行合併,成爲8。最後結果「4-8-0-0」。
整理一個過程:Left,2-2-4-4,加[]表示已合併過,無需再次合併。2-2-4-4 => [4]-0-4-4 => [4]-4-0-4 => [4]-[8]-0-0。
2、對不能合併的方塊進行移動
如「2-4-6-0」,方向Right,從右向左遍歷。過程爲:2-4-6-0 => 2-4-0-6 => 2-0-4-6 => 0-2-4-6。解釋略。
3、隨機增長新方塊
增長新方塊,添加2和4的機率比爲9比1,用隨機數實現。
而後須要尋找空位添加,這簡單,遍歷4x4數組,找到數值爲0的將其位置記錄,接着隨機抽位子。
---------------------------------------
花了一天實現了方塊的移動,也有難度。
項目相關:佈局只支持新增GUI對象,不支持刪除,所以須要一開始就建立好。
思路:原4x4中每一個方塊對應一個GUI對象(記做origin),另外再新建4x4的GUI對象(記做anime),用於實現動畫。
例:當前2-2-4-4,方向Right,結果爲0-0-4-8。設計動畫,假設[n]表明從左起第n個位置。
方塊移動:[1,2,3,4] => [3,3,4,4]。那麼當第一個2(位置爲[1])進行移動時,這時應該將origin方塊隱藏,將替身anime方塊代替origin位置並顯現,隨後播放動畫,將anime的位置從[1]逐漸移動到[3],移動完畢後,主角origin上場,替身anime下場。
總結一下:當origin須要移動時,召喚替身anime到指定位置,替身移動,最後替身消失,origin在替身消失的地方出現。替身移動其實就是插值思想。
另外,爲防止動畫沒有播放完程序仍接受遊戲指令致使邏輯亂套,所以在動畫播放期間用戶輸入無效,否則動畫就會出問題。
======我是分割線======
通過堅持不懈的努力,第一個遊戲已經制做完成。
遊戲邏輯所有用Lua實現,發揮Lua的特長。
前期的辛苦,到第一個遊戲完成時,已經煙消雲散了,想必製做遊戲的人們都是這個心情吧。
2048這個遊戲很經典,當前它的遊戲算法我是抄的:),由於沒足夠時間去思考,可是它的算法難度不算過高,我以爲沒有Popstar implementation(MFC)難寫(固然Popstar我也寫過纔敢這麼說)。
不過,因爲遊戲框架功能有限,2048中的動態滑動效果還沒有實現,下降了美觀度。
那麼搭建這個遊戲的框架所具有的最小功能有哪些呢?
從上面能夠看出:Lua將交互層與渲染層相解耦,是十分重要的膠水語言。
這樣作的好處有哪些?
初次使用Lua就體會到它強大之處,在乎料之中。
總結一下編寫簡單的遊戲框架並用其實現2048整個過程當中的問題。
那麼總體的思路是: