android小游戏之2048课程设计.doc

上传人:仙人指路1688 文档编号:2393563 上传时间:2023-02-17 格式:DOC 页数:18 大小:56.50KB
返回 下载 相关 举报
android小游戏之2048课程设计.doc_第1页
第1页 / 共18页
android小游戏之2048课程设计.doc_第2页
第2页 / 共18页
android小游戏之2048课程设计.doc_第3页
第3页 / 共18页
android小游戏之2048课程设计.doc_第4页
第4页 / 共18页
android小游戏之2048课程设计.doc_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《android小游戏之2048课程设计.doc》由会员分享,可在线阅读,更多相关《android小游戏之2048课程设计.doc(18页珍藏版)》请在三一办公上搜索。

1、广东行政职业学院学生毕业论文(设计)Android小游戏之2048课程设计学生姓名:钟家喻学号:12JW01B012系部:电子信息系专业:计算机技术(网络管理)班级:2012级1班指导教师:黄耿生 副教授目录前言- 3 - 内容安排- 4 - 一、功能设计- 4 - (1)设计界面- 4 - (2)游戏设计- 5 - (3)事件监听- 7 - (4)游戏最终实现- 8 - 二、游戏逻辑重新设定- 9 - 三、结束语- 18- 参考文献- 18- Android小游戏之2048课程设计 前言近期,新出的一款叫做2048的安卓游戏十分的火爆,几乎游戏下载排行榜前十名都能看到它的身影。然而并不是每一

2、个人都知道一件事,那就是一个关于2048诞生的故事。故事的发展是这样的,2048的祖先是一款名为Threes(中文名为小3传奇)的手游。小3传奇的两位开发者花了近一年半的时间才开发出这个游戏的核心玩法,却在其上架App store后仅21天就被1024抄了过去。最让人意想不到的事,2048则更为迅速,19岁的Gabriele Cirulli只用了一个星期改编前两者游戏,却获得最大的成功,Threes却不被人所知。而到了现在,这类游戏从发布到现在,不光是App Dtore还是Android市场,下载量已经远远超越了千万,晚上各种版本的都有,比如朝代版,后宫版,甲乙丙版,生肖版等。由于本人十分喜欢

3、2048这款手游,在了解本次课程设计是设计一个Android平台下的软件之后,就选定了2048游戏作为本次课程论文的课题。在此次课程论文的制作过程中,我将运用我在学校学习到的各种知识以及java编程知识和通过网上现有的资料尝试完成本次课程的开发。2048游戏可以通过简单的操作,丰富多彩的画面来使人们达到放松的效果,人们只需要几分钟的时间就可以达到放松的效果。由于2048游戏的开发要求并不高,所以不需要购买特定的设施,只需要安装特定的编程和图像处理软件来实现2048的开发。内容安排要开发这一款游戏,要根据以下几步来完成:首先是要对这款游戏的代码分析。对整一个游戏,要将各个部位分割成其对应部位的功

4、能代码,并且逐一去分析实现其中不同的功能。其次是游戏的流程。在做好每一个部分的代码之后,就需要把所创造的各个关键部分拼接起来,因此,就需要先把该游戏的流程一步一步的弄清楚。再者是对2048这一款游戏的算法分析。对于整个游戏而言,最主要的心脏就是这一款游戏的算法,游戏好不好,就看这一款游戏的算法是不是符合逻辑。2048这一款游戏的算法分为上下左右自个方向的,具体的下面分析。2048中每个格子的数据和颜色的刷新。在每一次移动之后,几乎在这4*4的每一个方格上的数据都会变化,因此在每一次移动之后,每一个方格上的数据都要刷新一次。相对的,每一个数的背景颜色是不同的,也就是说,在每一次数据刷新的时候,每

5、一个方格上的颜色也要同样的刷新一次。最后是可不可以继续游戏的检测。当屏幕上没有没有写有数据的方格并且屏幕上的数据没有哪两个相邻的数据是一样的两个数,那么就判定为游戏结束。功能设计1、设计界面 在设计整个2048游戏之前先得设计一个2048的游戏界面,只有有了游戏界面,才能够进行2048这一款游戏的下一步设计,这是创建2048小游戏的最基础的步骤。2048这一款游戏的界面是4*4方格的,于是就需要在界面上设置4*4的方格,有了这些方格之后才能在方格上面装卡片(Card),然后才能继续游戏。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);方格下面继而显示分数(Score)和最高分数(BestScore)。2、游戏设计在2048游戏的界面设计好了之后,要求完成最核心的玩法就是卡片在于界面上4*4的移动,于是下一步的操作就是对卡片的具体设置,以下是一部分关键代码。 (1)创建一个卡片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,目的是作为游戏中的卡片,卡片各个数字和样式的实现: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、) 卡片设计好了之后根据游戏要求判断在某一操作下同一方向上的卡片是否可以相加,可以相加的部分进行数据合并。/合并相同数据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、事件监听对于2048这个游戏经过之前对游戏界面的设计、对游戏元素卡片的创建和定义好了之后,最终目的是要使我们能够控制卡片进行移动,目标是使卡片能够根据我们的命令进行向上、向下、向左

