手把手教你做一个2048 上
目錄
?
0 簡介
1 什么是2048
0 簡介
閑來無事,搞了個2048玩玩,源碼放到了github上了,先上鏈接?https://github.com/tzx666/Android2048
現(xiàn)在已經(jīng)實現(xiàn)的功能有
經(jīng)典模式
自定義模式
歷史查看、游玩、刪除自己自定義的模式
還沒有實現(xiàn)的功能有
游戲的動畫、聲音
后臺功能、創(chuàng)意上傳、圖片合并等
效果圖
?
1 什么是2048
2048是一種游戲,核心玩法是通過左滑右滑上滑下滑去合并相同的數(shù)字,如果到達(dá)了2048則判定為勝利,如果已經(jīng)無法再滑動了則可以判斷失敗
那么我們便可以構(gòu)思出這個游戲必然有以下功能
1 基礎(chǔ)背景,一個4*4的游戲棋盤,這里我們使用一維數(shù)組作為底層實現(xiàn)
2 滑動的合并與判斷
3 隨機(jī)位置的生成
4 游戲勝利和結(jié)束條件的判斷
5 引申而來的,我們同樣可以對游戲使用mvc架構(gòu),即游戲顯示什么和實際邏輯是什么并無關(guān)系,只要定義符合合并機(jī)制,那么無論顯示什么都是合理的(霧)
2 抽象類的定義
根據(jù)上述的描述,我們不難定義出接口(其實應(yīng)該用抽象類更合理的說)
interface Game2048 {fun init(context:Context);fun init(context:Context,size:Int);fun start();fun moveleft();fun moveright();fun moveup();fun movedown();fun addRanrom();fun isEnd();fun isFirstVisiable(position:Int):Boolean; }其中 init()負(fù)責(zé)初始化數(shù)組,isFirstVisiable()負(fù)責(zé)動畫出現(xiàn)的判斷,movexx函數(shù)負(fù)責(zé)游戲過程中的合并
3 游戲邏輯的實現(xiàn)
2048的游戲邏輯比較簡單,參考代碼應(yīng)該很好懂
/* *@author tzx *@descrption 2048的邏輯實現(xiàn) */ public class Game2048impl implements Game2048 {private int score;private int[] map;private boolean[] isfirstAppear;private int MAPSIZE;private int GAME_OVER=101;private int GAME_WIN=102;private int GAME_CONTINUE=103;private int state=GAME_CONTINUE;private Context context;@Overridepublic void init(Context context,int size) {MAPSIZE=size;this.context=context;map=new int[MAPSIZE*MAPSIZE];isfirstAppear=new boolean[MAPSIZE*MAPSIZE];addRanrom();addRanrom();}@Overridepublic boolean isFirstVisiable(int positon) {return isfirstAppear[positon];}private enum state{GAME_OVER,GAME_CONTINUE,GAME_WIN};@Overridepublic void init(Context context) {this.context=context;MAPSIZE=4;map=new int[MAPSIZE*MAPSIZE];isfirstAppear=new boolean[MAPSIZE*MAPSIZE];addRanrom();addRanrom();}@Overridepublic void start() {}public int[] getMap() {return map;}@Overridepublic void moveleft() {boolean merge=false;for(int i=0;i<4;i++){for(int j=0;j<4;j++){for(int z=j+1;z<4;z++){if(map[i*MAPSIZE+z]>0){if(map[i*MAPSIZE+j]==0){map[i*MAPSIZE+j]=map[i*MAPSIZE+z];map[i*MAPSIZE+z]=0;j--;merge=true;}else if(map[i*MAPSIZE+j]==map[i*MAPSIZE+z]){map[i*MAPSIZE+j]*=2;score+=map[i*MAPSIZE+j];map[i*MAPSIZE+z]=0;merge=true;}break;}}}}if(merge){for(int i=0;i<isfirstAppear.length;i++)isfirstAppear[i]=false;addRanrom();isEnd();}}@Overridepublic void moveright() {boolean merge=false;for(int i=0;i<4;i++){for(int j=3;j>0;j--){for(int z=j-1;z>=0;z--){if(map[i*MAPSIZE+z]>0){if(map[i*MAPSIZE+j]==0){map[i*MAPSIZE+j]=map[i*MAPSIZE+z];map[i*MAPSIZE+z]=0;j++;merge=true;}else if(map[i*MAPSIZE+j]==map[i*MAPSIZE+z]){map[i*MAPSIZE+j]*=2;map[i*MAPSIZE+z]=0;score+=map[i*MAPSIZE+j];merge=true;}break;}}}}if(merge){for(int i=0;i<isfirstAppear.length;i++)isfirstAppear[i]=false;addRanrom();isEnd();}}@Overridepublic void moveup() {boolean merge=false;for(int j=0;j<4;j++){for(int i=0;i<4;i++){for(int z=i+1;z<4;z++){if(map[z*MAPSIZE+j]>0){if(map[i*MAPSIZE+j]==0){map[i*MAPSIZE+j]=map[z*MAPSIZE+j];map[z*MAPSIZE+j]=0;i--;merge=true;}else if(map[i*MAPSIZE+j]==map[z*MAPSIZE+j]){map[i*MAPSIZE+j]*=2;score+=map[i*MAPSIZE+j];map[z*MAPSIZE+j]=0;merge=true;}break;}}}}if(merge){for(int i=0;i<isfirstAppear.length;i++)isfirstAppear[i]=false;addRanrom();isEnd();}}@Overridepublic void movedown() {boolean merge=false;for(int j=0;j<4;j++){for(int i=3;i>0;i--){for(int z=i-1;z>=0;z--){if(map[z*MAPSIZE+j]>0){if(map[i*MAPSIZE+j]==0){map[i*MAPSIZE+j]=map[z*MAPSIZE+j];map[z*MAPSIZE+j]=0;i++;merge=true;}else if(map[i*MAPSIZE+j]==map[z*MAPSIZE+j]){map[i*MAPSIZE+j]*=2;score+=map[i*MAPSIZE+j];map[z*MAPSIZE+j]=0;merge=true;}break;}}}}if(merge){for(int i=0;i<isfirstAppear.length;i++)isfirstAppear[i]=false;addRanrom();isEnd();}}@Overridepublic void addRanrom() {Random rand=new Random();int x=rand.nextInt(4);int y=rand.nextInt(4);do{x=rand.nextInt(4);y=rand.nextInt(4);}while(map[x*MAPSIZE+y]!=0);isfirstAppear[x*MAPSIZE+y]=true;map[x*MAPSIZE+y]=Math.random()>0.1?2:4;}@Overridepublic void isEnd() {int state=this.GAME_OVER;for(int i=0;i<4;i++){for(int j=0;j<4;j++){if(map[i*MAPSIZE+j]==2048){state=GAME_WIN;return;}else if(map[i*MAPSIZE+j]==0||(i>0&&map[i*MAPSIZE+j]==map[(i-1)*MAPSIZE+j])||(i<3&&map[i*MAPSIZE+j]==map[(i+1)*MAPSIZE+j])||(j>0&&map[i*MAPSIZE+j]==map[i*MAPSIZE+(j-1)])||(j<3&&map[i*MAPSIZE+j]==map[i*MAPSIZE+(j+1)])){state=this.GAME_CONTINUE;return;}}}if(state==GAME_OVER){UtilsKt.showDialog(context, "游戲結(jié)束", "", new Callback() {@Overridepublic void onConfirm(@NotNull DialogInterface dialog) {((Activity)context).finish();}@Overridepublic void onCancel(@NotNull DialogInterface dialog) {}});}else if(state==GAME_WIN){UtilsKt.showDialog(context, "游戲勝利", "", new Callback() {@Overridepublic void onConfirm(@NotNull DialogInterface dialog) {((Activity)context).finish();}@Overridepublic void onCancel(@NotNull DialogInterface dialog) {}});}}public int getScore() {return score;}public void setScore(int score) {this.score = score;}void Gesture(int c){if(c==1) moveleft(); //getKeyCode()是表示按鍵按下的序號,KeyEvent.VK_UP表示up(下)鍵的序號if(c==2) moveright();if(c==3) moveup();if(c==4) movedown();} }事實上,上面的類完全可以通過scanner以控制臺的形式跑起來
上篇總結(jié)
在本篇,我們主要關(guān)注游戲的邏輯實現(xiàn),但是么有界面的游戲一定是假游戲,下一篇將結(jié)合用到的安卓開發(fā)知識介紹如何優(yōu)雅的畫界面(霧)
?
總結(jié)
以上是生活随笔為你收集整理的手把手教你做一个2048 上的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 陕西网络培训学院自动学习简易脚本
 - 下一篇: 网页版2048