收藏 分销(赏)

毕业设计论文-基于android的祖玛游戏开发与设计.docx

上传人:鼓*** 文档编号:9869448 上传时间:2025-04-11 格式:DOCX 页数:41 大小:1.45MB
下载 相关 举报
毕业设计论文-基于android的祖玛游戏开发与设计.docx_第1页
第1页 / 共41页
毕业设计论文-基于android的祖玛游戏开发与设计.docx_第2页
第2页 / 共41页
点击查看更多>>
资源描述
毕 业 设 计(论 文) 论文题目:基于Android的祖玛游戏开发与设计 摘 要 伴随着移动设备的发展,手机已经进入了社会的各个角落。随着Android系统的横空出世,由于它具有开源化的巨大优势,从而Android手机游戏的发展已经成为了手机行业发展的龙头。 本文详细地介绍了使用JAVA开发语言与Android技术开发祖玛游戏的设计过程。首先系统地介绍了现有游戏的现状和所用的语言和技术,然后提出了本游戏的需求分析,确定了开发游戏的总体流程,接下来,详细地描述了开发环境的搭建以及游戏的设计和程序的编写过程,重点介绍了小球的发射、小球的爆炸等关键技术,并对最终成果进行展示。最后对本次游戏的开发进行了总结并提出一些不足并细谈了对手机游戏未来的展望。 关键词 手机;Android系统;手机游戏 目录 第一章 绪言 1 第一节 课题目的及意义 1 第二节 研究现状 1 第二章 祖玛游戏的需求分析 3 第一节 需求概述 3 第二节 功能需求 3 第三节 数据需求 4 第四节 开发语言的介绍 4 第三章 祖玛游戏的总体设计 6 第一节 游戏框架设计 6 第二节 游戏的流程设计 6 第三节 游戏模块设计 8 第四章 祖玛游戏的详细设计与实现 9 第一节 开发环境的搭建 9 第二节 游戏的引擎创建 14 第三节 游戏显示界面的创建 15 第四节 游戏的运行过程 15 第五节 游戏结束 30 第六节 游戏成果展示 31 结论 33 谢辞 34 参考文献 35 第一章 绪言 第一节 课题目的及意义 一、课题的目的 在科技高速发展的今天,随着Android技术横空出世,Android手机游戏已经占据了手机游戏的半壁江山。本课题利用Eclipse平台、Android SDK、Android ADT设计一个基于Android平台的祖玛游戏,在设计过程中,添加了一些新的元素,让用户在回味曾经经典游戏的基础上,体验Android平台的流畅、便利等特点以及让用户了解Android平台的基本框架和运行原理。 二、课题的意义 祖玛游戏是一款很经典古老的游戏,此游戏在于锻炼玩家的反应能力、灵活力以及预判的能力。因此设计此款游戏让手机用户在业余以及闲暇的时间来放松自己,同时也锻炼自己的反应能力和预判能力,让手机用户在游戏中放松自己,获得无限快乐。 第二节 研究现状 手机游戏最早出现于1997年,经过这十几年的变化和发展,随着手机系统的不断进步,手机游戏也经历了由当初的贪吃蛇等简单游戏到现在各种网游等复杂的进化过程。作为手机娱乐发展的重要内容之一,近几年来,办理手机游戏业务的用户数目呈现快速增长的趋势,使很多开发者开始投入手机游戏的开发中。 从2009年到2010年底,中国手机游戏用户规模从刚开始流行突破1.3亿,到了2012年底,中国手机游戏市场规模达到12.2亿,手机游戏已成人们关注的焦点。在这几年手机游戏的发展过程中,手机平台也经历了由Java平台到现在的Android平台和IOS平台。其中Android系统的使用数占据榜首。 随着手机互联网的发展和智能手机的普及,手机已经成为人们生活的不可或缺品,几乎人走到手机跟到哪。随着手机网络的不断发展与加速,互联网已经逐渐从个人电脑向个人手机发展,这就为手机游戏的商业发展创造了新的机遇。手机游戏在全球范围内展现出了一个巨大的市场,成为了手机互联网发展的热门方向。 作为现在最热门的手机系统,由于开源化的优势,很多用户都在玩Android游戏,所以为了满足用户的需求,Android游戏的更新和开发也变得很重要,不仅要达到使用户娱乐的目的,而且也要具有益智性,让用户在业余时间不仅可以放松自己而且可以锻炼自己。但是据目前情况所致,国内的Android游戏大部分是通过对国外游戏的翻译或模仿移植而来,缺乏自己的创造力和符合自己风俗的色彩,可以看出国内对于Android游戏的开发需求量很大,拥有很大的市场潜力。 第二章 祖玛游戏的需求分析 第一节 需求概述 一、 游戏目标 该游戏易学易上手,具有一定的益智性和娱乐性,是一款很经典的游戏,可以锻炼你对颜色的迅速分辨能力以及及时的反映能力,可以让你在业余时间里放松自己。 二、用户类型和特征 本游戏适合16岁到45岁的手机用户,要求用户拥有一款具有Android系统的手机而且必须是Android 2.2 以上的系统才能运行此游戏,而且要求用户有一定的业余时间。 三、 运行环境 (1)软件环境的需求 操作系统:Windows XP 开发工具:Eclipse 3.4 所需插件:ADT 15.0+Android SDK+JDK 1.6 (2)硬件资源 Android系统的智能手机 第二节 功能需求 本游戏需要实现的功能有发射器更新小球、发射小球、小球的插入、小球的检测以及小球的爆炸等,,具体的功能如下图2.1所示: 图2.1 功能模型 第三节 数据需求 为了把游戏的具体功能清楚、准确的展示给用户,采用了建立数据模型,它包括数据对象、数据对象的属性以及数据对象彼此间相互连接的关系。它是一种面向问题的模型,按照用户的观点来建立的,反映了从用户角度看到的数据,与软件的实现方法无关,表现的是用户的真实环境[1]。 为了实现以上的数据模型,建立实体-联系图,又称E-R图,包括实体,对象和属性三部分,建立的关于本游戏系统的E-R图如图2.2: 图2.2 E-R图 第四节 开发语言的介绍 一、 JAVA语言 Java语言在1991年就已经诞生,在最初被称为OAK语言,用于创建能够嵌入在像遥控器、电冰箱等家用电器的软件,由于家电中CPU芯片各种各样,所以设计人员将其设计成为了一种能够可移植的、跨平台的语言,该语言能够运行在不同的平台、CPU上。1994年,Internet开始在全球范围内流行起来,作为全球最大的客户机-服务器系统,它拥有各种各样的客户机。这对Web开发人员来说是一个挑战,因为他们无法做到对可能访问其页面的每一台计算机都编写功能相同的程序。而在当时Java语言的简单、面向对象、分布式、健壮、高性能、多线程和安全等特点非常适合Internet环境。在1995年5月,SUN公司正式发布Java,并随着陆续的更新和版本的升级,使其在软件开发领域一直占据着主导地位,在近几年中始终保持着编程语言排行榜第一名的桂冠[2]。 二、 Android简介 Android一次的本来意思是“机器人”,就如大家看到Android系统时显示的小绿色机器人,该系统由Google收购并注资发展,主要用于智能手机和平板电脑,由于其自由、开源的有点,目前Android智能手机占据全球第一,在中国市场占有90%的市场。 Android的系统架构和其操作系统一样,采用了分层的架构。从架构图看,Androi d分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层[3],具体的结构图如图2.3所示: 图2.3 Android结构 第三章 祖玛游戏的总体设计 此阶段的设计看似简单但是非常重要,此阶段主要任务是设计游戏该怎么实现,比如框架结构、游戏的流程设计以及相关界面和音乐北京的设计。此阶段的设计,也影响到下一章中的模块设计与开发,在本章只给出设计的大体流程,具体的将在下一章中详细描述。 第一节 游戏框架设计 根据需求分析中的功能需求和数据需求,针对游戏将该游戏系统分为游戏开始、游戏进行、游戏背景、游戏音乐以及游戏结束这5部分,然后再根据这5部分需要来进行相关的设计,详细的设计将在详细设计与实现中具体描述。游戏框架见图3.1所示: . 图3.1 游戏框架图 第二节 游戏的流程设计 流程图是一种以一些简单的符号来向用户展示游戏进程的一种图,它表现出来的是整个系统的运行过程。 该游戏的主要流程包括游戏开始、游戏运行和游戏结束,其中每个流程中都会有一些详细的流程,具体的流程图如图3.2所示: 图3.2 游戏的流程图 第三节 游戏模块设计 一、 游戏开始界面 作为一款游戏的开始界面,这个界面的设计很重要,需要美观,给玩家一种舒心、放松的感觉,因为这是玩家直接面对的画面所以要精心的设计,背景方面要用一些特别的图片,选用一些清淡的颜色,能够引起用户的兴趣,而且不影响玩家的游戏过程,给玩家一种视觉轻松的感觉。 二、 游戏的道具设计 本游戏的主要对象就是小球,因此重点也在于小球的设计,在这里为用户提供了5种颜色的小球作为游戏中的道具,有红色小球、浅蓝色小球、深蓝色小球、黄色弹珠以及紫色小球,小球也有相关的动作,比如:发射、插入以及爆炸,游戏要就是围绕这些小球以及小球的相关动作来运行的。因此在详细设计阶段将重点介绍小球以及小球的相关函数。 三、游戏过程界面 作为游戏运行的主要界面,我们要对这个界面设计非常重要,比如背景颜色和画面不能影响用户玩的过程,另外小球的大小还有小球滚动的速度都要注意,还有发射器的位置也要放的地方对才行,这样才能增加游戏的可玩性。 四、游戏的音乐设计 声音作为玩家玩游戏重要的陪伴者,没有音乐的游戏玩家几乎不会玩,而且手机游戏也是为放松而设计的,所以在音乐方面应该选一些轻松的音乐,让玩家感到身心放松。在发射小球的过程、小球的插入以及小球的爆炸、游戏的结束都需要带有一定的音乐效果,这样才能让玩家喜欢上此游戏。 第四章 祖玛游戏的详细设计与实现 本阶段的主要任务,将按照上一章指定的计划和任务来完成,并做好相关的文档的书写,以便于后期的修改。 第一节 开发环境的搭建 1.JDK的安装 如果你的电脑上还没有JDK的话,可以去百度搜索JDK的下载或者去官网下载,下载完成后按照步骤一步一步的安装,然后设置环境变量,如下: (1)右击“我的电脑”,在属性栏中单击“高级”,从里面找到“环境变量”,然后就可以添加相关值了。 (2)JAVA_HOME值为:C:\Program Files\Java\jdk1.6.0_37(安装JDK的目录)。 (3)CLASSPATH为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;(切记不要忘记开头有个.;和最后面有个; (4)PATH:再开始之前添加;%JAVA_HOME%\bin; 完成以上环境变量的配置,就打开运行窗口,输上cmd进入命令提示符窗口,输入java –version,如果出现以下画面,则证明安装成功,如图4.1: 图4.1 检测JDK安装 2.Eclipse的安装 如果你的电脑上没有Eclipse,则可以去百度上搜索下载或者去官网公司下载,下载解压完成后,打开文件会有以下几个文件,如图4.2所示: 图4.2 Eclipse文件 3.Android SDK的安装 去官网上下载Android SDK(这里建议大家去官网下载,别在一些随便的论坛或者网上下载,因为后期要升级数据包,我由于前期随便下的,后期数据包升级不了,遇到很大的麻烦),然后解压出来,打开其中的SDK Manger会出现以下的画面,如图4.3所示: 图4.3 SDK的升级 选择你想用的平台和工具,单击右下方的Install package进行安装和更新。 4.ADT的安装 打开Eclipse,选择菜单中的”Help”中的"Install New Software"会进入界面如图4.4所示: 图4.4 ADT的安装1 单击Add,再次进入界面,如图4.5所示: 图4.5 ADT的安装2 Name项中随便起,Location项:如果你之前下载了ADT那就通过Archive选择你所下的ADT的所在目录 (建议将ADT放入Eclipse目录中),如果没下载的话,那就去网上找一个ADT的下载路径写进去,就开始自动下载。 5.创建AVD 在Eclipse中。选择Windows > Android SDK and AVD Manager,选择右面的new就可以创建一个AVD,如图4.6: 图4.6 创建AVD 输上名字和设置好API level,选好版本,创建成功后如图4.7: 图4.7 AVD界面 6.打开模拟器 选择你所创建的,然后选择右方的Start就打开了,如图4.8: 图4.8 模拟器 总结,在搭建开发环境的时候建议去官网下载响应的插件,因为私人网站上的插件都是经过修改的,可能搭建起来的开发环境缺少相应的数据包。 第二节 游戏的引擎创建 引擎就是整个游戏的发动机,是游戏的核心部分,他是掌管游戏的后台,在这里我们将用意了GameEngine来创建了这个游戏的引擎。这个引擎中主要包含了下面这些方法: (1)初始化:private void InitDate(); (2)处理点击事件:public void DealPress(); (3)重新开始游戏:private void RestartGame(); (4)退出游戏:public void ExitGame(); (5)开火:private void Fire(); (6)处理子弹间的距离:public float BulletDistance(); (7)撞击:public void CulStricke(); (8)检查是否胜利:private void Checkwin(); (9)插入子弹:private void InsertBullet(); (10)检查爆炸:public void checkBomb(); (11)爆炸更新:public void UpdataBomb(); (12)更新发射器:public void UpdataGun(); (13)重新检测发射器:public void reCheckBullet(); (14)获取闲置小球:private int GetFreeBall(); (15)更新发射球的位置:public void updataBullet(); (16)根据游戏状态执行各分支:public void Gameloop(); (17)向前移动:public void UpdataPreMoveList(); (18)加入到滚动队列:public void AddBalltoList(); (19)移出滚动队列:public void RemoveBallFromList(); (20)获取随机颜色:private int getrandomColor(); 从上述方法看出游戏包括的动作,其中最重要的是public void GameLoop()这个方法,在游戏中我们看到的小球在滚动,其实就是靠不断的循环来刷新来完成的,因此这个游戏运行的原理就是不断的循环。上述方法的具体实现,我们将在下面具体情节来细细的描述。 第三节 游戏显示界面的创建 界面就是整个游戏呈现在用户眼中画面,这个和引擎一样是游戏的主要部分之一,在这里我们用了一个GameView类来创建这个界面,其中包含的方法如下: (1)更新底部图片:public void UpdatePicture(); (2)run函数整个游戏的进行:public void run(); (3)载入Bitmap函数:private void LoadBitmap(); (4)View的循环控制:privete void DoDraw(); (5)画图的载入:public void drawLoading(); (6)画图的结果显示:private void DrawResult(); (7)画出子弹:private void DrawBullet(); (8)待发射子弹的效果:private void DrawGun(); (9)球滚动的效果:private void DrawMovingBall(); (10)检测爆炸的列表,制造爆炸效果:private void DrawBomb() (11)画出地图:private void DrawMap(); (12)创建特定的图片:private void createBuffImg(); (13)游戏开始:void StartGame(); (14)设置触屏事件响应:public Boolean onTouchEvent(); (15)设置返回键的事件响应:public Boolean onKeyDown(); 在以上的函数中,其中run()函数是关于整个游戏进行的,它是靠不断循环进行的,在这个循环中还包含了两个重要函数:DoDraw()和mEngine.GmaeLoop()两个循环函数,这两个函数是整个游戏的重点,可以说整个游戏就是这两个函数来实现的。 第四节 游戏的运行过程 一、游戏的开始 游戏的开始我们通过StartGame()函数来实现的,而且这个函数是一个异步的线程,如果改成同步线程的话,将会产生卡死的现象。游戏的运行主要是通过不断的刷新和循环来实现的,所以主要通过run()函数来进行循环,通过LoadBitmap()来加载相关的图片来完成的,里面有两个刷新的函数为new Thread(resload).start()和new Thread(this).start(),前者是不断的刷新载入的图片,后者则是不断的刷新每次运行出现的结果。 二、初始化地图信息 这里我们通过地图来描述,游戏中产生的地图如下图4.9所示: 图4.9 地图 我们将小球的轨道分为其部分:竖直部分、拐弯部分、水平部分、拐弯部分、竖直部分、拐弯部分、水平部分7部分组成的,从图中可以很直观的看出这7部分,我们通过以下函数完成实现的: private void InitMap() //初始化地图信息,以下代表路线 { for(int i=0;i<mMaxPath;i++) { if(i<=84) { { Data[i][0]=278; Data[i][1]=i*2; } }else if(i<=(84+16)) { float nums=i-84; Data[i][0]=(278-nums*1.35f); Data[i][1]=168+nums*1.35f; } else if(i<=(100+94)) { int nums=i-100; Data[i][0]=257-nums*2; Data[i][1]=190; }else if(i<=194+16) { int nums=i-194; Data[i][0]=67-nums*1.35f; Data[i][1]=190+nums*1.35f; } else if(i<=210+68) { int nums=i-210; Data[i][0]=45; Data[i][1]=210+nums*2; }else if(i<=278+16) { int nums=i-(278); Data[i][0]=45+nums*1.35f; Data[i][1]=345+nums*1.35f; }else if(i<=294+103) { int nums=i-(294); Data[i][0]=66+nums*2; Data[i][1]=367; } } mCount=397; } 可以看到里面有7个选择语句,我们是通过Data[i][0]和Data[i][1]代表X和Y轴的坐标,我们将最左边的竖直边当作Y轴,最下边的横边当作X轴,通过这个7个循环来画出小球运动轨道。 三 小球的队列 给小球创建队列这也是一个重要的指标,它代表小球的各种运动。 首先,我们建立一个总的队列,通过一下代码,我们实现了所有队列: public class List { int Max=100; //列表容量 int data[]=new int[Max]; //数据 int mCurrentCount=0; //当前列表数据个数 public List() { for(int i=0;i<Max;i++) { data[i]=-1; } } public void Push(int nums) //尾部添加数据 { data[mCurrentCount]=nums; mCurrentCount+=1; } public int getCount() { return mCurrentCount; } public int Get(int index) { if(index<0) return -1; else if(index>=mCurrentCount) return -2; return data[index]; } private int getIndex(int nums) { for(int i=0;i<mCurrentCount;i++) { if(data[i]==nums) return i; } return -1; } public int getLast() //获得最后一个数据 { if(mCurrentCount-1>=0) return data[mCurrentCount-1]; return -1; } public int getFirst() { return data[0]; } public int getAhead(int index) //获得前一个数据 { if(index==0) return -1; else return data[index-1]; } public int getBehind(int index) //获取后一个数据 { if(index>=mCurrentCount-1) return -1; else return data[index+1]; } public void ClearList() //清空列表 { for(int i=0;i<data.length;i++) { data[i]=-1; } mCurrentCount=0; } public void Insert(int pos,int nums,boolean bfirst)//插入列表 { if(bfirst) { for(int i=mCurrentCount-1;i>=pos;i--) { data[i+1]=data[i]; } data[pos]=nums; mCurrentCount+=1; }else { for(int i=mCurrentCount-1;i>pos;i--) { data[i+1]=data[i]; } data[pos+1]=nums; mCurrentCount+=1; } } public void MoveEByIndex(int index) //通过索引删除数据 { if(index!=-1) { for(int i=index;i<mCurrentCount;i++) { data[i]=data[i+1]; } data[mCurrentCount]=-1; mCurrentCount-=1; } } public void MoveE(int nums) //删除列表中的数据值 { int index=getIndex(nums); if(index!=-1) { for(int i=index+1;i<mCurrentCount;i++) { data[i-1]=data[i]; } data[mCurrentCount]=-1; mCurrentCount-=1; } } } 以上代码实现了所有队列,后面只要通过继承就可以实现队列的应用,在后面我们用到了一下三个队列: (1)正在滚动球的集合:public List mMoveList=new List(); (2)发射中的子弹的集合:public List mBulletList=new List(); (3)爆炸小球的集合:public List ExplodeList=new List(); 这三个都是继承了List对象的。 四、小球的行为 小球的行为包括:开火、撞击、插入、爆炸这四种行为,下面我们分别详细说说实现每种行为的方法 (1)开火:就是发射器将小球射向小球串中,用户看到是小球飞过去,其实是通过图片不断的刷新来实现的,主要通过下面的代码: private void Fire(float x,float y) { int free=this.GetFreeBall(); mBulletList.Push(free); mAcBall[free].bulletindex=0; mAcBall[free].mPosx=mGun.mAimx; mAcBall[free].mPosy=mGun.mAimy; mAcBall[free].mMoveIndex=0; mAcBall[free].mBallColor=mGun.mBullet[1]; mGun.mBullet[1]=-1; mAcBall[free].mMoveAnimationType=6; } 以上代码通过设置小球移动的坐标即X和Y的坐标来实现小球的移动,移动过程就像动画片那样,通过图片不断的刷新来实现。 (2)撞击:就是当小球遇到正在运动中的小球串时发生的情况,下面我们通过代码来说明: public void CulStricke() { int buletcount=mBulletList.getCount();//发射中子弹的数量 if(buletcount<=0) return; int rollcount=mMoveList.getCount();//滚动的数量 for(int i=0;i<buletcount;i++) { Ball bullet=mAcBall[mBulletList.Get(i)]; float srx=bullet.mPosx; float sry=bullet.mPosy; for(int j=0;j<rollcount;j++) { Ball roll=mAcBall[mMoveList.Get(j)]; float desx=mMap.getX(roll.mMoveIndex); float desy=mMap.getY(roll.mMoveIndex); float dis= BulletDistance(srx,sry,desx,desy); if(dis<=32) { float firstx=mMap.getX(roll.mMoveIndex+16); float firsty=mMap.getY(roll.mMoveIndex+16); float lastx=mMap.getX(roll.mMoveIndex-16); float lasty=mMap.getY(roll.mMoveIndex-16); float firstdis=BulletDistance(srx,sry,firstx,firsty); float lastdis=BulletDistance(srx,sry,lastx,lasty); if(firstdis<lastdis) { InsertBullet(mBulletList.Get(i),j,true); }else { InsertBullet(mBulletList.Get(i),j,false); } mBulletList.MoveEByIndex(i); return; } } } } (3)插入:就是小球碰到球串时应该进行的动作,就是将小球插入到两个小球的之间,代码如下: private void InsertBullet(int nums,int index,boolean firstpos) { Try { Ball roll=mAcBall[nums]; Ball indexBall=mAcBall[mMoveList.Get(index)]; int moveindex=indexBall.mMoveIndex; roll.mMoveAnimationType=indexBall.mMoveAnimationType; if(firstpos) { RollInsertPos=index; int aheadnums=mMoveList.getAhead(index); if(index==0) { roll.mMoveIndex=mAcBall[mMoveList.Get(0)].mMoveIndex+16; mMoveList.Insert(index, nums,firstpos); return; } Ball firstball=mAcBall[aheadnums]; if(firstball.mMoveIndex>moveindex+17) { roll.mMoveIndex=moveindex+16;; }else { roll.mMoveIndex=moveindex+16;; for(int i=index-1;i>=0;i--) { Ball temball=mAcBall[mMoveList.Get(i)]; int temindex=temball.mMoveIndex; if(temindex-moveindex<=(index-i)*16) temball.mMoveIndex+=16; else break; } } mMoveList.Insert(index, nums,firstpos); }else { RollInsertPos=index+1; int behindnums=mMoveList.getBehind(index); if(behindnums==-1) { roll.mMoveIndex=mAcBall[mMoveList.getLast()].mMoveIndex-16; mMoveList.Insert(index, nums,firstpos); return; } Ball behindball=mAcBall[behindnums]; if(behindball.mMoveIndex<moveindex-17) { roll.mMoveIndex=moveindex-16;; }else { roll.mMoveIndex=moveindex;; for(int i=index;i>=0;i--) { Ball temball=mAcBall[mMoveList.Get(i)]; int temindex=temball.mMoveIndex; if(temindex<=moveindex+(1+index-i)*16) temball.mMoveIndex+=16; else break; } } mMoveList.Insert(index, nums,firstpos); } }catch(Exception e) { String mess=e.getMessage(); e.printStackTrace(); } } 每当小球碰到小球串时,上述代码就会执行一边,将球插入到相应的位置。 (4)爆炸:这个行为则是游戏的规则,即遇到三个或三个以上颜色相同时就会产生爆炸行为,这里也用到上面所提到的队列,爆炸的小球串是一个队列。 public void checkBomb(int insert) { List TemList=new List(); Ball SertBall=mAcBall[mMoveList.Get(insert)]; int searchc=SertBall.mBallColor; int searchType=SertBall.mMoveAnimationType; int searchIndex=SertBall.mMoveIndex; TemList.Push(mMoveList.Get(insert)); for(int i=insert+1;i<mMoveList.getCount();i++) { int checkcolor=mAcBall[mM
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 学术论文 > 毕业论文/毕业设计

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服