毕业论文 - 基于安卓系统的拼图游戏设计 - word文档 下载本文

毕 业 论 文

设计(论文)题目: 基于Android 益智拼图游戏设计

学生姓名: 陈 斌 指导教师: 李莉 讲师 二级学院: 信息技术学院 专 业: 计算机科学与技术 班 级:08计算机科学与技术(2) 学 号: 0805110219 提交日期: 2012年 04月 27日 答辩日期: 2012年 05月 12日

金陵科技学院学士学位论文 目录

目 录

摘 要 .......................................................... III Abstract ........................................................ IV 1 绪 论 .......................................................... 1 1.1 课题开发的背景 ............................................ 1 1.2 课题意义 .................................................. 1 2 Android架构与开发平台搭建 ..................................... 2 2.1 Android的系统架构 ........................................ 2 2.2 Window下Android开发环境的搭建 ........................... 4 3 流程介绍与概要设计 ............................................. 5 3.1 游戏流程介绍 .............................................. 5 3.2 系统概要设计 .............................................. 6

3.2.1 界面布局模块 ........................................ 6 3.2.2 难度选择模块 ........................................ 6 3.2.3 图片选择模块 ........................................ 7 3.2.4 步数和时间模块 ...................................... 7 3.2.5 游戏实现模块 ........................................ 7

4 系统详细设计与实现 ............................................. 8 4.1 界面布局实现 .............................................. 8

4.1.1 选择界面布局 ........................................ 8 4.1.2 游戏界面布局 ........................................ 9 4.2 游戏功能实现 ............................................. 11

4.2.1 难度选择 ........................................... 11 4.2.2 图片选择 ........................................... 12 4.2.3 步数和时间设置 ..................................... 13 4.2.4 拼图的实现 ......................................... 14

5 系统测试 ...................................................... 17 5.1 Android仿真器介绍 ...................................... 17

I

金陵科技学院学士学位论文 目录

5.2 功能模块测试 ............................................ 17 5.3 出现的错误及解决方案 .................................... 20 6 总结与展望 .................................................... 21 参考文献 ........................................................ 22 附 录 ........................................................... 23 致 谢 ........................................................... 33

II

金陵科技学院学士学位论文 摘要

基于Android益智拼图游戏设计

摘 要

随着移动设备的日益普及,使用Android技术开发手机软件受到越来越多人的青睐。在此背景下,本课题开发了一款Android平台下的手机游戏——益智拼图。

本文首先对Android的研究背景,系统架构以及开发环境进行介绍,然后就玩家对游戏的需求进行一定的分析,最后运用Android技术实现拼图游戏的开发,并合理布局游戏界面,使游戏界面更加美观和人性化,实现了游戏的基本功能,最终可以让玩家享受拼图游戏的乐趣。

关键词:Android;拼图游戏;Activity;架构

III

金陵科技学院学士学位论文 Abstract

The development and features of Android

Abstract

Key words: Android;Jigsaw puzzle game;Activity;sturcture

IV

金陵科技学院学士学位论文 第1章 绪论

1 绪 论

1.1 课题开发的背景

随着嵌入式技术的发展,手持终端设备也迅速发展起来,目前,全球手机用户数已超过了PC机用户数,其中智能手机的比例越来越高。智能手机是指像电脑一样可以通过下载、安装软件来拓展基本功能的手机,一般具有智能手机操作系统。相较于非智能手机,它功能更强,处理速度更快。基于Linux的Android手机操作系统,由于具有开源、免费的特性,迅速得到广大爱好者及厂商的支持。目前,移动应用软件中的手机游戏开发是一项非常热门的技术。

Android系统对第三方软件是开放的,这促进了第三方软件的发展。Android系统以Linux 2.6为核心,其安全机制比较完善,增强了手机使用的安全性。Android平台已经形成由 Google牵头,OHA组织参与,系统支持商和服务供应商完善搭配的运作机制,为Android平台的快速发展提供了坚实的基础。

由于Android构建在开源代码的框架之上,并且提供了强大的SDK库和开放的理念,所以它为广大的没有任何移动应用程序开发经验的新手开辟了一条开发完美移动应用程序的康庄大道。而富有经验的移动开发人员现在也可以方便地扩展到Android平台上来,利用它独特的功能来改进现有产品或者开发其他新颖产品。

1.2 课题意义

Android软件在一两年的时间内已经迅速发展,在各类型应用系统中都有令用户满意的成果,本课题研究的就是基于此背景下Android手机的一款益智拼图游戏。通过该游戏的设计,将自己学到的Java,Android方面的理论知识应用于实践,提高自己的动手能力。在设计的过程中,不断的修补知识方面的漏洞,加深自己对程序设计的理解,为将来从事软件开发事业打下基础。

1

金陵科技学院学士学位论文 第2章 Android架构与开发平台搭建 2 Android架构与开发平台搭建

2.1 Android的系统架构

Android的系统架构和其操作系统一样,采用了分层的架构。从图2.1中可以看出,Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux核心层。

图2.1 Android系统架构图

(1) 应用程序

Android会同一系列核心应用程序包一起发布,该应用程序包包括Email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。

(2) 应用程序框架

开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。同样,该应用程序重用机制也使用户可以方便的替换程序组件。

