android小游戲之2048課程設(shè)計(jì)_第1頁(yè)
android小游戲之2048課程設(shè)計(jì)_第2頁(yè)
android小游戲之2048課程設(shè)計(jì)_第3頁(yè)
android小游戲之2048課程設(shè)計(jì)_第4頁(yè)
android小游戲之2048課程設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、廣東行政職業(yè)學(xué)院學(xué)生畢業(yè)論文(設(shè)計(jì))android小游戲之2048課程設(shè)計(jì)學(xué)生姓名:鐘家喻學(xué)號(hào):12jw01b012系部:電子信息系專業(yè):計(jì)算機(jī)技術(shù)(網(wǎng)絡(luò)管理)班級(jí):2012級(jí)1班指導(dǎo)教師:黃耿生 副教授目錄前言- 3 - 內(nèi)容安排- 4 - 一、功能設(shè)計(jì)- 4 - (1)設(shè)計(jì)界面- 4 - (2)游戲設(shè)計(jì)- 5 - (3)事件監(jiān)聽(tīng)- 7 - (4)游戲最終實(shí)現(xiàn)- 8 - 二、游戲邏輯重新設(shè)定- 9 - 三、結(jié)束語(yǔ)- 18- 參考文獻(xiàn)- 18- android小游戲之2048課程設(shè)計(jì) 前言近期,新出的一款叫做2048的安卓游戲十分的火爆,幾乎游戲下載排行榜前十名都能看到它的身影。然而并不是每一

2、個(gè)人都知道一件事,那就是一個(gè)關(guān)于2048誕生的故事。故事的發(fā)展是這樣的,2048的祖先是一款名為threes(中文名為小3傳奇)的手游。小3傳奇的兩位開(kāi)發(fā)者花了近一年半的時(shí)間才開(kāi)發(fā)出這個(gè)游戲的核心玩法,卻在其上架app store后僅21天就被1024抄了過(guò)去。最讓人意想不到的事,2048則更為迅速,19歲的gabriele cirulli只用了一個(gè)星期改編前兩者游戲,卻獲得最大的成功,threes卻不被人所知。而到了現(xiàn)在,這類游戲從發(fā)布到現(xiàn)在,不光是app dtore還是android市場(chǎng),下載量已經(jīng)遠(yuǎn)遠(yuǎn)超越了千萬(wàn),晚上各種版本的都有,比如朝代版,后宮版,甲乙丙版,生肖版等。由于本人十分喜歡

3、2048這款手游,在了解本次課程設(shè)計(jì)是設(shè)計(jì)一個(gè)android平臺(tái)下的軟件之后,就選定了2048游戲作為本次課程論文的課題。在此次課程論文的制作過(guò)程中,我將運(yùn)用我在學(xué)校學(xué)習(xí)到的各種知識(shí)以及java編程知識(shí)和通過(guò)網(wǎng)上現(xiàn)有的資料嘗試完成本次課程的開(kāi)發(fā)。2048游戲可以通過(guò)簡(jiǎn)單的操作,豐富多彩的畫(huà)面來(lái)使人們達(dá)到放松的效果,人們只需要幾分鐘的時(shí)間就可以達(dá)到放松的效果。由于2048游戲的開(kāi)發(fā)要求并不高,所以不需要購(gòu)買(mǎi)特定的設(shè)施,只需要安裝特定的編程和圖像處理軟件來(lái)實(shí)現(xiàn)2048的開(kāi)發(fā)。內(nèi)容安排要開(kāi)發(fā)這一款游戲,要根據(jù)以下幾步來(lái)完成:首先是要對(duì)這款游戲的代碼分析。對(duì)整一個(gè)游戲,要將各個(gè)部位分割成其對(duì)應(yīng)部位的功

