版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
毕业设计(论文)原创性声明本人郑重声明:所提交的毕业设计(论文),是本人在导师指导下,独立进行研究工作所取得的成果。除文中已注明引用的内容外,本毕业设计(论文)不包含任何其他个人或集体已经发表或撰写过的作品成果。对本研究做出过重要贡献的个人和集体,均已在文中以明确方式标明并表示了谢意。论文作者签名:日期:年月日摘要随着手机行业发展蓬勃迅速,尤其是以Android系统为例,越来越多的手机搭载了Android智能系统,该系统是以Linux为基础的开放源代码操作系统,其开放性、不受运营商限制、丰富的硬件支持、良好的扩展性,受到了外界良好评价与使用支持。Android的系统架构分为三个部分:应用部分,核心部分,底层部分。除了上述划分方式以外,从系统实际的架构模型来看,Android则可以分成以下几个层次:①应用层②框架层③运行时④核心类库⑤硬件抽象层⑥Linux内核。本文主要阐述了以面向对象的程序开发语言Java,以eclipse为开发工具,基于Android系统开发一款数独游戏。数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。每一道合格的数独谜题都有且仅有一个唯一答案,推理方法也以此为基础,任何无解或者多解的题目都是不合格的。本程序实现了难度选择功能,计时功能,成绩保存,重来功能等。关键词:Android;手机游戏;数独ABSTRACTWiththedevelopmentofmobilephoneindustryboomingrapidly,especiallyintheAndroidsystem,forexample,agrowingnumberofmobilephonewithAndroidintelligentsystem,thissystemisbasedontheLinuxopensourceoperatingsystem,itsopenness,withoutbeinglimitedbytheoperators,richhardwaresupport,goodexpansibility,goodevaluationandusethesupportbytheoutsideworld.Androidsystemarchitectureisdividedintothreeparts:thepart,thecorepart,thebottompart.Inadditiontotheclassifiedmethods,fromthepointofthearchitectureofthesystemmodel,theAndroidcanbedividedintothefollowingseverallevels:(1)theapplicationlayer(2)frameworklayer(3)theruntime(4)coreclasslibraries(5)hardwareabstractionlayer(6)Linuxkernel.Thisarticlemainlyelaboratedinanobject-orientedprogramminglanguageJava,eclipseasthedevelopmenttool,developedasudokugamebasedonAndroidsystem.Sudokuisakindofusepaperandpenciltocalculuslogicgame.Playersneedtoaccordingto9x9knownfiguresonthedisksurface,reasoningoutalltherestofthespace,andsatisfyeachrow,everycolumn,everyhouseNumbersarethicklinewith1-9,don'trepeat.Everyqualifiedsudokupuzzlehasonlyoneandonlyoneanswer,reasoningmethodsandonthisbasis,thetopicofanykindofsolutionorsolutionisnotqualified.Thisprocedurerealizethefunctionofdifficultchoice,timingfunctions,performancepreservation,tofunction,etc.Keywords:Android;Mobilephonegames;Sudoku目录TOC\o"1-3"\u第一章绪论 11.1游戏背景 11.2游戏简介 11.2.1数独题目的数量 11.2.2数独题目的最少组成 11.3手机游戏特征 21.4国内外研究现状 3本章小结 3第二章技术介绍 42.1Android简介 42.2Android平台架构与特征 42.2.1Android平台特征 42.2.2Android平台架构 52.3Android应用程序组件 7本章小结 8第三章系统分析与设计 93.1系统需求分析 93.1.1功能需求分析 93.1.2安全性需求分析 93.2系统的结构设计 9本章小结 10第四章基于Android平台数独游戏的实现 114.1Android开发环境介绍 114.2Android开发平台搭建步骤 114.3系统的主要功能 124.2游戏中主要类的简要介绍 144.2.1难易度选择界面相关类 144.2.2数独列表界面相关类 144.2.3游戏界面相关类 144.3游戏中主要功能详解 154.3.1选择难易度界面 154.3.2关卡选择界面 174.3.3正式游戏界面 234.4数独数据库存储 274.4.1数据库代码 274.4.2数据库关系E-R图 284.4.3游戏的数据检测 29本章小结 29第五章游戏的测试和运行 305.1游戏测试概述 305.2测试环境 315.3游戏运行结果 31本章小结 33第六章总结和展望 346.1总结 346.2展望 34结束语 35致谢 36参考文献 37附录第一章绪论1.1游戏背景“九宫格”一词想必大家并不陌生,它作为数独的前身,最早起源于中国。但九宫格游戏较为复杂,需要从纵向、横向、斜向三个方向的数字之和全部等于15,不适合现在快节奏的生活,所以人们对经典的九宫格游戏进行了改良,形成了数独游戏。洛书河图是我国目前已发现的最早的九宫格游戏记载,到了18世纪末,瑞士数学家莱昂哈德•欧文又发明了一种叫做“拉丁方块”的游戏,之后不久,美国的一家杂志机构也刊登了类似的游戏,从此这个游戏受到了更多的欢迎,之后日本市场也引进了这个游戏,并进行广泛的传播[1]。2004年,在英国《泰晤士报》上,第一个“数独”游戏被刊登在此报上,从那时起数独游戏才真正为世界所知晓,并且很快风靡全球。其原因得益于此类游戏操作简单,不需要进行复杂的数字运算且可玩性高、锻炼思维、开发大脑,也不需要特定的语言基础。1.2游戏简介1.2.1数独题目的数量到底有多少个9×9的拉丁方阵呢?答案是:5524751496156892842531225600个。但是由于数独的规则是每行、每列、每个小九宫格都是要1到9之间的不同数字,这与拉丁方阵有很大不同,所以数独的谜题要比拉丁方阵少很多。直到2005年底,数学家贝米耳(StanleyE.Bammel)与罗思坦(JeromeRothstein)才算出一共有6670903752021072936960种可能的数独谜题[2]。为了庆贺这一结果,这两个数学家专门写了一份研究报告。但是在同一个数独中,数独是可以变换的,像行交换、列交换,还有可能是代码交换(比如1和8交换、2和5、3和6……)。若进行上述变换,用不了几次就很难分清是否来自同一数独了。为了解决这一难题,西澳大利亚大学教授GordonRoyle博士利用图形理论,研究出了辨别数独变换的方法。他将数独谜题利用Nauty程序图形的转化来做比对,该研究结果把利用这一方法将宫格内的行交换、列交换、代码交换等变换方法产生的等价题都扣除,最后计算出本质上共有5472730538个不同的数独谜题。此结果表明数独谜题的数量之大,若全球每天通过互联网和报纸刊登10000个本质上不同的数独谜题,仍需要花上一万多年才能全部罗列完这接近55亿的数独谜题。1.2.2数独题目的最少组成好的数独题目要求已知的数字是点对称的,而且谜题要有唯一解甚至已知的数字越少越好。目前最好的纪录是给定18个数字就可以产生出唯一解的数独谜题。如果放宽条件到不需要点对称,那么最少可以给定的数字是17个。许多玩家和学者对数独游戏痴迷不已,当然也包括很多计算机程序人员,他们在网上提供了众多免费下载的数独谜题程序。例如,才华横溢的数学家和组合学家Zeilberger曾写了一个在Maple上跑的程序供大家解出数独谜题[3],可以发现,难度高的题目不一定给出较少的数字,有时候提供的数字很多但仍然难度很高。反之,提供的数字少也许反而比较容易解题。也就是说,谜题的难易程度与提供的数字多少不是绝对相关的,谜题的难易程度和设计者的逻辑思维模式有关[4]。1.3手机游戏特征1.易于学习:既然手机游戏面向的是普通消费者而不是计算机专家,那么他们不可能深入的学习游戏技巧。因此手机游戏的控制应当尽量简单,且易于学习。即便游戏计划的控制方式要求很多很复杂,开发商也应当考虑将其简化。与主机控制器相比,手机和平板电脑的按键和控制选项更少,这意味着手机游戏开发商需要进行创新。许多成功游戏的控制都很简单。比如流行游戏《翼飞冲天》需要的玩家输入便很简单,点击屏幕可以使下坡加速,在上坡的时候放开即可[5]。2.可中断性:多任务处理是手机生活方式的基本特征。在手机设备上,接到电话会导致游戏马上退出,所以在游戏中采用智能中断设置是必要之举。如果用户在接完电话后发现自己刚才的游戏状态已消失,那么自然不会对游戏产生良好的印象。将来用户再玩该游戏的可能性也会减小,因为担心再接到电话导致他们前功尽弃。所以一个好的手机游戏应该提供短时间的娱乐功能,并且允许用户在游戏与工作模式之间顺利切换。3.基于订阅:手机游戏的盈利成功取决于他们巨大的使用量。一开始开发与设计每个游戏都是昂贵的。如果一个手机游戏开发者要赢利的话,重要的是消耗一个游戏引擎,多个标题,基本的故事情节类似。基于订阅的游戏是不断产生收入的最好方法。4.丰富的社会交互:不管一个游戏设计得多好,只要玩家找到了它的根本模式或者玩完了所有的游戏路径很快就会厌烦这个游戏。对于一个基于订阅的游戏,重要的是与别的玩家合作以增强所玩游戏的智力与随机性。在今天纷繁复杂的多玩家游戏中具有丰富社会交互的游戏证明是成功的。5.好的网络基础设备:巨额的手机技术研发费用都花在提高设备与网络的可用性与可靠性上面。因此,手机设备硬件与网络协议与桌面/控制台世界(如全球定位系统(GPS)扩展、条形码扫描仪、与短消息服务(SMS)/多媒体信息服务(MMS)通讯)有着非常大的差别。好的手机游戏应该利用那些更新的设备特征与网络基础设备的优点。6.有效利用屏幕实用面积:任何屏幕上的使用面积都是有限的,开发商必须考虑到这一点。比如玩《僵尸时代》需要用你的拇指控制两个屏幕上的“虚拟操纵杆”。这需要占据大片屏幕实用面积,使游戏玩起来较为困难。平板电脑有着更大的实用面积,但依然会出现上述问题。如果用平板电脑来玩《僵尸时代》,操纵杆依然很难使用,触控精确性有一定的问题,因为相比手机来说两个操纵杆相隔更远。7.功能反馈:由于缺乏按动按键或震动等触觉反馈,手机游戏必须使用不同的方式来告知用户他们的动作已经被游戏接受,它们应当在屏幕上提供不显眼却能够传达信息的反馈。比如,在手游《无尽之剑》中会高亮玩家按动的屏幕按键[6],并在屏幕上呈现相关文本。这些信号立马便可以告知玩家攻击或格挡是否成功。同样,当受到伤害时,所受伤害数值也会显示在屏幕上,同时生命值扣除相应数值。1.4国内外研究现状Android操作系统是基于Linux平台的开发的手机操作系统,他是由著名的互联网公司Google公司进行开发的。Android操作系统包括用户界面、手机操作系统和手机应用程序等移动设备所需要的所有软件能够保证正常的使用,而且Android操作系统不存在和以前手机操作系统上的阻碍移动通信设备上所需创新的所有权障碍,因为他是一个开源的手机操作系统。Google与开放手机联盟合作开发了Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达电和T-Mobile在内的30多家技术和无线应用的领军企业组成[7]。Google通过与运营商、设备制造商、开发商和其他相关各方结成深层次的合作伙伴关系,希望借助建立标准化、开放式的移动设备软件平台,在移动产业内形成一个开放式的生态系统。
Androind操作系统作为谷歌企业战略的重要组成部分,将进一步推进“随时随地为每个人提供信息”这一企业目标的实现。Android手机操作系统将作为Google扩展移动设备市场的一个奠基石,而后为Google应用的推广起到了良好的作用。但Android操作系统不会替代谷歌长期以来奉行的移动发展策略:通过与全球各地的手机制造商和运营商结成合作伙伴,开发既有用又有吸引力的移动服务,并推广这些产品[8]。本章小结本章介绍了数独游戏的起源、数独游戏玩法和规则,手机游戏的特征,以与Android系统的国内外现状,希望能让大家对数独有更深入的了解。第二章技术介绍2.1Android简介Android(安卓),是一个以Linux为基础的开源移动设备操作系统,主要用于智能手机和平板电脑,由Google成立的OpenHandsetAlliance(OHA,开放手持设备联盟)持续领导与开发中。Android已发布的最新版本为Android5.0(Lollipop)。Android系统最初由安迪·鲁宾(AndyRubin)等人开发制作[9],最初开发这个系统的目的是创建一个数码相机的先进操作系统;但是后来发现市场需求不够大,加上智能手机市场快速成长,于是Android被改造为一款面向智能手机的操作系统。於2005年8月被美国科技企业Google收购。2007年11月,Google与84家制造商、开发商与电信营运商成立开放手持设备联盟来共同研发改良Android系统,随后,Google以Apache免费开放原始码许可证的授权方式,发布了Android的原码,让生产商推出搭载Android的智能手机,Android后来更逐渐拓展到平板电脑与其他领域上。2010年末数据显示,仅正式推出两年的Android作业系统在市场占有率上已经超越称霸逾十年的诺基亚Symbian系统,成为全球第一大智能手机操作系统[10]。2.2Android平台架构与特征2.2.1Android平台特征随着科技的发展,移动电话(MobilePhone)正朝着智能化的方向发展,逐步成为多种工具的功能载体,而Android就是这样一个智能手机的平台、一个多种工具的功能载体。通信工具移动电话的最基本功能为通信功能,因此使用运营商提供的通信网络进行语音通话也是Android平台的最基本功能。除了传统的语音通话功能外,Android平台还具有短消息功能,以与通常移动电话都具有的个人信息系统管理方面的功能(如电话本等)。2.网络工具随着数字业务使用的普遍化,移动电话通常被作为网络工具使用,即移动电话可以完成电脑的部分功能。而Android平台在网络方面的功能主要包括浏览器、IM(即时信息)、邮件等。3.媒体播放器随着多媒体技术的发展应用,在移动电话上进行音频和视频播放已经成为经常使用的功能。由此,Android平台具有支持更多的音频/视频格式,支持更高分辨率的视频,可更流畅地播放视频,以与支持网络流媒体等功能。4.媒体获取设备随着移动电话与媒体获取设备的集成日益增强,Android平台提供了照相机、录音机、摄像机等功能。5.多类型的连接设备Android平台提供了多种连接方式,如USB、GPS、红外、蓝牙、无线局域网等。6.具有友好和绚丽的用户界面Android平台具有友好的用户界面,使用户容易学习和操作;同时具有绚丽的用户界面,具有良好的视觉效果。7.可以个性化定制的平台Android平台针对于用户的个性化需求,提供了全面自定义手机的功能。除了上述介绍的Android平台的功能以外,其在技术上还具有以下几个方面的特性:全开放智能移动电话平台;支持多硬件平台;使用众多的标准化技术;核心技术完整、统一;完善的SDK和文档;完善的辅助开发工具。2.2.2Android平台架构从图2.1我们可以看出,Android操作系统的体系结构可分为4层,由上到下依次是应用程序、应用程序框架、核心类库和Linux内核,其中第三层还包括Android运行时的环境。下面分别来讲解各个部分。图2.1Android操作系统体系结构1.程序应用Android连同一个核心应用程序包一起发布,该应用程序包包括E-mail客户端、SMS短消息程序、日历、地图、浏览器、联系人管理程序等。所有的应用程序都是用Java编写的[11]。2.应用程序框架开发者完全可以访问核心应用程序所使用的API框架。该应用程序框架架构用来简化组件软件的重用,任何一个应用程序都可以发布它的功能块并且任何其他的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。该应用程序重用机制使得组件可以被用户替换。以下所有的应用程序都由一系列的服务和系统组成,包括:(1)一个可扩展的视图(Views)可以用来创建应用程序,包括列表(lists)、网络(grids)、文本框(textboxes)、按钮(buttons),甚至是一个可嵌入的Web浏览器。(2)内容管理器(ContentProviders)使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据。(3)一个资源管理器(ResourceManager)提供非代码资源的访问,如本地字符串、图形和分层文件(layoutfiles)。(4)一个通知管理器(NotificationManager)使得应用程序可以在状态栏中显示客户通知信息。(5)一个活动类管理器(ActivityManager)用来管理应用程序生命周期并提供常用的导航回退功能。3.Android程序库Android包括一个被Android系统中各种不同组件所使用的C/C++集库。该库通过Android应用程序框架为开发者提供服务。以下是一些主要的核心库[12]:(1)系统C库:一个从BSD继承来的标准C系统函数库(libc),专门为基于EmbeddedLinux的设备定制。(2)媒体库:基于PacketVideoOpenCORE;该库支持录放,并且可以录制许多流行的音频视频格式,还有静态映像文件包括MPEG4、H.264、MP3、AAC、JPG、PNG。(3)SurfaceManager:对显示子系统的管理,并且为多个应用程序提供2D和3D图层的无缝融合。(4)LibWebCore:一个最新的Web浏览器引擎,用来支持Android浏览器和一个可嵌入的Web视图。(5)SGL:一个内置的2D图形引擎。(6)3Dlibraries:基于OpenGLES1.0APIs实现;该库可以使用硬件3D加速(如果可用)或者使用高度优化的3D软加速。(7)FreeType:位图(bitmap)和向量(vector)字体显示。(8)SQLite:一个对于所以应用程序可用、功能强劲的轻型关系型数据库引擎。4.Android运行库Android包括了一个核心库,该核心库提供了Java编程语言核心库的大多数功能。每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik是针对同时高效地运行多个VMs实现的。Dalvik虚拟机执行.dex的Dalvik可执行文件,该格式文件针对最小内存使用做了优化。该虚拟机是基于寄存器的,所有的类都是经由Java汇编器编译,然后通过SDK中的DX工具转化成.dex格式由虚拟机执行[13]。Dalvik虚拟机依赖于Linux的一些功能,比如线程机制和底层内存管理机制。5.Linux内核Android的核心系统服务依赖于Linux内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型[14]。Linux内核也同时作为硬件和软件栈之间的硬件抽象层。2.3Android应用程序组件应用程序组件是Android应用程序的基本构建单元。每个组件是系统进入你的应用程序的不同入口点。不是所有的组件对于用户都是实际上的入口点,有些是互相依赖的,但是每个组件都有特定的作用——每个都是唯一的构建单元,这些构建单元定义你应用程序的全部行为这里有6个组件,它们是Android应用程序的基石[15]:(1)Activities(活动)应用程序的显示层。每一个画面对应于你的应用程序,将会是Activity类的扩展。Activity使用Views去构建UI来显示信息和响应用户的行为。就桌面开发而言,一个Activity相当于一张Form。(2)Services(服务)应用程序中不可见的“工人”。Service组件运行时不可见,但它负责更新的数据源和可见的Activity,以与触发通知。它们常用来执行一些需要持续运行的处理,当你的Activity已经不处于激活状态或不可见。(3)Content(内容)提供共享的数据存储。ContentProvider(内容提供器)用来管理和共享应用程序的数据库。在应用程序间,ContentProvider是共享数据的首选方式。这意味着,你可以配置自己的ContentProvider去存取其他的应用程序或者通过其他应用程序暴露的ContentProvider去存取它们的数据。Android设备本身包含了几个ContentProvider来访问像联系人信息等有用的数据库。(4)Intents(意图)简单的消息传递框架。使用Intent,你可以在整个系统内广播消息或者给特定的Activity或者服务来执行你的行为意图。系统会决定那个(些)目标来执行适当的行为。(5)BroadcastReceivers(广播接收器)Intent广播的“消费者”。通过创建和注册一个BroadcastReceiver,应用程序可以监听符合特定条件的广播的Intent。BroadcastReceiver会自动的启动你的应用程序去响应新来的Intent。BroadcastReceiver是事件驱动程序的理想手段。(6)Notifications(通知)用户通知的框架。Notification用来在不需要焦点或不中断它们当前Activity的情况下提示用户。它们是Service或BroadcastReceiver获得用户注意的首选方式。例如,当设备收到文本信息或外部来电时,它通过闪光,发声,显示图标或显示对话框信息来提醒你。本章小结本章主要讲述了开发基于Android系统的数独游戏的技术做了一些概述,通过本章的内容我们要了解Android的简介,Android平台的特征、架构、以与Android平台应用程序组件。第三章系统分析与设计3.1系统需求分析需求分析完成的好坏直接影响后续软件开发的质量,它的重要性由此可见一斑。现实情况往往是,用户不了解计算机的相关知识,而开发人员也对相关业务领域不甚了解。受思维定式的影响,用户和开发人员往往对同一问题有不同的理解,这样就对系统的功能确定带来了很大的麻烦。所以,开发人员和用户之间要进行充分和有效的沟通,甚至开发人员要置身于相关的业务领域,以确保开发出来的系统能够真正满足用户的需要[16]。3.1.1功能需求分析此次程序设计任务是Android平台下的数独游戏设计,程序将在Android模拟器中运行调试。此次程序设计用户界面要求较为友好,由于针对的用户为Android智能手机用户,因此程序的操作非常简单容易操作。游戏进行时通过底部键盘中的数字键输入答案,程序中储存了90个分三个难度的数独题目,供用户娱乐,此次程序设计的操作系统要求为Windows7,且此次程序设计需要在Eclipse环境下开发。1.重来功能重来功能主要实现用户想要重新开始本谜题。2.选关功能选关功能主要实现用户可以自主选择关卡。3.计时功能计时功能主要实现对用户解决谜题的计时。4.成绩保存功能成绩保存功能主要实现对用户解决本谜题所用时间的保存。5.难易程度选择功能难易程度选择功能主要实现用户根据自己实际水平选择适合自己难度的题目。6.退出功能退出功能主要实现退出游戏。3.1.2安全性需求分析因该游戏不涉与到用户信息等,因此不需要考虑信息的泄漏。3.2系统的结构设计系统结构为进入主界面显示选择难度界面,在用户选择难度之后,进入相应的关卡选择界面,选择具体关卡之后,将进入正式游戏界面。在正式游戏界面时,系统将会自动计时,用户按返回键则暂停计时,并返回关卡选择界面,若用户要重解本谜题,则可以使用菜单选项,按Restart键即可重新解答本谜题。当用户成功解决本谜题时,系统将会自动停止计时,并保存用户解决本谜题所用的时间(即成绩保存)。本程序中这三个界面之间都是可以通过返回键互相切换的,具体系统结构图如图3.1所示。启动游戏启动游戏选择难易度游戏主界面选则关卡重来功能计时功能退出功能图3.1系统结构图本章小结本章对Android数独游戏做了需求分析,并对系统结构做了简单介绍,可以从下一章中具体看到这些界面与具体的实现方法和部分代码。第四章基于Android平台数独游戏的实现4.1Android开发环境介绍Android的上层应用程序是用Java语言开发,同时还需要基于Dalvik虚拟机,所以,Google公司推荐使用主流的Java继承开发环境Eclipse[17]。只有Eclipse还不够,因为是使用Java语言进行开发,还应该有由SUN公司提供的JavaSDK(其中包括JRE:JavaRuntimeEnvironment)。此外,Android的应用程序开发和Java开发有较大区别的,所以还需要有Google提供的AndroidSDK。同时,还需要在Eclipse安装ADT,为Android开发提供开发工具的升级或者变更,是Eclipse下开发工具的升级下载的工具[18]。 简言之,需要以下软件,才能搭建Android开发环境,从而进行Android应用程序的开发。(1)JavaSDK(2)Eclipse(3)AndroidSDK(4)ADT4.2Android开发平台搭建步骤1.首先到/downloads/下载Eclipse集成开发环境并且解压,这里推荐下载JavaEE集成版本,可以为平台的搭建省下不少工作。接着再去/javase/downloads/index.jsp站点下载SDK后安装,下载/android/android-sdk-windows-1.5_r1.zipAndroidSDK1.5后解压。第一步下载工序就结束了。2.双击Eclipse解压后目录中的eclipse.exe然后启动,选择Eclipse菜单中的Help->InstallNewSoftware->选项卡上的AvailableSoftware,点击右侧的“Add”输入/android/eclipse/后确定,然后在“Workwith”下拉菜单中选择刚才输入的网址。过一会就会出现一个DeveloperTools选项,勾上以后点击Next以后Eclipse会自动网上查找Android开发工具插件,然后找到AndroidDDMS和AndroidDevelopmentTools,选中这两个点击Finish,Eclipse就会自动下载并安装Android插件了,最后会提示重启Eclipse。3.重启后选择Eclipse菜单中的Windows->Preferences在左侧的Android项目中SDKLocation中填入AndroidSDK解压后的目录,然后点击Apply。4.在WindowsXP的系统变量中的path变量中添加一个值,该值指向解压后的AndroidSDK目录下的tools文件夹[19]。4.3系统的主要功能数独游戏的规则很简单,只需在空格处填入1~9的数字,并保证每个数字在每个九宫格内只能出现一次,且每个数字在每一行、每一列也只能出现一次[20],然后玩家需要在空白处填上相应的数字使其满足游戏规则。该游戏的运行步骤如下:启动游戏后首先进入的便是游戏难度选择界面,效果如图4.1所示,在难度选择界面中,用户可以选择Easy,Medium,Hard三个难度等级。图4.1难度选择界面图4.2关卡选择界面当用户随意选择一个难度以后,将进入具体关卡选择界面,效果如图4.2所示,在任意难度中都有30个关卡。当用户随意选择一个关卡后,将正式进入数独游戏界面,效果如图4.3所示。在游戏界面,由9×9的九宫格和底部的数字键盘组成。图4.3数独游戏界面图4.4返回界面在这里,我们可以看到,在正式游戏界面顶部,有计时功能,从玩家打开本谜题时开始计时,当玩家按返回键时,则暂停计时,并且改变游戏状态,效果如图4-4所示。因为我们演示的是第二个谜题,当玩家按返回键时,则暂停计时,第二个谜题状态变为(Playing)。我们知道,当玩家已经知道一个谜题的正确解法,但已经错误太多时候,这时就需要有重新开始本谜题的功能,在这里我们先随意填写几个数字,当我们通过菜单功能按下(Restart)键时,本谜题将清除已填数字,且计时也重新开始,效果如图4.5,4.6所示。图4.5重新开始按钮图4.6重新开始以后的游戏当玩家正确填满谜题之后,将会弹出对话框完成对话框,且计时功能暂停,若没有正确填写则不弹出对话框,计时功能也将继续,直到全部正确填写完成之后才结束,效果如图4.7所示。当完成谜题之后,按返回键回到关卡选择界面,此时,被完成的谜题状态改变,且完成的成绩被保存在谜题后面,效果如图4.8所示。图4.7正确填写谜题结果图4.8谜题状态与成绩保存4.2游戏中主要类的简要介绍为了让读者更好地理解后面的代码,下面将对游戏中的各个类逐一进行简要说明。关于这些类的详细代码将在后面的章节中相继给出。4.2.1难易度选择界面相关类FolderListActivity类该类为选择难易度界面的实现类,主要负责选择难易度界面的绘制,是整个应用程序的入口。此类让activity继承ListActivity,并且舍弃XML布局文件,全部采用默认布局中存在的布局来布局。此类重写onCreate()方法,onResume()方法,onWindowFocusChanged()方法,onPause()方法,onDestroy()方法,onSaveInstanceState()方法(保存数据)等。4.2.2数独列表界面相关类SudokuListActivity类该类为数独列表(关卡)界面的实现类,主要负责数独关卡界面的绘制,此类继承了ListActivity,同样舍弃了XML布局文件,全部采用默认布局中存在的布局来布局。4.2.3游戏界面相关类(1)SudokuPlayActivity类SudokuPlayActivity类是游戏中最主要的一个类,游戏规则、游戏模型都包含在此类当中。同时该类还负责绘制游戏的画面、接收玩家的响应。(2)Cell类Cell类负责9×9九宫格中每一个小格的操作。(3)数独生成器DatabaseHelper类该类继承了SQLiteOpenHelper类,为游戏随机提供存放数独数字的二维数组,该类存储了本程序所有的谜题数据。(4)Timer类该类负责对游戏的计时功能。有start()功能,stop()功能,reset()功能,isRunning()功能,getTime等功能。(5)IMNumpad类该类是游戏进行时底部的键盘,负责输入数字。数字键盘主体部分有1-9的数字,和一个(C)清除符号。4.3游戏中主要功能详解4.3.1选择难易度界面图4.9选择难度界面选择难度界面主要代码如下:1.OnCreat()方法负责选择难易度界面的窗口生成,此窗口由三个ContentView组成。protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.folder_list); ViewgetMorePuzzles=(View)findViewById(R.id.get_more_puzzles); setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);getListView().setOnCreateContextMenuListener(this); mDatabase=newSudokuDatabase(getApplicationContext()); mCursor=mDatabase.getFolderList(); startManagingCursor(mCursor); SimpleCursorAdapteradapter=newSimpleCursorAdapter(this,R.layout.folder_list_item, mCursor,newString[]{FolderColumns.NAME,FolderColumns._ID}, newint[]{R.,R.id.detail}); mFolderListBinder=newFolderListViewBinder(this); adapter.setViewBinder(mFolderListBinder);setListAdapter(adapter);Changelogchangelog=newChangelog(this);changelog.showOnFirstRun(); }2.onListItemClick()方法负责点击所触法的功能。比如,当玩家点击Easy难度,将会进入下个Easy界面关卡中。protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){ Intenti=newIntent(this,SudokuListActivity.class); i.putExtra(SudokuListActivity.EXTRA_FOLDER_ID,id); startActivity(i); }3.自定义类FolderListViewBinder来对接口进行回调,它的作用很简单,就是绑定数据到view,用户点击不同的难度将会自动连接到绑定的数据库中。privatestaticclassFolderListViewBinderimplementsViewBinder{ privateContextmContext; privateFolderDetailLoadermDetailLoader; publicFolderListViewBinder(Contextcontext){ mContext=context; mDetailLoader=newFolderDetailLoader(context); } @Override publicbooleansetViewValue(Viewview,Cursorc,intcolumnIndex){ switch(view.getId()){ caseR.: ((TextView)view).setText(c.getString(columnIndex)); break; caseR.id.detail: finallongfolderID=c.getLong(columnIndex); finalTextViewdetailView=(TextView)view; detailView.setText(mContext.getString(R.string.loading)); mDetailLoader.loadDetailAsync(folderID,newFolderDetailCallback(){ publicvoidonLoaded(FolderInfofolderInfo){ if(folderInfo!=null) detailView.setText(folderInfo.getDetail(mContext)); } }); } returntrue; }4.3.2关卡选择界面图4.10关卡选择界面关卡选择界面主要代码如下:1.OnCreat()方法负责关卡选择界面窗口的生成,此界面显示了30道题库和每个谜题的状态,以与谜题是否完成。protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); AndroidUtils.setThemeFromPreferences(this); setContentView(R.layout.sudoku_list); mFilterStatus=(TextView)findViewById(R.id.filter_status); getListView().setOnCreateContextMenuListener(this); setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); mDatabase=newSudokuDatabase(getApplicationContext()); mFolderDetailLoader=newFolderDetailLoader(getApplicationContext()); Intentintent=getIntent(); if(intent.hasExtra(EXTRA_FOLDER_ID)){ mFolderID=intent.getLongExtra(EXTRA_FOLDER_ID,0); }else{ Log.d(TAG,"No'folder_id'extraprovided,exiting."); finish(); return; } finalSharedPreferencessettings=PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); mListFilter=newSudokuListFilter(getApplicationContext()); mListFilter.showStateNotStarted=settings.getBoolean(FILTER_STATE_NOT_STARTED,true); mListFilter.showStatePlaying=settings.getBoolean(FILTER_STATE_PLAYING,true); mListFilter.showStateCompleted=settings.getBoolean(FILTER_STATE_SOLVED,true); mAdapter=newSimpleCursorAdapter(this,R.layout.sudoku_list_item, null,newString[]{SudokuColumns.DATA,SudokuColumns.STATE, SudokuColumns.TIME,SudokuColumns.LAST_PLAYED, SudokuColumns.CREATED,SudokuColumns.PUZZLE_NOTE}, newint[]{R.id.sudoku_board,R.id.state,R.id.time, R.id.last_played,R.id.created,R.id.note}); mAdapter.setViewBinder(newSudokuListViewBinder(this)); updateList(); setListAdapter(mAdapter); }2.onKeyDown()方法实现当用户按下返回键时,实现界面从关卡选择界面到难度选择界面的之间的切换。publicbooleanonKeyDown(intkeyCode,KeyEventevent){ if(isTaskRoot()&&keyCode==KeyEvent.KEYCODE_BACK){ Intenti=newIntent(); i.setClass(this,FolderListActivity.class); startActivity(i); finish(); returntrue; } returnsuper.onKeyDown(keyCode,event); }3.onListItemClick()方法负责在此界面选择任意关卡将执行的操作。比如,当玩家选择了第二关,则相应的进入正式游戏界面。protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){ playSudoku(id); }4.playSudoku()方法表示当用户选择关卡以后将调用SudokuPlayActivity,进入谜题解答界面。privatevoidplaySudoku(longsudokuID){ Intenti=newIntent(SudokuListActivity.this,SudokuPlayActivity.class); i.putExtra(SudokuPlayActivity.EXTRA_SUDOKU_ID,sudokuID); startActivity(i); }5.自定义类SudokuListViewBinder来对接口进行回调,它的作用很简单,就是绑定数据到view,当玩家选择了一个关卡,则会进入已绑定题库的游戏界面。此类包含游戏状态函数,游戏成绩保存函数getDateAndTimeForHumans()。privatestaticclassSudokuListViewBinderimplementsViewBinder{ privateContextmContext; privateGameTimeFormatmGameTimeFormatter=newGameTimeFormat(); privateDateFormatmDateTimeFormatter=DateFormat.getDateTimeInstance( DateFormat.SHORT,DateFormat.SHORT); privateDateFormatmTimeFormatter=DateFormat .getTimeInstance(DateFormat.SHORT); publicSudokuListViewBinder(Contextcontext){ mContext=context; } publicbooleansetViewValue(Viewview,Cursorc,intcolumnIndex){ intstate=c.getInt(c.getColumnIndex(SudokuColumns.STATE)); TextViewlabel=null; switch(view.getId()){ caseR.id.sudoku_board: Stringdata=c.getString(columnIndex); CellCollectioncells=null;; try{cells=CellCollection.deserialize(data); }catch(Exceptione){ longid=c.getLong(c.getColumnIndex(SudokuColumns._ID)); Log.e(TAG,String.format("Exceptionoccurredwhendeserializingpuzzlewithid%s.",id),e); } SudokuBoardViewboard=(SudokuBoardView)view; board.setReadOnly(true); board.setFocusable(false); ((SudokuBoardView)view).setCells(cells); break; caseR.id.state: label=((TextView)view); StringstateString=null; switch(state){ caseSudokuGame.GAME_STATE_COMPLETED: stateString=mContext.getString(R.string.solved); break; caseSudokuGame.GAME_STATE_PLAYING: stateString=mContext.getString(R.string.playing); break; } label.setVisibility(stateString==null?View.GONE :View.VISIBLE); label.setText(stateString); if(state==SudokuGame.GAME_STATE_COMPLETED){ label.setTextColor(Color.rgb(187,187,187)); }else{ label.setTextColor(Color.rgb(255,255,255)); } break; caseR.id.time: longtime=c.getLong(columnIndex); label=((TextView)view); StringtimeString=null; if(time!=0){ timeString=mGameTimeFormatter.format(time); } label.setVisibility(timeString==null?View.GONE :View.VISIBLE); label.setText(timeString); if(state==SudokuGame.GAME_STATE_COMPLETED){ label.setTextColor(Color.rgb(187,187,187)); }else{ label.setTextColor(Color.rgb(255,255,255)); } break; caseR.id.last_played: longlastPlayed=c.getLong(columnIndex); label=((TextView)view); StringlastPlayedString=null; if(lastPlayed!=0){ lastPlayedString=mContext.getString(R.string.last_played_at, getDateAndTimeForHumans(lastPlayed)); } label.setVisibility(lastPlayedString==null?View.GONE :View.VISIBLE); label.setText(lastPlayedString); break; } returntrue; }4.3.3正式游戏界面图4.11正式游戏界面正式游戏界面主要代码:1.onCreate方法负责窗口生成。首先要对窗口进行全屏操作,然后加载计时功能,最后加载数字键盘功能。publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState); Displaydisplay=getWindowManager().getDefaultDisplay(); if((display.getWidth()==240||display.getWidth()==320) &&(display.getHeight()==240||display.getHeight()==320)){ requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mFullScreen=true; } AndroidUtils.setThemeFromPreferences(this); setContentView(R.layout.sudoku_play); mRootLayout=(ViewGroup)findViewById(R.id.root_layout); mSudokuBoard=(SudokuBoardView)findViewById(R.id.sudoku_board); mTimeLabel=(TextView)findViewById(R.id.time_label); mDatabase=newSudokuDatabase(getApplicationContext()); mHintsQueue=newHintsQueue(this);mGameTimer=newGameTimer();mGuiHandler=newHandler();if(savedInstanceState==null){ mSudokuGameID=getIntent().getLongExtra(EXTRA_SUDOKU_ID,0); mSudokuGame=mDatabase.getSudoku(mSudokuGameID);}else{ mSudokuGame=newSudokuGame(); mSudokuGame.restoreState(savedInstanceState); mGameTimer.restoreState(savedInstanceState);}if(mSudokuGame.getState()==SudokuGame.GAME_STATE_NOT_STARTED){ mSudokuGame.start();}elseif(mSudokuGame.getState()==SudokuGame.GAME_STATE_PLAYING){ mSudokuGame.resume();}if(mSudokuGame.getState()==SudokuGame.GAME_STATE_COMPLETED){ mSudokuBoard.setReadOnly(true);}mSudokuBoard.setGame(mSudokuGame); mSudokuGame.setOnPuzzleSolvedListener(onSolvedListener); mHintsQueue.showOneTimeHint("welcome",R.string.welcome,R.string.first_run_hint); mIMControlPanel=(IMControlPanel)findViewById(R.id.input_methods); mIMControlPanel.initialize(mSudokuBoard,mSudokuGame,mHintsQueue); mIMControlPanelStatePersister=newIMControlPanelStatePersister(this);mIMPopup=mIMControlPanel.getInputMethod(IMControlPanel.INPUT_METHOD_POPUP);mIMSingleNumber=mIMControlPanel.getInputMethod(IMControlPanel.INPUT_METHOD_SINGLE_NUMBER);mIMNumpad=mIMControlPanel.getInputMethod(IMControlPanel.INPUT_METHOD_NUMPAD);}2.在此窗口,还要调用View的继承类SudokuBoardView中的onDraw()方法,此方法用来绘制九宫格的游戏界面,下面只给出部分主要代码。protectedvoidonDraw(Canvascanvas){ for(intc=0;c<=9;c++){ floatx=(c*mCellWidth)+paddingLeft; canvas.drawLine(x,paddingTop,x,height,mLinePaint); } for(intr=0;r<=9;r++){ floaty=r*mCellHeight+paddingTop; canvas.drawLine(paddingLeft,y,width,y,mLinePaint); } intsectorLineWidth1=mSectorLineWidth/2; intsectorLineWidth2=sectorLineWidth1+(mSectorLineWidth%2); for(intc=0;c<=9;c=c+3){ floatx=(c*mCellWidth)+paddingLeft; canvas.drawRect(x-sectorLineWidth1,paddingTop,x+sectorLineWidth2,height,mSectorLinePaint); } for(intr=0;r<=9;r=r+3){ floaty=r*mCellHeight+paddingTop; canvas.drawRect(paddingLeft,y-sectorLineWidth1,width,y+sectorLineWidth2,mSectorLinePaint); } }3.当玩家点击MENU菜单时调用onOptionsItemSelected方法,并弹出菜单栏,玩家点击Restart按钮,实现重来功能(restart())。publicbooleanonOptionsItemSelected(MenuItemitem){switch(item.getItemId()){caseMENU_ITEM_RESTART: showDialog(DIALOG_RESTART);returntrue;}returnsuper.onOptionsItemSelected(item); }4.一个Dialog一直被创建与作为Activity的一部分显示的时候,一般情况下,你应该使用回调方法onCreateDialog(int)创建Dialog,当你使用这个方法的时候,Android系统会自动的管理每一个Dialog的状态,并有效的控制着每个Dialog,同样的,每个Dialog也会继承Activity中的某些特性。就像当一个Dialog显示的时候,按下菜单键显示Activity定义的选项菜单或者使用音量键调整音视频音量的大小,当你想显示一个Dialog的时候,调用showDialog(int)方法,传递的参数是唯一能标识你想显示的对话框的整数。此处有两个对话框,分别是正确解决谜题时弹出的DIALOG_WELL_DONE:对话框,以与当玩家点击restart按钮弹出的DIALOG_RESTART对话框,以下是对话框的详细代码。protectedDialogonCreateDialog(intid){ switch(id){ caseDIALOG_WELL_DONE:returnnewAlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_info).setTitle(R.string.well_done).setMessage(getString(R.string.congrats,mGameTimeFormatter.format(mSudokuGame.getTime()))).setPositiveButton(android.R.string.ok,null).create(); caseDIALOG_RESTART:returnnewAlertDialog.Builder(this).setIcon(android.R.drawable.ic_menu_rotate).setTitle(R.string.app_name).setMessage(R.string.restart_confirm).setPositiveButton(android.R.string.yes,newDialogInterface.OnClickListener(){publicvoidonClick(DialogInterfacedialog,intwhichButton){ mSudokuGame.reset(); mSudokuGame.start(); mSudokuBoard.setReadOnly(false); if(mShowTime){ mGameTimer.start(); }}}).setNegativeButton(android.R.string.no,null).create(); } returnnull;}5.GameTimer类负责此程序的计时功能。privatefinalclassGameTimerextendsTimer{ GameTimer(){ super(1000); } protectedbooleanstep(intcount,longtime){ updateTime();returnfalse;} }4.4数独数据库存储4.4.1数据库代码本程序共有90个谜题,分3个难度,Easy,Medium,Hard。每个难度有30个谜题,在本程序中我们采用DatabaseHelperextendsSQLiteOpenHelper,定义了类DatabaseHelper,继承了SQLiteOpenHelper,谜题的数据都存在类DatabaseHelper中的OnCreat()方法中,但由于题库量较大,此处只给出2个题库数据,具体代码如下:publicvoidonCreate(SQLiteDatabasedb){db.execSQL("CREATETABLE"+SudokuDatabase.SUDOKU_TABLE_NAME+"("+SudokuColumns._ID+"INTEGERPRIMARYKEY,"+SudokuColumns.FOLDER_ID+"INTEGER,"+SudokuColumns.CREATED+"INTEGER,"+SudokuColumns.STATE+"INTEGER,"+SudokuColumns.TIME+"INTEGER,"+SudokuColumns.LA
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 施工总包合同文本
- 厨房日用品采购合同
- 借款还款合同范本
- 医院药品采购合同的价格调整
- 物流电子商务合作合同
- 苏州市物业管理合同评析
- 房屋买卖合同中介服务的发展趋势
- 钢筋分项工程分包合同
- 借款还款合同协议书
- 服务外包合同的转让条件
- 汽车技术人员奖惩制度范本
- 统计造假弄虚作假自查范文(通用5篇)
- 互联网背景下小学生心理健康教育策略 论文
- 传统节日文化在幼儿园课程中的应用研究 论文
- 《机械设计基础A》机械电子 教学大纲
- 2022宁夏共享集团公司校园招聘48人上岸笔试历年难、易错点考题附带参考答案与详解
- 基因扩增实验室常用仪器使用课件
- 2023年营养师、营养指导员专业技能及理论知识考试题库(附含答案)
- 肺功能万里行考试内容
- 男生青春期教育讲座-课件
- 《银行运营档案管理系统业务管理规定》制定说明
评论
0/150
提交评论