2

金陵科技学院学士学位论文 第2章 Android架构与开发平台搭建 隐藏在每个应用后面的是一系列的服务和系统, 其中包括;

丰富而又可扩展的视图(Views):可以用来构建应用程序,它包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons),甚至可嵌入的web浏览器。

内容提供器(Content Providers):使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据。

资源管理器(Resource Manager):提供非代码资源的访问,如本地字符串,图形,和布局文件(layout files)。

通知管理器(Notification Manager):使得应用程序可以在状态栏中显示自定义的提示信息。

活动管理器(Activity Manager):用来管理应用程序生命周期并提供常用的导航回退功能。

(3) 系统运行库 1) 程序库

Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android应用程序框架为开发者提供服务。以下是一些核心库:

系统C库:一个从BSD继承来的标准C系统函数库(libc), 它是专门为基于embedded linux的设备定制的。

媒体库:基于PacketVideo OpenCORE,该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4,H.264,MP3,AAC,AMR,JPG,PNG。

Surface Manager:对显示子系统的管理,并且为多个应用程序提供了2D和3D图层的无缝融合。

LibWebCore:一个最新web浏览器引擎用,支持Android浏览器和一个可嵌入的web视图。

SGL:底层的2D图形引擎。

3D libraries:基于OpenGL ES 1.0 APIs实现;该库可以使用硬件3D加速(如果可用)或者使用高度优化的3D软加速。

FreeType:位图(bitmap)和矢量(vector)字体显示。

SQLite:一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。 2) Android 运行库

Android包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。 每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟 机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK的\dx\工具转化成.dex格式

3

金陵科技学院学士学位论文 第2章 Android架构与开发平台搭建 由虚拟机执行。

Dalvik虚拟机依赖于Linux内核的一些功能,比如线程机制和底层内存管理机制。 (4) Linux内核

Android的核心系统服务依赖于Linux 2.6内核,如安全性,内存管理,进程管理,网络协议栈和驱动模型。Linux内核也同时作为硬件和软件栈之间的抽象层。

2.2 Window下Android开发环境的搭建

为了在PC主机上得到Android的开发环境,我们选择在Windows操作系统中进行对Android开发环境的搭建,具体步骤如下:

(1)JDK安装

首先下载JDK,按照提示安装成功后,最重要的是进行环境变量的配置,步骤如下:我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量:

Java_HOME值为:C:\\Program Files\\Java\\jdk1.6.0_20(安装JDK的目录)

CLASSPATH值为:.;%Java_HOME%lib\\tools.jar;%Java_HOME%\\lib\\dt. jar;%Java _HOME%\\bin;

Path值:添加C:\\Program Files\\Java\\jdk1.6.0_20\\bin;

(2)Eclipse安装可下载一个绿色版的Eclipse,无需安装,和安装版一样都能为Android开发提供功能。

(3)Android SDK安装在Android Developers下载Android-sdk_r07-windows.zip,下载完成后解压到任意路径。

运行SDK Manager.exe,出现如图以下界面,点击Available Package。选择希望安装的SDK及其文档或者其它包,点击Installation Selected、Accept All、Install Accepted,开始下载安装所选包。

下载完成后出现如下图的所有Android-sdk_r07-windows文件夹内容; (4)ADT安装

ADT实际上是一个工具,它可以连接sdk和Eclipse,帮助Eclipse找到sdk打开Eclipse界面,进入进入菜单中的“Help”-> “Install New Software”,点击Add按钮弹出对话框要求输入Name和Location,完成之后,选择Window >Preferences;在左边的面板选择Android,然后在右侧点击Browse;并选中SDK路径,本机为;D:\YJSH\Android\Android-sdk_r07-windows;点击Apply、OK。配置完成。

(5)创建AVD

为使Android应用程序可以在模拟器上运行,必须创建AVD,步骤如下:

在Eclipse中,选择Windows > Android SDK and AVD Manager,点击左侧面板的Virtual Devices,再右侧点击New,填入Name,选择Target的API,SD Card大小任意,Skin随便选,Hardware目前保持默认值,点击CreateAVD即可完成创建AVD。

4

金陵科技学院学士学位论文 第3章 流程介绍与概要设计

3 流程介绍与概要设计

3.1 游戏流程介绍

根据拼图游戏的游戏规则,本设计拟出游戏的大致流程如图3.1所示:

点击“益智拼图”进入选择界面已进入点击下拉列表,完成难度选择点击图片框中的一张图片点击“确定”进入游戏界面已进入点击play按钮,时间开始计时未进入选择界面点击图块并拖动未进入游戏界面每拖一次,步数加1图片拼成原样,游戏结束游戏失败

图3.1 拼图游戏流程图

5

金陵科技学院学士学位论文 第3章 流程介绍与概要设计

3.2 系统概要设计

本设计参考了拼图游戏流程图(图3.1)按照自顶向下的设计方式将拼图游戏分为以下模块进行设计,如图3.2所示:

益智拼图游戏界面布局模块游戏功能模块难度选择模块图片选择模块步数,时间设置模块游戏实现模块 图3.2 拼图游戏模块

3.2.1 界面布局模块