4、能代碼,并且逐一去分析實(shí)現(xiàn)其中不同的功能。其次是游戲的流程。在做好每一個(gè)部分的代碼之后,就需要把所創(chuàng)造的各個(gè)關(guān)鍵部分拼接起來(lái),因此,就需要先把該游戲的流程一步一步的弄清楚。再者是對(duì)2048這一款游戲的算法分析。對(duì)于整個(gè)游戲而言,最主要的心臟就是這一款游戲的算法,游戲好不好,就看這一款游戲的算法是不是符合邏輯。2048這一款游戲的算法分為上下左右自個(gè)方向的,具體的下面分析。2048中每個(gè)格子的數(shù)據(jù)和顏色的刷新。在每一次移動(dòng)之后,幾乎在這4*4的每一個(gè)方格上的數(shù)據(jù)都會(huì)變化,因此在每一次移動(dòng)之后,每一個(gè)方格上的數(shù)據(jù)都要刷新一次。相對(duì)的,每一個(gè)數(shù)的背景顏色是不同的,也就是說(shuō),在每一次數(shù)據(jù)刷新的時(shí)候,每

5、一個(gè)方格上的顏色也要同樣的刷新一次。最后是可不可以繼續(xù)游戲的檢測(cè)。當(dāng)屏幕上沒(méi)有沒(méi)有寫(xiě)有數(shù)據(jù)的方格并且屏幕上的數(shù)據(jù)沒(méi)有哪兩個(gè)相鄰的數(shù)據(jù)是一樣的兩個(gè)數(shù),那么就判定為游戲結(jié)束。功能設(shè)計(jì)1、設(shè)計(jì)界面 在設(shè)計(jì)整個(gè)2048游戲之前先得設(shè)計(jì)一個(gè)2048的游戲界面,只有有了游戲界面,才能夠進(jìn)行2048這一款游戲的下一步設(shè)計(jì),這是創(chuàng)建2048小游戲的最基礎(chǔ)的步驟。2048這一款游戲的界面是4*4方格的,于是就需要在界面上設(shè)置4*4的方格,有了這些方格之后才能在方格上面裝卡片(card),然后才能繼續(xù)游戲。private void ondrawborder(canvas canvas) paint.setshad