10、、向右的四个方向上的移动,这个需要加上4个方位的事件监听。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; 以上是事件监听的部分关键代码,事件监听创建好了之后,整个游戏大部分要求已经完成了。4、游戏最终实现从游戏的角度来说,这个2048游戏有界面,有元素,可以移动已经基本完成了,但作为有个游戏而言最后还有几步没有完善。初始化进入游戏,初

12、始化4*4表格,并随机产生两个数字(2或者4);二维数组this.tables表格循环存入数据;random1, random2 ,random11, random22四个随机数可以确定两个2的xy位置;方法newNumber里面,根据位置i,j和级别num可以确定一个新的数字;创建背景cell和cell上面的数字标签cellLabel;并根据num确定是否显示cellLabel;最后给cell关联一个data数据;特别说明这里的number:num不是精灵上面的数字而是精灵的级别,比如number=11 则数字是1024。游戏结束的判断每次发生卡片移动,都要检查游戏还能否继续,是否已经结束。

13、使用函数CheckComplete()完成游戏是否失败的检查。游戏的计分在卡片的每一次移动的时候判断是否有两个相同数字进行相加,凡是有相见的两个数字其相加所得的和需要存入计分中,其中如果游戏获得了最高分要对最高分进行保存。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();游戏逻辑重新设定 用不同方法制作尝试可能性。首先看一下,我在实现2048时用到的一些存储的数据结构。我在实现时,为了省事存储游戏过程中的变量主要用到的是List。比如说:ListspaceList = new ArrayList();这个spaceList主要作用于保存,所有空白格的位置,也就是

15、空白格在GridLayout中的位置(从0到15)对于数字格,以及格子对应的数据,我写了一个类如下:package com.example.t2048;import java.util.ArrayList;import java.util.List;import android.util.Log;/* * 用于保存数字格,已经数字格对应的数字 * author Mr.Wang * */public class NumberList /这个list用于保存所有不为空的格子的坐标(在GridLayout中的位置从0到15)private List stuffList = new ArrayList

16、();/这个list用于保存所有不为空的格子对应的数字(以2为底数的指数)private List numberList = new ArrayList();/* * 新加入的数字格 * param index 数字格对应的位置 * param number 对应数字的指数(以2为底数) */public void add(int index, int number)stuffList.add(index);numberList.add(number);/* * 用于判断当前位置是否为数字格 * param index 当前位置 * return true表示是 */public boolea

17、n contains(int index)return stuffList.contains(index);/* * 将当前的格子从数字列表中去掉 * param index */public void remove(int index)int order = stuffList.indexOf(index);numberList.remove(order);stuffList.remove(order);/* * 将当前格子对应的数字升级,指数加1 * param index */public void levelup(int index)int order = stuffList.inde

18、xOf(index);numberList.set(order, numberList.get(order)+1);/* * 将当前格子对应的位置置换为新的位置 * param index 当前位置 * param newIndex 新的位置 */public void changeIndex(int index, int newIndex)stuffList.set(stuffList.indexOf(index), newIndex);/* * 通过格子对应的位置获取其对应的数字 * param index 当前位置 * return 格子对应数字的指数 */public int getN