由于本课题的题材是一款游戏,对于游戏的界面以及一些基本控件有必要介绍一下。本系统一共有两个界面:一个选择界面,一个游戏界面,基本的控件有文本框,下拉列表,网格视图,按钮,图片视图等。下面简单介绍下它们的作用:

文本框主要是用来显示一些文本,这些文本基本是描述文本框所在位置的功能。 下拉列表主要用在了难度选择部分,当玩家点击难度时,会出现下拉列表。 网格视图主要用于图片选择部分,利用网格视图将图片一一列出,供玩家选择图片进行游戏。

按钮是两个界面的链接枢纽,在第一个选择界面按下确定按钮,会跳转到游戏界面。在游戏界面也设置了一个按钮,主要是给玩家提供“重新游戏”的机会。

图片视图只要用来显示图片,在游戏界面用图片视图显示图片,供玩家游戏。

3.2.2 难度选择模块

拼图游戏的难度在于图片被分割后的块数,数量越多,自然难度就越大。 (1)难度最小的是将其设置为3*3

当难度设置为3*3时,系统将图片分割为3行3列,也就是将图片分成了9块。 (2)难度最大的是将其设置为4*4

当难度设置为4*4时,系统将图片分割成4行4列,也就是将图片分成了16块。 (3)难度中等的设置有两种:3*4 和4*3

当难度设置为3*4时,系统将图片分割成3行4列,即分成了12块。

6

金陵科技学院学士学位论文 第3章 流程介绍与概要设计

当难度设置为4*4时,系统将图片分割成4行3列,同样分成了12块。

3.2.3 图片选择模块

图片选择步骤相当简单,只要在选择界面的图片选择区域,从9张图片中鼠标单击1张玩家感兴趣的图片即可。

3.2.4 步数和时间模块

拼图游戏过程中,为了增加趣味性,玩家每移动一次图块,步数加一,知道游戏全部位置正确,游戏结束,统计最后步数;从游戏开始,时间模块开始计时,直到游戏结束,时间停止,并显示玩家完成游戏所花的时间。

3.2.5 游戏实现模块

在完成上述的图片选择,难度选择后就可以开始正式的拼图游戏。

玩家选择“play”后,图片会根据玩家选择的难度随机分解图片。在本设计中,原图分割后右下角设置为空白块,为图块的移动提供可能。玩家用鼠标点击与空白块相邻的图块,并将选中的图片往空白块拖动,这样就完成了空白块与选中图片的位置的互换。这样子循环往复,知道全部图块位置正确,游戏就结束了。

7

金陵科技学院学士学位论文 第4章 系统详细设计与实现

4 系统详细设计与实现

4.1 界面布局实现

本设计有两个界面:选择界面和游戏界面。界面的设计主要运用Android的绘图技术,图形的绘制通常是在View类中完成的,同时也会用到各种控件,如:TextView,Button,Spinner,GridView,ImageView。当然说到控件,容器就不得不提了,两者是息息相关的。本设计中用到了最常用的LinearLayout容器,控件的布局也用到了相对布局,绝对布局等。

4.1.1 选择界面布局

选择界面在main.xml文件中布局,界面效果如图4.1.1 :

图4.1.1 选择界面

该界面采用LinearLayout布局,在LinearLayout标签中完成界面设置。

布局设置:设置布局排列方式为竖直排列,宽和高的值为填满,背景颜色为黑色。代码如下:

android:orientation=\

8

金陵科技学院学士学位论文 第4章 系统详细设计与实现

android:layout_width=\

android:layout_height=\

下面给出构成该界面的一些基本控件的设置代码:

设置文本框的高和宽根据内容调整,文本内容从values文件夹中的strings.xml文

件中读取,内容为“等级”:

android:layout_width=\ android:layout_height=\ android:text=\

style=\ 设置下拉列表的高和宽根据内容调整: android:layout_width=\ android:layout_height=\

设置文本框高根据内容调整,宽为填满,文本内容取自values文件夹下strings.xml

文件,内容为选择图片区:

android:layout_width=\ android:layout_height=\ android:text=\ style=\

android:background=\ 设置网格视图宽和高为填满: android:layout_width=\ android:layout_height=\

设置按钮属性,宽和高为根据内容调整,按钮内容取自values文件夹的strings.xml文件,内容为“确定”:

android:layout_width=\

android:layout_height=\ android:text=\ style=\ android:layout_gravity=\

4.1.2 游戏界面布局

游戏界面在jigsaw.xml文件中布局,界面效果如图4.1.2:

9

金陵科技学院学士学位论文 第4章 系统详细设计与实现

图4.1.2 游戏界面

该界面同样采用LinearLayout布局,在LinearLayout标签中进行基本设置。 布局设置:高和宽为填满,排列方式为竖直排列,背景颜色为黑色。代码如下: android:layout_width=\ android:layout_height=\ android:orientation=\

android:background=\

下面给出游戏界面其他控件的设置内容和相关代码:

设置文本框的高和宽根据内容调整,文本框的内容取自strings.xml,内容为“预

览”,位置居中: android:layout_width=\ android:layout_height=\ android:text=\ style=\ android:layout_gravity=\

设置图片框高和宽根据内容调整,图片取自drawable文件下的pingtu_6 : android:layout_width=\

android:layout_height=\ android:src=\

10