6、er(null);paint.setstrokewidth(16);paint.setcolor(color.white);canvas.drawline(0, 0, 0, this.getheight(), paint);canvas.drawline(0, 0, this.getwidth(), 0, paint);canvas.drawline(this.getwidth(), 0, this.getwidth(), this.getheight(), paint);canvas.drawline(0, this.getheight(), this.getwidth(), this.ge

7、theight(), paint);方格下面繼而顯示分?jǐn)?shù)(score)和最高分?jǐn)?shù)(bestscore)。2、游戲設(shè)計(jì)在2048游戲的界面設(shè)計(jì)好了之后,要求完成最核心的玩法就是卡片在于界面上4*4的移動(dòng),于是下一步的操作就是對(duì)卡片的具體設(shè)置,以下是一部分關(guān)鍵代碼。 (1)創(chuàng)建一個(gè)卡片private card getcard(int num) card c; if (cards.size()0) c = cards.remove(0); else c = new card(getcontext(); addview(c); c.setvisibility(view.visible); c.setn

8、um(num); return c; (2) 類card繼承了framelayout,目的是作為游戲中的卡片,卡片各個(gè)數(shù)字和樣式的實(shí)現(xiàn):public void setnum(int num) this.num = num; if (num=0) label.settext(); else label.settext(num+); switch (num) case 0: label.setbackgroundcolor(0x00000000);/透明色 break; case 2: default: label.setbackgroundcolor(0xff3c3a32); break; (3

9、) 卡片設(shè)計(jì)好了之后根據(jù)游戲要求判斷在某一操作下同一方向上的卡片是否可以相加,可以相加的部分進(jìn)行數(shù)據(jù)合并。/合并相同數(shù)據(jù)int addscode = 0;for(int p=0;p0;q-)if(arraysqp=arraysq-1p&arraysqp!=0) flag_move = true; rraysqp+=arraysq-1p; addscode+=arraysqp; arraysq-1p=0; q-; 3、事件監(jiān)聽(tīng)對(duì)于2048這個(gè)游戲經(jīng)過(guò)之前對(duì)游戲界面的設(shè)計(jì)、對(duì)游戲元素卡片的創(chuàng)建和定義好了之后,最終目的是要使我們能夠控制卡片進(jìn)行移動(dòng),目標(biāo)是使卡片能夠根據(jù)我們的命令進(jìn)行向上、向下、向左

10、、向右的四個(gè)方向上的移動(dòng),這個(gè)需要加上4個(gè)方位的事件監(jiān)聽(tīng)。overridepublic boolean onfling(motionevent e1, motionevent e2, float velocityx,float velocityy) float x=e2.getx()-e1.getx();float y=e2.gety()-e1.gety();final int fling_min_distance =50;if(xfling_min_distance&math.abs(velocityx)math.abs(velocityy)toright();else if(xmath.a

11、bs(velocityy)toleft();else if(yfling_min_distance&math.abs(velocityx)math.abs(velocityy)todown();else if(y-fling_min_distance&math.abs(velocityx)math.abs(velocityy)toup();return false; 以上是事件監(jiān)聽(tīng)的部分關(guān)鍵代碼,事件監(jiān)聽(tīng)創(chuàng)建好了之后,整個(gè)游戲大部分要求已經(jīng)完成了。4、游戲最終實(shí)現(xiàn)從游戲的角度來(lái)說(shuō),這個(gè)2048游戲有界面,有元素,可以移動(dòng)已經(jīng)基本完成了,但作為有個(gè)游戲而言最后還有幾步?jīng)]有完善。初始化進(jìn)入游戲,初

12、始化4*4表格,并隨機(jī)產(chǎn)生兩個(gè)數(shù)字(2或者4);二維數(shù)組this.tables表格循環(huán)存入數(shù)據(jù);random1, random2 ,random11, random22四個(gè)隨機(jī)數(shù)可以確定兩個(gè)2的xy位置;方法newnumber里面,根據(jù)位置i,j和級(jí)別num可以確定一個(gè)新的數(shù)字;創(chuàng)建背景cell和cell上面的數(shù)字標(biāo)簽celllabel;并根據(jù)num確定是否顯示celllabel;最后給cell關(guān)聯(lián)一個(gè)data數(shù)據(jù);特別說(shuō)明這里的number:num不是精靈上面的數(shù)字而是精靈的級(jí)別,比如number=11 則數(shù)字是1024。游戲結(jié)束的判斷每次發(fā)生卡片移動(dòng),都要檢查游戲還能否繼續(xù),是否已經(jīng)結(jié)束。

13、使用函數(shù)checkcomplete()完成游戲是否失敗的檢查。游戲的計(jì)分在卡片的每一次移動(dòng)的時(shí)候判斷是否有兩個(gè)相同數(shù)字進(jìn)行相加,凡是有相見(jiàn)的兩個(gè)數(shù)字其相加所得的和需要存入計(jì)分中,其中如果游戲獲得了最高分要對(duì)最高分進(jìn)行保存。public class bestscore private sharedpreferences sp;public bestscore(context context)sp = context.getsharedpreferences(bestscore, context.mode_private);public int getbestscore()int bestscor

14、e = sp.getint(bestscore, 0);return bestscore;public void setbestscore(int bestscore)editor editor = sp.edit();editor.putint(bestscore, bestscore);mit();游戲邏輯重新設(shè)定 用不同方法制作嘗試可能性。首先看一下,我在實(shí)現(xiàn)2048時(shí)用到的一些存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)。我在實(shí)現(xiàn)時(shí),為了省事存儲(chǔ)游戲過(guò)程中的變量主要用到的是list。比如說(shuō):listspacelist = new arraylist();這個(gè)spacelist主要作用于保存,所有

15、空白格的位置,也就是空白格在gridlayout中的位置(從0到15)對(duì)于數(shù)字格,以及格子對(duì)應(yīng)的數(shù)據(jù),我寫(xiě)了一個(gè)類如下:package com.example.t2048;import java.util.arraylist;import java.util.list;import android.util.log;/* * 用于保存數(shù)字格,已經(jīng)數(shù)字格對(duì)應(yīng)的數(shù)字 * author mr.wang * */public class numberlist /這個(gè)list用于保存所有不為空的格子的坐標(biāo)(在gridlayout中的位置從0到15)private list stufflist = new

16、 arraylist();/這個(gè)list用于保存所有不為空的格子對(duì)應(yīng)的數(shù)字(以2為底數(shù)的指數(shù))private list numberlist = new arraylist();/* * 新加入的數(shù)字格 * param index 數(shù)字格對(duì)應(yīng)的位置 * param number 對(duì)應(yīng)數(shù)字的指數(shù)(以2為底數(shù)) */public void add(int index, int number)stufflist.add(index);numberlist.add(number);/* * 用于判斷當(dāng)前位置是否為數(shù)字格 * param index 當(dāng)前位置 * return true表示是 */pub

17、lic boolean contains(int index)return stufflist.contains(index);/* * 將當(dāng)前的格子從數(shù)字列表中去掉 * param index */public void remove(int index)int order = stufflist.indexof(index);numberlist.remove(order);stufflist.remove(order);/* * 將當(dāng)前格子對(duì)應(yīng)的數(shù)字升級(jí),指數(shù)加1 * param index */public void levelup(int index)int order = stuf

18、flist.indexof(index);numberlist.set(order, numberlist.get(order)+1);/* * 將當(dāng)前格子對(duì)應(yīng)的位置置換為新的位置 * param index 當(dāng)前位置 * param newindex 新的位置 */public void changeindex(int index, int newindex)stufflist.set(stufflist.indexof(index), newindex);/* * 通過(guò)格子對(duì)應(yīng)的位置獲取其對(duì)應(yīng)的數(shù)字 * param index 當(dāng)前位置 * return 格子對(duì)應(yīng)數(shù)字的指數(shù) */publi

19、c int getnumberbyindex(int index)int order = stufflist.indexof(index);return numberlist.get(order) ;public string tostring()return stufflist.tostring()+numberlist.tostring();public void printlog()log.i(stufflist, stufflist.tostring();log.i(numberlist, numberlist.tostring();這個(gè)類主要是我對(duì)數(shù)字格、數(shù)字格對(duì)應(yīng)數(shù)字的保存,和增刪

20、改等操作。其實(shí)就是兩個(gè)list,我為了操作起來(lái)方便,所以把他們寫(xiě)在一個(gè)類里。然后,游戲的邏輯。比如,我們?cè)谟螒蜻^(guò)程中執(zhí)行了一次向右滑動(dòng)的操作,這個(gè)操作中,我們要對(duì)所有可移動(dòng)和合并的格子進(jìn)行半段和相應(yīng)的操作:數(shù)字格的右邊如果是空白格,則數(shù)字格與空白格交換數(shù)字格右邊如果有多個(gè)空白格,則數(shù)字格與連續(xù)的最后一個(gè)空白格做交換數(shù)字格的右邊如果存在與之相同的數(shù)字格,則本格置空,右邊的數(shù)字格升級(jí)(指數(shù)加一)如果滑動(dòng)方向連續(xù)存在多個(gè)相同的數(shù)字格,右的格子優(yōu)先升級(jí)在一次滑動(dòng)中,每個(gè)格子最多升級(jí)一次當(dāng)一個(gè)格子存在上述四種中的任意一種時(shí),則完成了對(duì)它的操作。我們?cè)囍焉厦娴呐袛嘁?guī)則翻譯成代碼,首先,明確在gridla

21、yout中的坐標(biāo)位置,我在gridlayout中采用的是水平布局,所以每個(gè)格子對(duì)應(yīng)的位置如下0 1 2 34 5 6 78 9 10 1112 13 14 15在這個(gè)基礎(chǔ)上,我建立如下坐標(biāo)軸,以左上角為原點(diǎn),x軸為橫軸,y軸為豎軸。當(dāng)向右滑動(dòng)的時(shí)候,從上面邏輯來(lái)看,為了方便我們應(yīng)當(dāng)從右向左歷格子:for(int y=0;y=0;x-)int thisidx = 4*y +x;change(thisidx,direction);每遍歷到一個(gè)新的格子,執(zhí)行一次change()方法,其實(shí)應(yīng)該是沒(méi)遍歷到一個(gè)非空的格子,執(zhí)行一次change()當(dāng)時(shí)我為了省事,把非空判斷加到了change的代碼里,來(lái)看一

22、下change()這個(gè)方法的實(shí)現(xiàn),這個(gè)方法主要是用來(lái)判斷,一個(gè)格子是需要移動(dòng)、合并,還是什么都不操作:/* * 該方法,為每個(gè)符合條件的格子執(zhí)行變動(dòng)的操作,如置換,升級(jí)等 * param thisidx 當(dāng)前格子的坐標(biāo) * param direction 滑動(dòng)方向 */public void change(int thisidx,int direction)if(numberlist.contains(thisidx)int nextidx = getlast(thisidx, direction);if(nextidx = thisidx)/不能移動(dòng)return;else if(spacel

23、ist.contains(nextidx)/存在可以置換的空白格replace(thisidx,nextidx);elseif(numberlist.getnumberbyindex(thisidx)=numberlist.getnumberbyindex(nextidx)/可以合并levelup(thisidx, nextidx);elseint before = getbefore(nextidx, direction);if(before != thisidx)/存在可以置換的空白格replace(thisidx,before);其中g(shù)etlast()方法,用于獲取當(dāng)前格子在移動(dòng)方向的可

24、以移動(dòng)或者合并的最后一個(gè)格子,如果返回值還是當(dāng)前的格子,則表示不能移動(dòng)。其中調(diào)用的getnext()方法是為了獲取當(dāng)前格子在移動(dòng)方向的下個(gè)格子的位置。/* * 用于獲取移動(dòng)方向上最后一個(gè)空白格之后的位置 * param index 當(dāng)前格子的坐標(biāo) * param direction 移動(dòng)方向 * return */public int getlast(int thisidx, int direction) int nextidx = getnext(thisidx, direction); if(nextidx 0) return thisidx; else if(spacelist.cont

25、ains(nextidx) return getlast(nextidx, direction); else return nextidx; 然后是replace(int thisdx,int nextldx),這個(gè)方法是執(zhí)行兩個(gè)格子互換位置,內(nèi)容主要是對(duì)格子中的view更換背景圖片,然后操作空白格的list和數(shù)字格的list:/* * 該方法用來(lái)交換當(dāng)前格與目標(biāo)空白格的位置 * param thisidx 當(dāng)前格子的坐標(biāo) * param nextidx 目標(biāo)空白格的坐標(biāo) */public void replace(int thisidx, int nextidx)moved = true;/

26、獲取當(dāng)前格子的view,并將其置成空白格view thisview = gridlayout.getchildat(thisidx);imageview image = (imageview) thisview.findviewbyid(r.id.image);image.setbackgroundresource(icons0);/獲取空白格的view,并將其背景置成當(dāng)前格的背景view nextview = gridlayout.getchildat(nextidx);imageview nextimage = (imageview) nextview.findviewbyid(r.id.

27、image);nextimage.setbackgroundresource(iconsnumberlist.getnumberbyindex(thisidx);/在空白格列表中,去掉目標(biāo)格,加上當(dāng)前格spacelist.remove(spacelist.indexof(nextidx);spacelist.add(thisidx);/在數(shù)字格列表中,當(dāng)前格的坐標(biāo)置換成目標(biāo)格的坐標(biāo)numberlist.changeindex(thisidx, nextidx);levelup(int thisldx,int nextldx)這個(gè)方法是為了實(shí)現(xiàn)相同數(shù)字格的合并操作,其實(shí)就是將當(dāng)前的格子置成空白格

28、,將移動(dòng)方向上下一個(gè)格子對(duì)應(yīng)的背景置成下一個(gè)背景:/* * 剛方法用于合并在移動(dòng)方向上兩個(gè)相同的格子 * param thisidx 當(dāng)前格子的坐標(biāo) * param nextidx 目標(biāo)格子的坐標(biāo) */public void levelup(int thisidx, int nextidx)/一次移動(dòng)中,每個(gè)格子最多只能升級(jí)一次if(!changelist.contains(nextidx)moved = true;/獲取當(dāng)前格子的view,并將其置成空白格view thisview = gridlayout.getchildat(thisidx);imageview image = (ima

29、geview) thisview.findviewbyid(r.id.image);image.setbackgroundresource(icons0);/獲取目標(biāo)格的view,并將其背景置成當(dāng)前格升級(jí)后的背景view nextview = gridlayout.getchildat(nextidx);imageview nextimage = (imageview) nextview.findviewbyid(r.id.image);nextimage.setbackgroundresource(iconsnumberlist.getnumberbyindex(nextidx)+1);/在空白格列表中加入當(dāng)前格spacelist.add(thisidx);/在數(shù)字列中刪掉第一個(gè)格子numberli

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論