19、umberByIndex(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();这个类主要是我对数字格、数字格对应数字的保存,和增删改等操作。其实就是两

20、个list,我为了操作起来方便,所以把他们写在一个类里。然后,游戏的逻辑。比如,我们在游戏过程中执行了一次向右滑动的操作,这个操作中,我们要对所有可移动和合并的格子进行半段和相应的操作:数字格的右边如果是空白格,则数字格与空白格交换数字格右边如果有多个空白格,则数字格与连续的最后一个空白格做交换数字格的右边如果存在与之相同的数字格,则本格置空,右边的数字格升级(指数加一)如果滑动方向连续存在多个相同的数字格,右的格子优先升级在一次滑动中,每个格子最多升级一次当一个格子存在上述四种中的任意一种时,则完成了对它的操作。我们试着把上面的判断规则翻译成代码,首先,明确在GridLayout中的坐标位置

21、,我在GridLayout中采用的是水平布局,所以每个格子对应的位置如下0 1 2 34 5 6 78 9 10 1112 13 14 15在这个基础上,我建立如下坐标轴,以左上角为原点,X轴为横轴,Y轴为竖轴。当向右滑动的时候,从上面逻辑来看,为了方便我们应当从右向左历格子:for(int y=0;y=0;x-)int thisIdx = 4*y +x;Change(thisIdx,direction);每遍历到一个新的格子,执行一次change()方法,其实应该是没遍历到一个非空的格子,执行一次change()当时我为了省事,把非空判断加到了change的代码里,来看一下change()这

22、个方法的实现,这个方法主要是用来判断,一个格子是需要移动、合并,还是什么都不操作:/* * 该方法,为每个符合条件的格子执行变动的操作,如置换,升级等 * param thisIdx 当前格子的坐标 * param direction 滑动方向 */public void Change(int thisIdx,int direction)if(numberList.contains(thisIdx)int nextIdx = getLast(thisIdx, direction);if(nextIdx = thisIdx)/不能移动return;else if(spaceList.contai

23、ns(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);其中getLast()方法,用于获取当前格子在移动方向的可以移动或者合并的最后

24、一个格子,如果返回值还是当前的格子,则表示不能移动。其中调用的getNext()方法是为了获取当前格子在移动方向的下个格子的位置。/* * 用于获取移动方向上最后一个空白格之后的位置 * param index 当前格子的坐标 * param direction 移动方向 * return */public int getLast(int thisIdx, int direction) int nextIdx = getNext(thisIdx, direction); if(nextIdx 0) return thisIdx; else if(spaceList.contains(nextI

25、dx) return getLast(nextIdx, direction); else return nextIdx; 然后是replace(int thisdx,int nextldx),这个方法是执行两个格子互换位置,内容主要是对格子中的view更换背景图片,然后操作空白格的list和数字格的list:/* * 该方法用来交换当前格与目标空白格的位置 * param thisIdx 当前格子的坐标 * param nextIdx 目标空白格的坐标 */public void replace(int thisIdx, int nextIdx)moved = true;/获取当前格子的vie

26、w,并将其置成空白格View thisView = gridLayout.getChildAt(thisIdx);ImageView image = (ImageView) thisView.findViewById(R.id.image);image.setBackgroundResource(icons0);/获取空白格的view,并将其背景置成当前格的背景View nextView = gridLayout.getChildAt(nextIdx);ImageView nextImage = (ImageView) nextView.findViewById(R.id.image);nex

27、tImage.setBackgroundResource(iconsnumberList.getNumberByIndex(thisIdx);/在空白格列表中,去掉目标格,加上当前格spaceList.remove(spaceList.indexOf(nextIdx);spaceList.add(thisIdx);/在数字格列表中,当前格的坐标置换成目标格的坐标numberList.changeIndex(thisIdx, nextIdx);Levelup(int thisldx,int nextldx)这个方法是为了实现相同数字格的合并操作,其实就是将当前的格子置成空白格,将移动方向上下一个

28、格子对应的背景置成下一个背景:/* * 刚方法用于合并在移动方向上两个相同的格子 * param thisIdx 当前格子的坐标 * param nextIdx 目标格子的坐标 */public void levelup(int thisIdx, int nextIdx)/一次移动中,每个格子最多只能升级一次if(!changeList.contains(nextIdx)moved = true;/获取当前格子的view,并将其置成空白格View thisView = gridLayout.getChildAt(thisIdx);ImageView image = (ImageView) th

29、isView.findViewById(R.id.image);image.setBackgroundResource(icons0);/获取目标格的view,并将其背景置成当前格升级后的背景View nextView = gridLayout.getChildAt(nextIdx);ImageView nextImage = (ImageView) nextView.findViewById(R.id.image);nextImage.setBackgroundResource(iconsnumberList.getNumberByIndex(nextIdx)+1);/在空白格列表中加入当前

30、格spaceList.add(thisIdx);/在数字列中删掉第一个格子numberList.remove(thisIdx);/将数字列表对应的内容升级numberList.levelup(nextIdx);changeList.add(nextIdx);写完这些,基本完成了主要的判断,当时还有两个问题:1是如果每次滑动没有各自移动(合并),那么就不应该新随机生成格子;2每个格子只能合并一次。为了解决这两个问题,我又加了两个变量:/用于保存每次操作时,已经升级过的格子List changeList = new ArrayList();/用于表示本次滑动是否有格子移动过boolean move

31、d = false;其中changeList在每次滑动前清空,然后加入本次移动中发生过合并的格子,在每次合并的判断时首先看看要合并的格子是不是在这个list中,如果在的话,说明已经合并过,那么久不执行合并的操作了。还有个波尔型的moved变量,这个也是在每次滑动前置为false,如果在本次滑动中,有格子移动或者合并,就置为ture,在滑动的最后,通过这个变量判断是否要随机生产新的格子。结束语 写到这里,最为我学习Android以来,第一个自己写的比较好程序已经完成一半。逻辑判断这部分写的时候,还是费了一点时间,因为总有一些情况没有考虑进去,到现在基本上已经实现了。但是也反应出来一个很重要的问题,那就是自己在数据结构和算法方面还是很薄弱,整个读一下自己写的代码,为了完成对各种情况的判断,整个代码看起来十分冗余,而且效率之低就更不用说了。再看看别人写的代码,感觉自己在开放方面还是很长的路要走的。接下来的时间,我会利用工作之余的时间不断去完善这个程序,并尽可能的去优化。参考文献1 Android项目开发实-2048游戏2 Android游戏源码分享之20483 4 5 Android左右滑动切换背景

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号