金陵科技学院学士学位论文 第4章 系统详细设计与实现

设置文本框高和宽根据内容调整,文本框内容取自strings.xml中的level2,内容为

“等级”:

android:layout_width=\ android:layout_height=\ android:text=\

style=\

设置文本框高和宽根据内容调整,文本框内容取自strings.xml中的stepNum,内容为“步数”:

android:layout_width=\ android:layout_height=\ android:text=\ style=\

设置文本框高和宽根据内容调整,文本框内容取自strings.xml中的time,内容为“时

间”:

android:layout_width=\ android:layout_height=\ android:text=\

style=\

设置按钮高和宽根据内容调整,文本框内容取自strings.xml中的play,内容为“play” android:layout_width=\ android:layout_height=\ android:text=\ android:textSize=\

4.2 游戏功能实现

游戏代码具体运行流程是这样的:游戏启动后,启动MainActivity,接着加载main.xml初始化选择界面,在完成难度选择和图片选择后,点击“确定”按钮,运行MainActivity类中的监听器btnOnClickListener跳转在JigsawActivity,并加载jigsaw.xml文件初始化游戏界面,然后根据界面上的内容进行游戏。

整个设计过程中主要完成以下功能:难度选择,图片选择,步数和计时功能,拼图功能。

4.2.1 难度选择

在选择界面点击“等级”后的下拉列表,跳出下拉列表框,供玩家选择难度,在 MainActivity中导入MainImpl类和IMain类用于实现难度选择。MainImpl类中定义了 getLevelAdapter方法,使用List()将四种难度等级存入列表,以供选择。

getLevelAdapter方法的代码如下:

public ArrayAdapter getLevelAdapter(Context context) { 11

金陵科技学院学士学位论文 第4章 系统详细设计与实现

List list=new ArrayList();

String[] level=context.getResources().getStringArray(R.array.levelArray); for(String str:level){

list.add(str); }

ArrayAdapter cityArrayAdapter=new

ArrayAdapter(context,android.R.layout.simple_spinner_item,list); cityArrayAdapter.setDropDownViewResource(android.R.layout.simple_ spinner_dropdown_item); return cityArrayAdapter; }

在MainActivity中给难度选择定义两个监听器ItemClickListener,玩家单击下拉列表,就会启动ItemClickListener,玩家点击四个难度中的一种后又会启动另一个监听器 ItemSelectedListener。玩家选择完,选择的难度将会传回Activity。

监听器的简单代码如下:

private class ItemSelectedListener implements OnItemSelectedListener{ }

public void onItemSelected(AdapterView adapterView, View view, int position, long rowid) { pictureIndex=position; }

public void onNothingSelected(AdapterView arg0) { }

4.2.2 图片选择

选择界面会列举出9种图片供玩家选择。图片列举功能是由MainActivity中的 showGridView方法和getAllItemsForListView方法完成的。showGridView方法获取屏幕大小,根据screenWidt和screenHeight自动调整图片大小,保证界面的美观。而getAllItemsForListView方法生成动态数组imageItem,并且传入数据,将图片一一列举出来。玩家点击一张图片并按下“确定”按钮时,将选择的图片同时传递给JigsawActivity。代码如下:

private void showGridView(){ DisplayMetrics dm = new DisplayMetrics();

dm = this.getApplicationContext().getResources().getDisplayMetrics(); pictureGridView.setColumnWidth((screenWidth-10*4)/3); SimpleAdapter saImageItems = new SimpleAdapter(this, getAllItemsForListView(), R.layout.grid_item, new String[] { \ new int[] { R.id.gridItem_imgView}); pictureGridView.setAdapter(saImageItems); pictureGridView.setSelector(R.drawable.menuitemshape);

12

金陵科技学院学士学位论文 第4章 系统详细设计与实现

}

列出9张图片,并选择一张图片进行游戏是在getAllItemsForListView()方法中实现的,

在该方法中生成了动态数组imageItem,将各个图片的序号传入了数组中。 public List> getAllItemsForListView() { List> imageItem = new ArrayList>(); for (int i=0;i tempMap = new HashMap(); tempMap.put(\ imageItem.add(tempMap); } return imageItem;

}

4.2.3 步数和时间设置

在JigsawActivity的initControls分别给stepNumTV和timeTV做出定义。玩家点击界面上的“play”按钮,启动onClick方法,该方法开始给步数和时间赋初值。关于时间设置,还给出了时间的分秒设置。这是在timeParser方法中实现的,每过60秒,分钟加1。游戏过程中图片移动一次,步数加1。具体实现如下:

在游戏过程中,秒数一直在加一,这一实现体现在GameRunable 类中的run方法中。当然在秒数加1之前要先判断是否为游戏状态,代码为: public void run() { while(isGaming){ try { second++; Message msg=new Message(); msg.what=TIME_MESSAGE; mHandler.sendMessage(msg); Thread.sleep(1000); // } catch (InterruptedException e) { e.printStackTrace(); } }

步数和时间的运行都是handleMessage方法中实现,在该方法中通过switch—case语句实现判断。

public void handleMessage(android.os.Message msg){ switch(msg.what){ case TIME_MESSAGE: break; case INIT_MESSAGE: break; }

13

金陵科技学院学士学位论文 第4章 系统详细设计与实现

super.handleMessage(msg); }

4.2.4 拼图的实现

在JigsawActivity中进行游戏时首先要解决的问题就是图片的随机分割问题。该问题的解决方案在JigsawView类中,JigsawActivity只是导入了该类。在该类中定义了相当多的变量,具体如下: private Bitmap[] oBitamp;//初始化切割后的图片输数组 private int row=2;//行 private int col=2;//列 private int cutBitmapWidht;//切割后每张位图的宽 private int cutBitmapHeight;//切割后每张位图的高 private float x,y;//当然触发的X,Y坐标 private int offsetW,offsetH;//偏移量宽度\\高度 private int maxRectW,maxRectH;//最大矩形宽,高 private PointF downPoint=new PointF();//触发的坐标点 private PointF currPoint=new PointF();//当前坐标点 private int step=0;//步数

private boolean isGameing=false;//是否游戏中

该问题的解决涉及到随机和分割两个算法。关于随机的问题,算法中使用了randomGenerated 方法,该方法随机生成0-n范围内不重复的数字,不包含n。在Math类中有定义的random方法,因此只需要调用以下。代码如下: private void randomGenerated(int n){ Vector vector=new Vector(); int[] num=new int[n]; for(int i=0;i

14

金陵科技学院学士学位论文 第4章 系统详细设计与实现

cutBitmap(mBitmap); }

分割图片是通过cutBitmap方法实现的,定义了cutBitmaoWidth,cutBitmapHeight变量

表示分割后图片的宽和高,并根据难度选择的行数和列数初始化分割后的图片数数组。具体代码如下:

private void cutBitmap(Bitmap srcBitamp){ cutBitmapWidht=srcBitamp.getWidth()/row; //分割后每张位图的宽。 cutBitmapHeight=srcBitamp.getHeight()/col; //分割后每张位图的高。 offsetW=cutBitmapWidht; //偏移量宽度。 offsetH=cutBitmapHeight; //偏移量高度。 oBitamp=new Bitmap[row*col]; //初始化切割后的图片数数组。 for(int i=0;i

}

用randomGenerated 方法解决了图片随机分割的问题之后,接着就是游戏的运行即交换图片功能的实现。首先确保鼠标点击并拖动图片有效,然后实现图片的交换。为确保鼠标点击和拖动有效,定义onTouchEvent方法进行活动的判断,该方法中定义了x,y两个变量表示坐标,来显示鼠标点击的位置。

onTouchEvent方法中定义了如下两个变量: x=event.getX(); y=event.getY(); 通过如下语句实现判断鼠标的活动:按下(MotionEvent.ACTION_DOWN),离开(MotionEvent.ACTION_UP),移动(MotionEvent.ACTION_MOVE)。 if(!((x<=maxRectW)&&(y<=maxRectH))){ return false; } switch(event.getAction()){ case MotionEvent.ACTION_DOWN:{ } case MotionEvent.ACTION_UP:{

15

金陵科技学院学士学位论文 第4章 系统详细设计与实现

}

case MotionEvent.ACTION_MOVE:{ } }

return super.onTouchEvent(event); }

交换图片的动作由swapPicture方法实现,交换代码简单如下: int value;

value=picture1.value; picture1.value=picture2.value;

picture2.value=value;

16

金陵科技学院学士学位论文 第5章 系统测试

5 系统测试

5.1 Android仿真器介绍

仿真器是在计算机中运行的一个虚拟的移动装置,用它来设计、调试应用。 ADT是一个用于开发Android应用的eclipse插件,它方便了我们的开发。例如,它让我们方便从eclipse内部访问DDMS工具(可用于截屏,管理port-forwarding,设断点,查看线程和进程信息)

DDMS(Dalvik Debug Monitor Service)和Dalvik虚拟机集成,将在IDE和模拟器起到一个转发服务。用它能管理仿填器或者设备的进程,并且辅助调试。你可用它杀死进程,选择某一进程去DEBUG,产生TRACE数据,查看堆和线程信息等等。

Aapt(Andvoid Asset Packaging Tool),用于创建.apk文件。 Aidl(Andvoid Interface Description Language)用于产生代码。 Sqlite3用于访问SQLite数据文件。 Traceview用于查看LOG信息

Dx工具用于重写.class字节码到Andvoid字节码。

ActivityCreator用于产生ant文件的脚本。当然,若用eclipse插件就不需要它了。

5.2 功能模块测试

在虚拟器上完成一次拼图游戏,即可测试出本设计是否已经完成。下面给出各个功能模块的测试过程,若这些功能在模拟器上都能得到体现,则说明本设计基本成功。

1) 难度选择模块:

在选择界面点击“等级”下拉框,选择一个难度,按下“确定”按钮后跳转到游戏界面,在游戏界面的文本框“等级”下显示出玩家选择的难度。

界面如下:

17

金陵科技学院学士学位论文 第5章 系统测试

图5.2.1 难度选择模块

2) 图片选择模块:

在选择界面点击一张图片,按下“确定”按钮后跳转到游戏界面,在游戏界面的图片框中显示玩家选择的图片。

界面如下:

18

金陵科技学院学士学位论文 第5章 系统测试

图5.2.2 图片选择模块

3) 步数和时间设置模块:

在游戏界面,点击“play”按钮后,时间开始自加1秒,每移动一个图块,步数一栏加1 。

界面如下:

图5.2.3 步数和时间设置模块

4) 游戏实现模块:

在游戏界面,点“play”按钮后,鼠标点击图块并拖动,能与空白图块交换位置。当图片拼成原样时,弹出窗口提示游戏结束。

界面如下:

19

金陵科技学院学士学位论文 第5章 系统测试

图5.2.4 游戏实现模块

5.3 出现的错误及解决方案

完成系统的过程中不可避免的出现了一些问题,通过自我学习和他人指导,最终解决了这些问题。具体错误和解决方案如下表5.1:

表5.1 错误及解决方案对照表

系统出现的错误 解决方案 Activity之间的界面跳转无法实现 各个控件之间的链接出错 运行游戏时,系统报错,无法正常游戏 在Activity.java中给出界面跳转到下一个Activity必须的代码实现。 在同一个界面中的控件之间的联系可以通过在Activity.java中编写代码来实现。 检查SDK版本以及仿真器的配置。 20

金陵科技学院学士学位论文 第6章 总结与展望

6 总结与展望

大学四年学习的编程思想和编程技巧,在最后的毕业设计当中得到了运用。经过此次毕业设计,充分认识到了自己编程能力方面的缺陷,感觉到自己的基础比较薄弱。但在这段时间里,我不断地发现自己的问题,并且找出问题产生的原因,根据相关的方法解决问题。几个月的努力没有白费,终于基本上完成拼图游戏的功能,虽然还有不少不足,我将不断的完善它。

做一个完整的系统之前,必须先对该系统进行需求分析,拟好系统需要达到的功能和系统的所有需求,并且画出系统的大体设计流程图和框架。做完这些准备工作,做系统的时候才会得心应手。想到那里就做到那里,不仅效率不高,还会影响到系统的可用性。

完成系统之后才发现,对于软件设计,要想做到得心应手,必须多多练习。只有写够足够多的代码,才能真正理解软件设计的思想及运用。当然要做到这一步,要付出相当多的努力,在没有做到之前,遇到不懂的地方就要多参考资料,请教别人。

21

金陵科技学院学士学位论文 参考文献

参考文献

[1] (美)Eric J.Baucle.软件设计——从程序设计到体系结构[M].李仁发等译.北京: 电子工业出版社,2007.

[2] 孔令德.毕业设计案例教程——从系统开发到论文写作[M].北京:国防工业出版社,2007.

[3] (美)威尔顿,麦可匹克.JavaScript入门经典(第3版)[M].北京 施宏斌译.北京:清华大学出版社,2009.

[4] E2ECloud工作室.深入浅出Google Android[M].北京:人民邮电出社,2009.08. [5] 余志龙等.Android SDK开发范例大全[M].北京:人民邮电出版社.2009. [6] 姚尚朗,靳岩.Google Android开发入门与实践 [M].北京:人民邮电出版社,2009. [7] 余志龙等.Google Android SDK开发范例大全(第二版)[M].北京:人民邮电出版社,2010.

[8] 李船戊.智能手机原理与未来发展[J].科技与生活,2010,第1卷5(期). [9] (美)墨菲.Android开发入门教程[M].北京:人民邮电出版社,2010. [10] 郭宏志.Android应用开发详解[M].北京:电子工业出版社,2010.

[11] 熊刚.基于Android的智能手机的设计与实现[D].武汉:武汉理工大学,2010. [12] 贾理华,乐燕芬,施伟斌.基于Android平台简易即时通讯的研究与设计[J].常州工学院学报,2010,第56卷28(期).

[13] 杨丰盛.Android应用开发揭秘[M].北京:机械工业出版社,2010. [14] 李宁.Android开发权威指南[M].北京:人民邮电出版社,2011.

[15] 吴亚峰.Android编程典型实例与项目开发[M].北京:电子工业出版社,2011.

22

附录 附 录

拼图游戏主要代码:

1)选择界面MainActivity代码 package com.angelnet.jigsaw.view; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;

import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog;

import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle;

import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View;

import android.widget.AdapterView; import android.widget.Button; import android.widget.GridView;

import android.widget.SimpleAdapter; import android.widget.Spinner;

import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import com.angelnet.jigsaw.model.service.IMain; import com.angelnet.jigsaw.model.service.MainImpl; public class MainActivity extends Activity { private int screenWidth=0;//屏幕的宽度 private int screenHeight=0;//屏幕的高度 private Spinner levelSp;//等级 private GridView pictureGridView;//图片 private Button confBtn; private static final int[]

pictureArray={R.drawable.pingtu_1_1,R.drawable.pingtu_2_2,R.drawable.pingtu_3_3, R.drawable.pingtu_4_4,R.drawable.pingtu_5_5,R.drawable.pingtu_6_6, R.drawable.pingtu_7_7,R.drawable.pingtu_8_8,R.drawable.pingtu_9_9}; private static final int AUTHOR_INFO_ID=Menu.FIRST;//作者简介 private static final int ABOUT_ID=Menu.FIRST+1;//关于 private static final int EXIT_ID=Menu.FIRST+2;//退出 private IMain iMain;

23

附录 private int pictureIndex=0; @Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initControls(); showGridView(); }

private void initControls(){ iMain=new MainImpl();

levelSp=(Spinner)findViewById(R.id.main_level_spinner);

pictureGridView=(GridView)findViewById(R.id.main_picture_gridView); pictureGridView.setOnItemClickListener(new ItemClickListener());//监听

pictureGridView.setOnItemSelectedListener(new ItemSelectedListener());//选择监听 levelSp.setAdapter(iMain.getLevelAdapter(this));

confBtn=(Button)findViewById(R.id.main_confirm_btn); confBtn.setOnClickListener(btnOnClickListener); }

@Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub menu.add(0, AUTHOR_INFO_ID, 0, R.string.author).setShortcut('1', 'i').setIcon(R.drawable.author_info); menu.add(0, ABOUT_ID, 0, R.string.about).setShortcut('2', 'a').setIcon(R.drawable.about);

menu.add(0, EXIT_ID, 0, R.string.exit).setShortcut('4', 'e').setIcon(R.drawable.exit); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub switch(item.getItemId()){ case AUTHOR_INFO_ID:{ onCreateDialog(AUTHOR_INFO_DIALOG).show(); return true; } case ABOUT_ID:{ onCreateDialog(ABOUT_DIALOG).show(); return true; } case EXIT_ID:{ exitApp(); return true; }

24

附录 }

return super.onContextItemSelected(item); }

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub

if(keyCode==KeyEvent.KEYCODE_BACK){ exitApp(); return true; }

return super.onKeyDown(keyCode, event); }

private static final int ABOUT_DIALOG=1;

private static final int AUTHOR_INFO_DIALOG=2; @Override

protected Dialog onCreateDialog(int id) { // TODO Auto-generated method stub switch (id) {

case ABOUT_DIALOG:{ AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setIcon(R.drawable.alert_dialog_icon); builder.setTitle(R.string.about); builder.setMessage(R.string.aboutInfo); builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); return builder.create(); }

case AUTHOR_INFO_DIALOG:{ AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setIcon(R.drawable.alert_dialog_icon); builder.setTitle(R.string.author); builder.setMessage(R.string.authorInfo); builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); return builder.create(); } }

return super.onCreateDialog(id);

25

附录 } /** * 显示就九空格 */ private void showGridView(){ //获取屏幕大小 DisplayMetrics dm = new DisplayMetrics();

dm = this.getApplicationContext().getResources().getDisplayMetrics(); screenWidth = dm.widthPixels; screenHeight = dm.heightPixels; //两列之间的边距为10

pictureGridView.setColumnWidth((screenWidth-10*4)/3); SimpleAdapter saImageItems = new SimpleAdapter(this, getAllItemsForListView(), R.layout.grid_item, new String[] { \ new int[] { R.id.gridItem_imgView}); pictureGridView.setAdapter(saImageItems); pictureGridView.setSelector(R.drawable.menuitemshape); } public List> getAllItemsForListView() { // TODO Auto-generated method stub // 生成动态数组,并且传入数据 List> imageItem = new ArrayList>(); for (int i=0;i tempMap = new HashMap(); // Bitmap bitamp=BitmapFactory.decodeResource(this.getResources(), pictureArray[i]); tempMap.put(\ imageItem.add(tempMap); } return imageItem; } /** * 当AdapterView被单击(触摸屏或者键盘),则返回的Item单击事件 * */ private class ItemClickListener implements OnItemClickListener { /** * @param adapterView * The AdapterView where the click happened * @param arg1 * The view within the AdapterView that was clicked * @param position * The position of the view in the adapter

26

附录 * @param rowid * The row id of the item that was clicked */ public void onItemClick(AdapterView adapterView, View view,int position, long rowid){ // 在本例中position=rowid pictureIndex=position; } } /** * 选择监听 */ private class ItemSelectedListener implements OnItemSelectedListener{ @Override public void onItemSelected(AdapterView adapterView, View view, int position, long rowid) { // TODO Auto-generated method stub // HashMap item = (HashMap) adapterView.getItemAtPosition(position); pictureIndex=position; } @Override public void onNothingSelected(AdapterView arg0) { // TODO Auto-generated method stub } } /** * 退出应用程序 */ private void exitApp(){ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setIcon(R.drawable.question_dialog_icon); builder.setTitle(\退出\ builder.setMessage(\您确定要退出益智拼图吗?\ builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { MainActivity.this.finish(); } }); builder.setNegativeButton(\取消\ @Override

27

附录 }

public void onClick(DialogInterface dialog, int which) { } });

builder.create().show(); }

private View.OnClickListener btnOnClickListener=new View.OnClickListener() { @Override

public void onClick(View v) {

// TODO Auto-generated method stub switch (v.getId()) {

case R.id.main_confirm_btn: Bundle extras=new Bundle(); extras.putInt(\ extras.putInt(\ Intent intent=new Intent(MainActivity.this, JigsawActivity.class); intent.putExtras(extras); startActivityForResult(intent, 1); break; } } };

2)游戏界面JigsawActivity代码:

package com.angelnet.jigsaw.view; import android.app.Activity; import android.graphics.Bitmap;

import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView;

import com.angelnet.jigsaw.model.widgets.JigsawView; public class JigsawActivity extends Activity { private ImageView previewImgView; private JigsawView mJigsawView; private TextView levelTV; private TextView stepNumTV; private TextView timeTV;

28

附录 private Bitmap mBitmap; private Button startBtn; private boolean isGaming=false; private boolean isFirstThread=false; private boolean isPlay=false; /** * 第一次运行该Activity时,就要运行onCreate方法 * */ @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.jigsaw); initControls(); } private void initControls(){ Bundle extras=this.getIntent().getExtras(); int level=extras.getInt(\ int pictureIndex=extras.getInt(\ previewImgView=(ImageView)findViewById(R.id.jigsaw_preview_imgview); mJigsawView=(JigsawView)findViewById(R.id.main_JigsawView); if(0==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_1); }else if(1==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_2); }else if(2==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_3); }else if(3==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_4); }else if(4==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_5); }else if(5==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_6); }else if(6==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_7); }else if(7==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_8); }else if(8==pictureIndex){

mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pingtu_9); }

levelTV=(TextView)findViewById(R.id.jigsaw_level_tv); if(level==0){

mJigsawView.setRowCol(3, 3); levelTV.setText(\

29

附录 }else if(level==1){

mJigsawView.setRowCol(3, 4); levelTV.setText(\ }else if(level==2){

mJigsawView.setRowCol(4, 3); levelTV.setText(\ }else if(level==3){

mJigsawView.setRowCol(4, 4); levelTV.setText(\ }

previewImgView.setImageBitmap(mBitmap); mJigsawView.setBitamp(mBitmap);

stepNumTV=(TextView)findViewById(R.id.jigsaw_stepNum_tv); stepNumTV.setText(String.valueOf(mJigsawView.getStep())); timeTV=(TextView)findViewById(R.id.jigsaw_time_tv); timeTV.setText(timeParser(second));

startBtn=(Button)findViewById(R.id.jigsaw_start_btn); startBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //开始游戏 if(!isPlay){ isPlay=true; }else{ mJigsawView.setBitamp(mBitmap); } isGaming=true; second=0; mJigsawView.setStep(0); mJigsawView.setGameing(isGaming); startBtn.setText(\ if(!isFirstThread){ isFirstThread=true; new Thread(new GameRunable()).start(); } Message msg=new Message(); msg.what=INIT_MESSAGE; mHandler.sendMessage(msg); } }; } /** *

30

附录 * @param totalSecond * @return */

private String timeParser(int totalSecond) { StringBuffer sb = new StringBuffer(); int minute = totalSecond / 60; sb.append(minute); sb.append(\

int second = totalSecond % 60; if (second >= 10)

sb.append(second); else

sb.append(\ return sb.toString(); }

private int second=0;

class GameRunable implements Runnable{ public void run() {

// TODO Auto-generated method stub while(isGaming){ try { second++; Message msg=new Message(); msg.what=TIME_MESSAGE; mHandler.sendMessage(msg); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

private static final int INIT_MESSAGE=1; private static final int TIME_MESSAGE=2; Handler mHandler=new Handler(){ @Override

public void handleMessage(android.os.Message msg){ switch(msg.what){ case TIME_MESSAGE: stepNumTV.setText(String.valueOf(mJigsawView.getStep())); timeTV.setText(timeParser(second)); isGaming=mJigsawView.isGameing(); if(!isGaming) isFirstThread=false;

31

附录 break; case INIT_MESSAGE: stepNumTV.setText(String.valueOf(mJigsawView.getStep())); timeTV.setText(timeParser(second)); mJigsawView.invalidate(); break; }

super.handleMessage(msg);

}

}

32

致谢

致 谢

四年的大学生活即将步入尾声,我们的校园生活就要划上句号,心中非常的不舍和眷恋。出了大学校门,我就将开始新的人生旅程。

毕业设计是我大学生涯的最后一个作业了,借此机会首先要感谢培养我四年的金陵科技学院,特别是曾经教导过我们的老师们,感谢他们对我的教育,指导和关心。有了他们的支持,我才能顺利完成四年的大学学习生涯。

首先,我要感谢学院为我提供了一次良好的锻炼环境,完成此次设计,对提高我的个人能力有相当大的好处,能够提高自身软件开发能力,以便我适应将来的编程工作。

由于我在做毕业设计的同时,已经开始在公司上班实习。在公司学习到的编程知识刚好强化了我薄弱的编程能力。由于离校的原因不能及时了解学校关于毕业设计工作的最新动态,幸好我的指导老师李莉老师秉着认真负责的态度,及时与我沟通,通知我学校的最新安排。并且针对我毕业设计过程中出现的一些问题,提出中肯的修改意见,以便我能一次性通过学校的审查。在此,我对李老师的认真负责的指导表示衷心的感谢。

其次,我还要感谢帮助过我的同学,同事。他们为我解决了不少我不太明白的设计上的难题。没有他们的帮助,只靠我一个人来摸索的话,估计还会走不少弯路。

回首大学生活的喜怒哀乐,感慨良多。曾经一起走过的老师们,同学们,感谢你们的帮助和关心,没有你们的陪伴,我的毕业设计将会遇到更多更难得问题,谢谢你们!

33