资源描述:
《基于J2ME俄罗斯方块游戏的设计和实现【毕业论文】》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
本科毕业设计(20届)基于J2ME俄罗斯方块游戏的设计和实现 摘要随着时代的进步和新技术的发展,手机因其小巧便捷的特性成为人们必备的通讯工具,同时手机的硬件配置要求越来越高,与之对应的增值服务也越来越多元化。其中游戏作为人们日常生活中一个重要的娱乐项目,理所当然出现在手机上,手机游戏也就拥有了巨大的市场空间,随着3g的开通和应用,必将迎来新的一轮游戏热潮!,而J2ME易于开发和跨平台的特性使其成为手机增值服务开发的理想开发工具。该系统是一个基于J2ME平台的俄罗斯方块游戏,利用JavaMEWirelessToolkit(WTK)开发包工具在无线网络移动端上实现经典的俄罗斯方块游戏。该文章先介绍了游戏的开发背景,然后是对开发工具的相关介绍以及俄罗斯方块游戏规则,在设计与实现方面,分成游戏规则、方块处理这两个模块进行实现,最终展示了该游戏开发的基本开发过程和设计思路,以及游戏的实现。关键词:J2ME;手机游戏;游戏开发;无线网络移动端;俄罗斯方块 AbstractWiththeprogressofTheTimesandthedevelopmentofnewtechnology,Mobilephoneconvenientfeaturesbecomepeopleessentialcommunicationtools,becauseitssmall,andmobilephonehardwareconfigurationtothedemandishigherandhigher,andthecorrespondingvalue-addedservicesalsomoreandmorediversified.Whichgamesaspeopledailylifeanimportantentertainmentproject,grantedappearonmobilephones,cellularphonegamealsohasahugemarketspace,asthe3genlightenedandapplications,willusherinanewroundofgamesboom!AndtheJ2MEeasytodevelopandcross-platformpropertiesthatmakeitbecomehandsetvalue-addedservicedevelopmentidealdevelopmenttool.ThissystemisbasedonJ2MEplatformgametetris,usingWirelessToolkit(JavaMEWTK)toolintheWirelessnetworksetupsmobileterminalimplementedonclassicgametetris.Thispaperfirstlyintroducesthebackgroundofthedevelopmentofthegame,thenthedevelopmenttoolsofrelatedintroductionandRussiansquaregamerulesinthedesignandrealizationways,therulesofthegame,asquaredealwiththemoduleswhichmakerealizationandfinallydemonstratesthisgamedevelopmentofbasicdevelopmentprocessanddesignideas,aswellastherealizationofthegame.KeyWords:J2ME;Mobilegames;Gamedevelopment;Thewirelessnetworkmobileterminal;Tetris 目录1 引言11.1课题研究背景与意义11.2手机游戏的发展现状11.3论文的主要工作与内容安排22游戏开发环境介绍42.1编程环境的介绍和选择42.2JavaMEWirelessToolkit软件简介52.3JavaMEWirelessToolkit开发环境的介绍73俄罗斯方块游戏介绍113.1俄罗斯方块游戏的背景和规则113.2俄罗斯方块游戏的特性113.3俄罗斯方块游戏的发展前景134游戏系统分析设计154.1系统解决方案154.2系统总体结构154.2.1方块处理模块164.2.2游戏规则模块164.3游戏中断处理流程165系统的实现185.1系统源文件结构185.2游戏规则模块185.2.1游戏规则模块结构185.2.2游戏规则模块功能195.3方块处理模块255.3.1方块处理模块结构255.3.2方块处理模块功能266运行与测试307 结论34致谢35参考文献36附录1系统源代码37附录2毕业设计作品说明书66 1 引言1.1课题研究背景与意义随着经济社会的发展,人民的生活水平也日益提高,移动设备特别是手机得到了非常广泛的应用,在手机平台上运行的游戏也被更多游戏爱好者所接受。作为一个新兴的行业,手机游戏成为无线增值业务迅猛发展的最大亮点。因此,J2ME作为开发手机游戏的主流平台有着非常良好的前景。而J2ME这个主要的游戏开发平台相比其他智能客户端而言,有个独特的优点,就是它是专为手机设计的。J2ME应用可运行在不同投资商的不同设备上,这一特性在高度竞争的手机设备行业中是特别重要的,现在所有主要的智能手机制造商都支持J2ME平台,所以基于J2ME的手机游戏开发前景是非常美好的。如今的手机游戏,无论从视觉效果、听觉效果还是游戏的可玩性来说,都很精彩。当今世界,移动电话数量巨大,除美国之外,其他各个发达国家拥有手机的人数比拥有计算机的人数还多。而在我国,手机拥有量甚至超过了美国的人口数量,而且每个月手机的数量仍然以惊人的速度增长着。手机市场的高速发展带动了手机游戏市场的急速膨胀,基于Java,BREW等技术平台的手机游戏市场规模纷纷呈现几何增长态势。基于J2ME的俄罗斯方块游戏虽然只是一款简单的游戏,但它可谓是一款经典之作,因为玩家可以一次一次地挑战新纪录,而且积分越高方块速度越快,给人一种挑战感,大大增加了其可玩性。在设计这款游戏的同时,还有助对于J2ME知识的理解,其次一个小型的手机游戏中有很多地方代码结构是相同的,比如开始动画、游戏菜单等。于是,开发一套可以为我们编写代码框架的J2ME手机游戏开发引擎对于提高游戏的开发速度是很有帮助的。1.2手机游戏的发展现状IT业作为一项热门的产业,游戏已经成为其技术创新背后的动力之一。游戏玩家们总是渴望有更强大的硬件条件来实现质量更高的游戏,以获得较好的视觉效果和乐趣,手机游戏虽然目前还不 能与计算机游戏的功能相比较,但是它是在手机上运行的特点是它的一项优势,因为手机是我们日常生活中随身携带的通讯工具,可以随时随地的玩游戏。由于受目前的技术条件限制,在众多的游戏种类中,只有几种游戏类型是适合无线网络移动端开发的,如低激烈程度的街机游戏;简单的运动类游戏;解谜游戏;简单的匹配游戏和主题测试游戏。而网络游戏产业的繁荣,让企业和消费者同时认识到了游戏的力量,虽然受到屏幕尺寸和操作性的限制,但作为全球使用量最大的通信产品,手机也具有成功进入掌上游戏领域的理由。而彩屏革命过后,手机游戏就变得更加丰富多样了。从当初诺基亚手机中经典的二维贪吃蛇游戏,到今天的三维画面及声色效果俱佳的游戏,手机游戏已经成为一种非常普遍的休闲方式,为玩家带来了很多快乐及新奇的体验,同时也为开发商带来了更多的利润。这一切得益于Sun公司,它是Java平台的东家,可以说手机端游戏的发展与Java技术的发展有着不可分割的联系。Java2推出后,Sun推出了一种名为J2ME的平台,被广泛应用于手机端。随着各大手机生产商对J2ME标准的支持,以及基于J2ME开发的手机游戏的可移植性和快速开发的优势,J2ME手机游戏市场需求越来越高。手机游戏在日本、韩国的发展是非常快的,2009年日本手机游戏市场超过一万亿日元,其中KDDI为用户提供了350多款游戏。韩国则是全球最大的游戏生产国,SKT提供280款手机游戏,年销售额达1500亿韩元;KTF为用户提供了600多款游戏,销售额约1000亿韩元;LGT游戏业务在所有内容业务中占据了30%的比例。日韩手机游戏营收占其增值业务总营收的近10%,但在我国这个比例还不到1%。目前我国有超过1亿的手机上网用户,庞大的用户基数以及与日韩的市场差距,意味着我国手机游戏市场蕴藏着一座巨大的“金矿”[1]。1.3论文的主要工作与内容安排本文主要介绍的是基于J2ME俄罗斯方块游戏的设计与实现,该软件主要实现的功能如下:1.能产生7种不同形状的下坠物,其中的有两对下坠物形状相似,只是朝向不同。2.当任何一层被填满时,该层会消失,最多一次可以消除4行。3. 当游戏屏幕的顶端被下坠物接触到且无法继续下落,则游戏结束,屏幕显示“Gameover”字样。4.游戏具有暂停功能。5.具有积分功能,每次消除任何一行积满行,都会得到相应的分数。完成后能使软件在仿真软件上运行并实现以上功能,而文章的具体内容共分为6个章节,各章节名称与大致内容如下:第一章 引言:主要介绍课题的研究背景与意义以及论文的内容安排。第二章游戏开发环境介绍:主要是对游戏开发平台J2ME与开发工具WTK软件的介绍。第三章俄罗斯方块游戏介绍:主要介绍俄罗斯方块游戏的背景、规则、游戏特性和该游戏的发展前景。第四章游戏系统分析设计:主要讲解游戏的系统解决方法、总体结构以及游戏中断处理流程。第五章系统的实现:主要介绍系统的源文件结构由四个类组成,然后具体地介绍游戏规则模块与方块处理模块功能的实现。第六章运行与测试:主要讲解介绍所编写的软件各个要求实现的功能在仿真软件上的实现。 2游戏开发环境介绍2.1编程环境的介绍和选择如今,移动网络端开发主要有以下四种平台。BinaryRuntimeEnvironmentforWireless(BREW),Symbian,WindowMobileSmartphone和JavaMicroEdition(JavaME)。以下是对这四种平台的简单介绍:1.BinaryRuntimeEnvironmentforWireless(BREW)BREW是基于高通公司CodeDivisionMultipleAcces(CDMA)技术的手机开发平台,在北美和亚洲有部分无线通信服务提供商。它使用C或C++结合BREWAPI来开发BREW设备上的程序。和JavaME相同的是BREW能够作为游戏和地磁手机操作系统之间的一个中介。而和JavaME不同的是BERW也支持本地代码,能够专门针对某一手机的处理器而编译,而本地代码一般要比对应的解释版本要快很多,但是在设备之间移植会花费很多技巧与功夫。2.SymbianSymbian是一种开放的操作系统,任何的设备制造商都能获得使用许可。它支持C++、Java和VisualBasic等编程语言,但是大多数商业Symbian游戏都是用C++作为本地Symbian应用程序来开发的,这使得它们和Java开发的游戏相比要快一些。3.WindowMobileSmartphone在WindowMobileSmartphone平台上,可以使用在编写PocketPC游戏时所使用的相同的工具和API。这就意味着要使用C、C++或C#编程语言并结合使用WindowMobileAPI。4.JavaMicroEdition(JavaME)JavaMicroEdition(JavaME)是SunMicrosystem公司于1999年6月推出的。JavaME以往称作J2ME,根据Sun的定义:JavaME是一种高度优化的Java运行环境,其广泛用于为信息家电市场提供应用服务,这些信息家电包括电视机顶盒、传呼机、个人商务助理(PDA)、移动电话、POS终端和其他消费类电子设备。JAVAME技术在1999年的JavaOneDeveloper Conference大会上正式推出,它将Java语言的与平台无关的特性移植到小型电子设备上,允许移动无线设备之间共享应用程序,它和JavaSE、JavaEE一起构成Java技术的三大版本,并且同样是通过JCP(JavaCommunityProcess)制订的[2]。对于俄罗斯方块游戏的设计与实现,这里选择使用JavaMicroEdition英文缩写为J2ME,因为J2ME是目前最占优势的移动软件开发技术,全球手机制造商中,JavaME有着最广泛的工业支持,据统计2007年约有4.5亿支持Java的手机销售出去,占整个市场的百分之七十五,并可能继续发展其市场份额。还有很重要的一点,我们都知道无线移动设备的屏幕相比计算机要小许多,而且计算能力两者目前无法相比,JavaME是JavaSE的子集和简化功能集,它支持一个较小的功能集,这些功能很适合无线移动设备。JavaME拥有丰富的应用程序接口(API)和一组可以灵活调用的开发工具,依靠的不是本地应用程序代码,而是通用的字节码,它的程序移植到不同的手机比较容易,不需废多大的力气,相比其他开发工具优势比较明显。由于Java语言自身的特点,和系统的关联不大,所以开发速度很快,程序的开发周期比较短。另一方面从技术入门的角度来说,由于Java语言相当的普及,而对于有一定Java语言基础的人来说,学习J2ME技术的门槛很低,所以J2ME技术的普及速度很快,在编写俄罗斯方块游戏时,遇到问题通过学习相对要容易解决。但是J2ME也有其技术的劣势,其一是功能有限,为了实现J2ME技术的移植性,J2ME技术无法实现系统的功能,例如读取电话簿、短信息等系统内容,却无法开发手机上的系统软件。其次是运行速度比较慢,由于J2ME技术运行在jvm基础上,再加上手机硬件的限制,所以运行速度相对比较慢,不过这个速度还是在用户可以接受的范围之内。最后是程序大小受限制,在手机上J2ME技术开发的程序在程序大小上受到很大的限制,例如NOKIAS40系列的程序大小一般都限制在64KB以内,这个大大限制了J2ME程序的功能。不过在设计实现俄罗斯方块游戏上,要求实现的功能没有那么复杂,运行速度的要求也是不那么高,程序大小的要求也不高,所以这么些缺陷这设计俄罗斯方块游戏时没有太大的影响,所以选择J2ME作为开发工具是理智的。2.2JavaMEWirelessToolkit软件简介JavaMEWirelessToolkit是软件开发常用工具,简称J2MEWTK,全称Java ME无线开发工具包。WTK是Sun公司提供的一个用于创建MIDP应用程序的工具集。该工具集包含了生成工具(KToolbar)、实用程序集(Utilities)和设备仿真器(Emulator)等主要组件。J2MEWTK当前的版本为2.52,支持由JCP所定义的CLDC1.1(JSR139)、JTWI1.0(JSR185)、WMA2.0(JSR205)、MMAPI1.1(JSR135)等许多标准应用程序编程接口(API)的功能。J2MEWTK2.2支持多种操作系统,包括Windows操作系统和RedHatlinux操作系统,并且有英文、日文、简体中文和繁体中文几个版本。J2MEWTK2.2作为一个轻量级的IDE工具,没有提供编辑功能,必须与其他文本编辑工具结合在一起使用,也可以与Jbuilder、NetBeans和Eclipse等IDE集成使用。J2MEWTK2.2可以从Sun公司的网站通过注册后免费获取。WTK的安装程序很简单,但是有一点需要注意,因为WTK软件自身并没有附带Java的运行环境JDK,所以,在安装WTK之前需要先安装JDK。WTK会首先自动检测当前系统已有的Java虚拟机,然后显示出当前虚拟机所在路径,在确定无误后,按继续,最后安装成功后,您将得到一个包括多种实用工具的开发包,目录如图2-1所示:图2-1WTK目录结构WTK的目录结构包括以下几个目录以及该目录包含的内容: appdb目录:RMS数据库信息 apps目录:WTK自带的demo程序 bin目录:J2ME开发工具执行文件 docs目录:各种帮助与说明文件 lib目录:J2ME程序库,Jar包与控制文件 session目录:性能监控保存信息 wtklib目录:JWTK主程序与模拟器外观 WTK是用来开发MIDP的,为了让MIDlet能顺利编译和执行,WTK必须具有CLDC和MIDP的类库,它可以帮助我们省去额外安装调试这些类库的时间。而不同版本的WTK包含的程序库内容是不一样的,例如2.0版本中包含了midpapi.jar,wma.jar,mmapi.jar,而在2.1版本中则变为了cldcapi10.jar,cldcapi11.jar,midpapi10.jar,midpapi20.jar,wma.jar以及mmapi.jar;在2.2中,wma.jar又细分为wma11.jar,wma20.jar。如果您在开发中需要某个特定的jar包而当前的WTK版本又没有时,您可以简单把这个jar包拷贝如当前WTK的lib文件夹即可。apps目录中包含有许多Demo程序,能为我们演示J2ME的一些技术实例,它们可是很好的学习材料[3]。2.3JavaMEWirelessToolkit开发环境的介绍在J2MEWTK中,各MIDlet套件被组织成一个个项目。因此,一个项目的最终结果就是一个MIDlet套件。项目中包含用于生成MIDlet套件的所有文件,包括Java源文件、资源文件以及MIDlet清单文件和应用程序描述文件。J2MEWTK通过Ktboolbar对项目进行新建、打开、设置、打包和运行等管理工作。启动Ktoobar后就可看到控制台窗口,如图2-2所示:图2-2控制台窗口 新建项目后,需输入项目的名称和药编写的MIDlet类的名称,其中MIDlet类名必须和主类名称一致,新建界面如图2-3所示:图2-3新建项目对话框新建完成后单击“设置”,将自动弹出项目设置窗口,通过其中的各个选项可以设置项目的生成环境,如图2-4所示:图2-4项目设置窗口 如果采用省缺选项,只需单击“确定”关闭窗口即可,此时,KToolbar控制台的窗口标题将更改为新的项目名称。并且,控制台中害将显示一些消息,表明新建项目的源代码、资源文件和库文件所储存的确切位置,如图2-5所示:图2-5新建项目后控制台显示的消息如果要直接运行MIDP应用程序,只需在程序组中直接选择“运行(R)”即可,在弹出对话框中选择其它路径中的JAD程序运行,JAD描述文件与其对应的JAR文件要在同一个目录下,需要注意的是运行目录路径中不能包含中文。KToolBar的生成功能会将源代码编译并预先审核,但并不会产生JAR文件,如果要发布MIDP程序,除了JAD描述文件,还必须打包成JAR文件。在KToolbar菜单中选择项目然后选择包,再选择产生包就可以把整个程序和资源文件打包成JAR文件。形成的JAR文件保存在项目所对应的bin目录下。另外除了产生包之外还有产生混淆包的功能,可以防止别人反编译后读取源代码。最后为了尽可能模拟手机运行环境,可以在菜单中选择编辑,然后选择偏好,选择自己想要的手机模拟环境,如图2-6所展示: 图2-6模拟手机环境“偏好”的选择 3俄罗斯方块游戏介绍3.1俄罗斯方块游戏的背景和规则俄罗斯方块游戏是一款简单又经典的方块匹配游戏,它是款相当直观的游戏,一款关于坠落碎片重新组合的简单游戏,哪怕新手也会很自然地想要把它们排列拼凑起来,它会激起普通人想把杂乱的事物整理成有规则的形状的想法,这是一种自然天性,各种方块的突出点和缺口可以完整地组合。在操控性方面,更是简单得彻底,只需操作方向键就可以对游戏进行全盘控制,可谓是最简单的游戏操作,这也正符合手机上运行游戏的条件,因为不需要太多的按键。说句玩笑话,俄罗斯方块可谓是过去二十年间最浪费人们时间的事物之一。它也曾被评选为历史上最伟大的游戏之一,起源大概要追溯到八十年代中期,是由俄罗斯人阿列克谢·帕基特诺夫(AlexeyPazhitnov)发明的,而它的人气自开发出来一直到几年后才开始显露出来。游戏的概念相当简单,现在已成为一种公认的规则:从屏幕顶部以随机顺序落下不同形状的碎片,玩家要试图把它们拼凑成没有空隙的行列,每充满一行就消去这一行,得到相应的分数,而最多可以同时消去四行,得到更多的分数,当玩家进行游戏方块填充上去,接触到屏幕顶端但下面的方块无法消去时游戏就宣告失败。这款游戏有一特点,就是玩家是没有办法赢得比赛的,因为坚持的时间越长,方块下落的速度就会变得越来越快,而游戏的吸引力就在于使玩家顶住碎块的进攻,支撑的时间比上一次更长,赢得更多的分数。俄罗斯方块举世闻名的游戏性,在该游戏新鲜出炉时就显得非常直观,深受众多游戏玩家的好评。3.2俄罗斯方块游戏的特性俄罗斯方块游戏具有五大主要特性:1.简单易学,容易操作:俄罗斯方块游戏真正杰出的地方是在于它的游戏机制非常非常简单,浅显易懂。玩好这个游戏只需上下左右的方向键以及暂停和旋转需要的键,所有的操作都在屏幕上一览无余,这样的话,不论玩家是否熟悉计算机游戏, 都可以很好的去驾驭上面的方块,去拼凑他们,因为整理拼凑各种形状的碎片是人类与生具有的能力。但是,玩家却永远不可能完全掌握这个游戏,因为这个游戏在理论上可以玩无限长的时间,只要玩家不输。2.单屏游戏:俄罗斯方块的游戏另一个明显特性是它的游戏内容全部反映在一个屏幕上,包括积分,下一个到来的方块等信息。即游戏玩家可以在同一时间看到整个游戏环境,在这个基础上可以决定如何处理手上的这块碎片。这个游戏中没有任何的探索成分在内,不会吓着玩家也不会给玩家惊喜,非常的平淡。总的来说玩家能看到让游戏顺利进行下去几乎所有的信息,所以玩家输了的话只能怪自己的判断和思考。3.无限游戏:在游戏过程中只要碎块还没有堆到屏幕顶端,这游戏就会一直进行下去,无论玩家犯多少错误。但是每次游戏都是失败而告终的,没有人能真正赢得这个游戏,除非玩家玩的版本有最高分限制。玩家可以在游戏过程中累积经验,找到坚持更久的技巧,让游戏水平不断地提高,这就是俄罗斯方块相比普通拼图游戏的一大魅力所在,因为玩家成功完成了一幅拼图,只要他还记得是如何拼凑的,那么这个拼图对他而言就没有挑战性了,所以大家通常不会多次玩一个拼图,但俄罗斯方块这个设计精巧的游戏却能让玩家玩上一遍又一遍,一直保持吸引力。4.无限生命和许多街机游戏不同,俄罗斯方块游戏不会因为玩家因为一次失误而结束,只要方块不堆积到屏幕顶端。因为游戏的设计允许玩家犯一定的错误,却不会立即败下阵来,所以当游戏碎块堆积在长方形盒子的底部时,玩家可以清楚地看到自己的失误情况,在失败前,他还是有一定的时间思考如何把后面的碎块拼凑得更合理,从而获取更多的分数。就这样,俄罗斯方块游戏虽然没有给玩家多条生命,但却在游戏重新开始前,给予游戏玩家一个思考游戏技巧以及获得一定成就的机会。5.最高分制度俄罗斯方块游戏具有一个计分模式,它能够给玩家计分并把分数记录在积分排行榜上面,能够让玩家本人或其他玩家查看之前的一些记录。其实 ,因为玩家不可能赢得游戏,所以,为了打破之前的记录或者挑战朋友的高分,让玩家充满斗志并且兴趣浓厚,继续寻找方法提高技术来赢得更多的分数,从来在高分排行榜上记录自己的名字。3.3俄罗斯方块游戏的发展前景1984年6月,在俄罗斯科学院计算机中心工作的数学家帕基特诺夫利用空闲时间编出一个游戏程序,原本是用来测试当时一种计算机的性能,因为他爱玩拼图,突然产生灵感,设计出了举世闻名的俄罗斯方块游戏。直到一年后,他把这个程序移植到个人计算机上运行,俄罗斯方块从此开始传播开来。而在1988年,罗杰斯在美国拉斯韦加斯的一个展览会上看到了俄罗斯方块游戏,觉得很有趣味,而且发现其他人也喜欢。作为宜个游戏专业人士,罗杰斯立刻嗅到了巨大的商机,随后他与日本游戏厂商任天堂达成口头协议,出发前往莫斯科。由于帕基特诺夫把俄罗斯方块授权给了他工作的计算机中心,使其成为了公有财产,所以罗杰斯面对的谈判对象是当时苏联政府的代表,最终罗杰斯于1989年代表任天堂取得了俄罗斯方块游戏在家用计算机机上的授权。而罗杰斯与帕基特诺夫因此相识,并且成了好朋友,这奠定了此后许多年中他们围绕俄罗斯方块进行密切合作的基础。在苏联解体后,帕基特诺夫在罗杰斯的帮助下移民美国,继续从事游戏开发。1996年,他拿回了俄罗斯方块的知识产权,与好友罗杰斯一起成立了蓝色行星软件公司,由该公司独家代理俄罗斯方块游戏的授权事务。小方块拼凑的魅力经久不衰,截至2009年,俄罗斯方块游戏发售了1.25亿份,受到50多个国家和地区的玩家喜爱,有超过50种语言的版本,运行在几十种游戏平台上,从掌机、街机、个人电脑,到手机和PDA。而移动设备已经成为俄罗斯方块游戏新的主要平台,该领域的发售量已超过7500万份,并且仍在快速增长中。而在北美和欧洲俄罗斯方块网络版的官方网站上,每天超过100万人玩这个游戏。俄罗斯方块因此获得了许多奖励,在多项评选中被评为最经典的游戏之一。2002年,一名过分沉迷此游戏的英国玩家在飞机上用手机玩俄罗斯方块游戏, 而且不听机组人员的劝阻,结果被判刑入狱4个月,这个独特的事件可以反映出该游戏的独特魅力。如今25年过去了,电子游戏业发生了翻天覆地的变化,拥有高画质高操作性的网络游戏纷纷出现,开辟并占据了新的市场。如此,俄罗斯方块这样的游戏还有前途吗?答案是肯定有前途的,因为俄罗斯方块是一个休闲游戏,首先它面对的是那些没有精力或兴趣玩大型游戏的玩家,这些人只是需要一类简单好玩的游戏来消遣和打发时间,拿起来就能进入状态,在忙碌的生活中寻求片刻放松,因为俄罗斯方块游戏对硬件的要求较低,所以再目前的大都移动设备来说都可以运行,这大大的提高了其普遍性。而在中国市场,罗杰斯说他正在与中国腾讯公司商谈,研究将俄罗斯方块集成到即时通讯软件QQ中去的事宜。他还将参加今年7月份在中国举行的国际数码互动娱乐展览会,与联众等中国游戏企业探讨合作前景。虽然是一款小小的方块拼凑游戏,其发展前景依然一片光明,特别是在小型移动设备上,如图3-1所示,游戏界面与操作按钮非常直观。图3-1模拟在移动设备上运行俄罗斯方块游戏的情景 4游戏系统分析设计4.1系统解决方案本系统的操作系统为大家所熟悉的WindowsXP,以JavaMicroEditionWirelessToolkit2.52作为开发工具,用中文版eclipse做为代码编辑器而实现的。在KToolBar开发包中菜单编辑中的偏好选择DefaultColorPhone模拟器,进行调试和运行。4.2系统总体结构本系统开发的主要任务是基于J2ME的俄罗斯方块游戏能在无线移动端设备上实现。游戏的操作流程非常简单,用户启动MIDlet后,马上就进入游戏的欢迎画面,当用户按下[开始]按钮后,就可以开始玩游戏了,用户想暂停时,再次按一下[开始]按钮,游戏就暂停了,在暂停的情况下再按[开始]按钮,游戏继续运行。任何时候按[退出]按钮,游戏MIDlet都会终止。该流程图如图4-2所示:图4-2游戏画面流程图 而根据游戏的内容,俄罗斯方块游戏最重要的组成是它各式各样的方块,还有像消去积满行得到相应的分数等游戏规则。要实现这些功能,游戏可分为两个模块:方块处理模块和游戏规则模块。4.2.1方块处理模块本系统中的方块处理模块主要有7种形状的下坠物,每种形状的下坠物都是由4个基础正方形小方块组成,其中两种下坠物的形状是差不多的,只是所朝方向不同而已,如下图4-2所示:图4-2各种形状的下坠物4.2.2游戏规则模块本系统中的游戏规则模块主要任务是实现俄罗斯方块游戏的基本规则。从游戏屏幕的顶端,从7种形状的下坠物中随机选择一种下落,在下落过程中可以选择快速下路,可以控制下坠物旋转,直至不能继续下落,当下坠物接触到游戏屏幕顶端且无法继续下落时,游戏结束,而每填充满一行或多行,消去填充满的,得到相应的积分,记录游戏最高分。总的来说游戏规则由随机生成下坠物,消减积满行,快速下落,方块旋转,分数计算组成。结构图如图4-3所示:游戏规则消减积满行快速下落方块翻转分数计算随机生成下坠物物图4-3游戏规则模块的结构图4.3游戏中断处理流程 在运行游戏时,玩家可随时暂停游戏或直接结束游戏,也可以再暂停情况下结束游戏。中断处理是移动设备程序生命周期的重要组成特性,包括挂起阶段(pauseApp)、运行阶段(startApp)和结束阶段(destroyApp),各阶段转换处理如图4-4所示:运行阶段(startApp)挂起阶段(pauseApp)结束阶段(destroyApp)唤醒挂起结束结束图4-4系统生命周期图即玩家在运行游戏时,可以暂停游戏,使之处理挂起阶段,暂停时可以直接结束游戏,也可以唤醒继续进行游戏,当然运行游戏时同样可以直接结束游戏,使之直接转换到结束阶段。 5系统的实现5.1系统源文件结构本系统由4个类组成实现所有功能,项目名称为xuqh,MIDlet名也为xuqh,所有实现系统功能的源文件都在src目录下,其中xuqh.java为主类,如图5-1所示:图5-1C盘中WTK2.52目录下xuqh项目下的源文件所在位置5.2游戏规则模块5.2.1游戏规则模块结构本游戏的两个模块由3个类组成并且实现,其中KetrisBlock.java,该类为处理生成下坠物及下落问题。第二个类KetrisCanvas.java,该类为处理游戏界面问题。第三个KetrisMap.java,该类为处理游戏画布问题。游戏规则模块由这3个类中的一些方法实现,总结如下: 消减积满行由KetrisMap.java类中的paint(Graphics)、check(Graphics,int)与deleteRow(Graphics,int)实现。快速下落由KetrisCanvas.java类中的keyPressed(int)控制方块方向的下移部分实现。方块翻转由KetrisBlock.java类中的paint(Graphics)与checkRot()方法实现。分数计算由KetrisMap.java类中的init()方法与paintScore(Graphics)实现。而随机生成下坠物由KetrisBlock.java类中的int()方法、readPattern(int[][][])以及KetrisCanvas.java类中的run()方法实现,其中KetrisCanvas.java类中的run()方法实现了方块的循环下落,代码如下:publicvoidrun(){while(true){try{thread.sleep(50);}catch(InterruptedExceptione){break;}repaint();}}5.2.2游戏规则模块功能基于J2ME的俄罗斯方块游戏的游戏规则模块能实现的功能为随机生成下坠物,消减积满行,快速下落,方块旋转,分数计算。俄罗斯方块游戏的下坠物是随机生成的,主要由类KetrisBlock.java中的int()方法、readPattern(int[][][])实现,部分代码如下:protectedvoidinit(){pattern=next;next=Math.abs(rand.nextInt())%7+1;/*得到当前下坠物*/switch(pattern){case1:readPattern(blockpattern1);break;case2:readPattern(blockpattern2);break; case3:readPattern(blockpattern3);break;case4:readPattern(blockpattern4);break;case5:readPattern(blockpattern5);break;case6:readPattern(blockpattern6);break;case7:readPattern(blockpattern7);break;}/***设置当前下坠物变量的内容*@paramnowblockint[][][]7种下坠物常量之一*/privatevoidreadPattern(int[][][]nowblock){blockpattern=newint[4][4][4];for(inti=0;i<4;i++){for(intj=0;j<4;j++){for(intk=0;k<4;k++){blockpattern[i][j][k]=nowblock[i][j][k];}}}} 游戏中一个重要环节消减积满行的功能,就是将填满的行删除,变成背景的颜色,而被删除行的上面一行方块则会相应地下落,直至不能下落停止,其部分代码如下:publicvoidpaint(Graphicsg){//清屏KetrisCanvas.clear(g);for(inti=0;i<16;i++){for(intj=0;j<12;j++){if(mapdata[i][j]==8){KetrisBlock.drawBrick(KetrisCanvas.GAMEAREA_X+j*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+i*KetrisCanvas.BRICK_WIDTH,g,7);}}}}publicbooleancheck(Graphicsg,introw){booleandeleteFlag=false;//最多可以连消4行inttmpRowNo;if(row+4>=15){tmpRowNo=15;}else{tmpRowNo=row+4;}for(inty=row;y=0;i--){//列for(intj=0;j<4;j++){intmx=x+j;intmy=y+i;if(my<0){my=0;}if(blockpattern[rot][i][j]==1&&map.get(mx,my)!=8&&map.get(mx,my)!=0){returntrue;}}}returnfalse;} 6运行与测试打开wtk2.52软件,选择“打开项目”,选择xuqh,如下图6-1所示:图6-1运行wtk2.52软件,载入xuqh然后选择生成,如下图6-2所示:图6-2xuqh生成完成然后点击运行,会弹出个模拟手机使用环境,只需点击手机右边的按钮选择“启动”就可以运行该软件,显示效果如下图6-3所示: 图6-3启动游戏前效果图图6-4游戏欢迎界面效果图点击启动后,即可进入“欢迎进入俄罗斯方块世界”的游戏欢迎界面,该界面显示作者名字与所读院校,如上图6-4所示。现在想要马上进入游戏,只需点击模拟手机右上方的键,选择“开始”,就可以开始游戏了,游戏一旦开始,游戏屏幕顶端立刻开始随机生成下坠物,只需操作上下左右按钮就可以控制方块的运动方向及翻转,游戏效果图如图6-5所示。在游戏进行时可以随时暂停游戏,有两种方法暂停,一种是按下右上角的按钮选择“开始”,游戏就进入挂起状态,再按下次按钮选择“开始”,游戏继续进行;另一种方法是选择手机屏幕左上角的MIDlet,选择“暂停”,要继续选择“恢复” ,但此方法只能在软件仿真时使用,手机上运行时只需使用第一种方式,暂停画面如图6-6所示:图6-5游戏开始后的效果图 图6-6游戏暂停效果图游戏的积分功能,在消去积满行后开始实现,得分后在游戏屏幕右侧显示,如图6-7所示,消去了一行后得到20分。当下坠物接触到游戏屏幕顶端且无法继续下落的时候,游戏结束,画面显示“gameover”,如下图6-8所示,此时玩家可以按左上角的按钮选择“退出”退出游戏,也可以按右上角的按钮选择“开始”继续开始新一盘的游戏。 图6-7游戏消得分功能实现效果图图6-8游戏结束时显示“gameover”效果图在游戏运行过程中或者暂停时都可以按手机左上角按钮选择“退出”结束游戏,退出游戏后回到图16启动游戏前的画面。最后是该游戏在真机NOKIAN95手机上实现的效果图,如图6-9和图6-10所示:图6-9游戏开始时真机实现效果图图6-10游戏中得分后的真机实现效果图 7 结论本系统严格按照任务书的内容完成,是一个基于J2ME平台能在无线网络移动端运行的经典俄罗斯方块游戏,利用JavaMEWirelessToolkit(WTK)作为开发包工具在无线网络移动端上运行并实现了该游戏。论文开始的部分先介绍了无线网络移动端系统开发经常使用的几种开发语言和开发环境,然后进行比较,解释选择J2ME语言和WTK软件作为开发语言和环境的原因,然后对WTK软件作了相关的介绍和部分操作演示。之后对俄罗斯游戏这款经典游戏的背景和发展前景进行了介绍与分析,说明对此开发的意义。在进行系统设计时,遵循无线网络移动端程序startApp、pauseApp、destroyApp的开发生命周期。在设计与实现方面,根据游戏规则、方块处理两个模块进行介绍与实现。最终展示了无线网络移动端的游戏开发的基本开发过程与设计思路。与电脑游戏以及其他家用游戏的开发一样,无线网络移动端的游戏开发必须要掌握和组合应用多种软件开发技术。同时,无线网络端游戏也是计算机科学技术与艺术相结合的结晶,使对它的开发充满独特的魅力。如今手机普及率之高,让无线网络移动端游戏的产业越来越繁荣,而且手机数量和使用者仍在不断地增加,使其充满活力,前景一片美好,做为手机支持率最高的J2ME语言,也会随着无线网络端游戏的欣欣向荣而不断发展。如今,手机游戏几乎是每款手机必备的功能,功能更强大、画质更好的高端手机游戏将越来越受欢迎,在中国如此庞大的市场,更是潜力无限。 参考文献[1]黄蕗,手机游戏:娱乐和信息产业的又一亮点[J].2010,(2)[2]丁月华,J2ME手机游戏开发平台的设计与实现[J],2007,(05)[3]胡虚怀等编著.J2ME移动设备程序设计[M].北京:清华大学出版社,2006.01[4]金鑫,基于J2ME的手机游戏的分析[J].2010,(12)[5]MichaelMorrison.BeginningMobilePhoneGameProgramming.Copyright[M]2005bySamepublishing.[6]王雷,移动设备中基于J2ME技术游戏的开发与实现[J],2008,06,(6)[7]陆昌辉,曾健等编著.J2ME应用开发详解[M].北京:电子工业出版社,2009.04[8]Bray,J.,Sturman,C.F.Bluetooth:ConnectwithoutCables[J].UpperSaddleRiver,NewJersey:PrenticeHallPTR,2002[9]连飞,基于J2ME的无线蓝牙技术应用研究[J].2008,(20)[10]周臻,郭庆平.基于J2ME的蓝牙应用开发及实现[J]电脑知识与技术(学术交流),2007,(13).[11]马毅华,冯恩信.基于JSR-82规范的J2ME蓝牙应用及其实现[J]无线电工程,2004,(08)[12]汤茂斌,基于虚拟环境下手机飞行游戏中蓝牙通讯技术的应用[J],2008,(9)[13]周臻.基于J2ME的移动蓝牙联网游戏研究与应用[D]武汉理工大学,2008[14]樊志平,洪添胜.基于J2ME和蓝牙技术的中国象棋游戏的研究[J],2010,(15)[15]邹吉涛编著.J2ME游戏开发[M].北京:清华大学出版社2009.09 附录1系统源代码主类xuqh:importjavax.microedition.midlet.*;importjavax.microedition.lcdui.*;publicclassxuqhextendsMIDlet{KetrisCanvasketris;publicxuqh(){ketris=newKetrisCanvas(this);}publicvoidstartApp(){Display.getDisplay(this).setCurrent(ketris);}publicvoidpauseApp(){}publicvoiddestroyApp(booleanunc){}}KetrisBlock类:publicstaticfinalint[]BRICK_COLORS={0x00FF0000,0x0000FF00,0x00FFFF00,0x000000FF,0x00FF00FF,0x0000FFFF,0x00C0DCC0,0x00808080};protectedintblockpattern1[][][]={{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0} },{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}}};protectedintblockpattern2[][][]={{{0,0,1,0},{0,0,1,0},{0,1,1,0},{0,0,0,0}},{{0,0,0,0},{0,1,0,0}, {0,1,1,1},{0,0,0,0}},{{0,0,0,0},{0,1,1,0},{0,1,0,0},{0,1,0,0}},{{0,0,0,0},{1,1,1,0},{0,0,1,0},{0,0,0,0}}};protectedintblockpattern3[][][]={{{0,1,0,0},{0,1,0,0},{0,1,1,0},{0,0,0,0},},{{0,0,0,0},{0,1,1,1},{0,1,0,0},{0,0,0,0}},{ {0,0,0,0},{0,1,1,0},{0,0,1,0},{0,0,1,0}},{{0,0,0,0},{0,0,1,0},{1,1,1,0},{0,0,0,0}}};protectedintblockpattern4[][][]={{{0,0,1,0},{0,0,1,0},{0,0,1,0},{0,0,1,0},},{{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}},{{0,0,1,0},{0,0,1,0},{0,0,1,0},{0,0,1,0} },{{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}}};protectedintblockpattern5[][][]={{{0,0,0,0},{1,1,0,0},{0,1,1,0},{0,0,0,0}},{{0,0,1,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}},{{0,0,0,0},{1,1,0,0},{0,1,1,0},{0,0,0,0}},{{0,0,1,0},{0,1,1,0}, {0,1,0,0},{0,0,0,0}}};protectedintblockpattern6[][][]={{{0,0,0,0},{0,1,1,0},{1,1,0,0},{0,0,0,0}},{{0,1,0,0},{0,1,1,0},{0,0,1,0},{0,0,0,0}},{{0,0,0,0},{0,1,1,0},{1,1,0,0},{0,0,0,0}},{{0,1,0,0},{0,1,1,0},{0,0,1,0},{0,0,0,0}}}; protectedintblockpattern7[][][]={{{0,0,0,0},{1,1,1,0},{0,1,0,0},{0,0,0,0}},{{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},{{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},{{0,1,0,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}}};privateintblockpattern[][][];privateintblockNextpattern[][];privateintx;//blockpatternprivateinty;//blockpattern privateintoldx;privateintoldy;privateintrot;privateintoldrot;privateintpattern;privateintnext;privateKetrisMapmap;protectedRandomrand;publicKetrisBlock(KetrisMapmap){this.map=map;rand=newRandom();next=Math.abs(rand.nextInt())%7+1;}protectedvoidinit(){pattern=next;next=Math.abs(rand.nextInt())%7+1;switch(pattern){case1:readPattern(blockpattern1);break;case2:readPattern(blockpattern2);break;case3:readPattern(blockpattern3);break;case4:readPattern(blockpattern4);break; case5:readPattern(blockpattern5);break;case6:readPattern(blockpattern6);break;case7:readPattern(blockpattern7);break;}switch(next){case1:readNextPattern(blockpattern1);break;case2:readNextPattern(blockpattern2);break;case3:readNextPattern(blockpattern3);break;case4:readNextPattern(blockpattern4);break;case5:readNextPattern(blockpattern5);break;case6:readNextPattern(blockpattern6);break;case7: readNextPattern(blockpattern7);break;}x=5;y=0;rot=0;while(isCrashAtBegin()){y--;if(y<-4){break;}}oldx=x;oldy=y;oldrot=rot;}privatevoidreadPattern(int[][][]nowblock){blockpattern=newint[4][4][4];for(inti=0;i<4;i++){for(intj=0;j<4;j++){for(intk=0;k<4;k++){blockpattern[i][j][k]=nowblock[i][j][k];}}}}privatevoidreadNextPattern(int[][][]nowblock){blockNextpattern=newint[4][4];for(inti=0;i<4;i++){for(intj=0;j<4;j++){ blockNextpattern[i][j]=nowblock[0][i][j];}}}protectedvoidrotBlock(){rot++;if(rot==4){rot=0;}}publicsynchronizedvoidpaint(Graphicsg){if((oldrot!=rot)||(oldx!=x)||(oldy!=y)){g.setColor(KetrisCanvas.BACKGROUD);for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blockpattern[oldrot][i][j]==1){g.fillRect(KetrisCanvas.GAMEAREA_X+(oldx+j)*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+(oldy+i)*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.BRICK_WIDTH,KetrisCanvas.BRICK_WIDTH);}}}drawBlock(g);oldrot=rot;oldx=x;oldy=y;} }publicvoiddrawBlock(Graphicsg){for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blockpattern[rot][i][j]==1){drawBrick(KetrisCanvas.GAMEAREA_X+(x+j)*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+(y+i)*KetrisCanvas.BRICK_WIDTH,g,pattern-1);}}}}publicbooleanisCrashAtBegin(){for(inti=3;i>=0;i--){for(intj=0;j<4;j++){intmx=x+j;intmy=y+i;if(my<0){my=0;}if(blockpattern[rot][i][j]==1&&map.get(mx,my)!=8&&map.get(mx,my)!=0){returntrue;}}}returnfalse;}publicstaticvoiddrawBrick(intpx,intpy,Graphicsg,intcolorIndex){ g.setColor(255,255,255);g.fillRect(px,py,1,KetrisCanvas.BRICK_WIDTH);g.fillRect(px,py,KetrisCanvas.BRICK_WIDTH,1);intcolor=BRICK_COLORS[colorIndex];g.setColor(color);g.fillRect(px+1,py+1,KetrisCanvas.BRICK_WIDTH-1,KetrisCanvas.BRICK_WIDTH-1);g.setColor(0x00c0c0c0);g.fillRect(px+KetrisCanvas.BRICK_WIDTH-1,py+1,1,KetrisCanvas.BRICK_WIDTH-1);g.fillRect(px+1,py+KetrisCanvas.BRICK_WIDTH-1,KetrisCanvas.BRICK_WIDTH-2,1);}publicvoiddrawNextBlock(Graphicsg){g.setColor(KetrisCanvas.BACKGROUD);intpx=KetrisCanvas.GAMEAREA_X+12*KetrisCanvas.BRICK_WIDTH;intpy=KetrisCanvas.GAMEAREA_Y+2*KetrisCanvas.BRICK_WIDTH;intwidth=KetrisCanvas.BRICK_WIDTH*4;g.fillRect(px,py,width,width);for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blockNextpattern[i][j]==1){drawBrick(px+j*KetrisCanvas.BRICK_WIDTH,py+i*KetrisCanvas.BRICK_WIDTH,g,next-1);}}}} publicbooleancheckDown(booleankyouseiflag){booleancheck=true;for(inti=0;i<4;i++){introw=3;while(row>=0){if(blockpattern[rot][row][i]==1){if(map.get(x+i,y+row+1)!=0){check=false;}row=-1;}else{row--;}}}returncheck;}publicvoiddown(){y=y+1;}publicbooleancheckRot(){booleancheck=true;inttmpRot=rot+1;if(tmpRot==4){tmpRot=0;}for(inti=0;i<4;i++){for(intj=0;j<4;j++){ if(blockpattern[tmpRot][i][j]==1){if(map.get(x+j,y+i)!=0){check=false;}}}}returncheck;}publicbooleancheckMove(intdirect){booleancheck=true;for(inti=0;i<4;i++){if(direct==1){introw=0;while(row<=3){if(blockpattern[rot][i][row]==1){if(map.get(x+row-1,y+i)!=0){check=false;}row=4;}else{row++;}}}else{introw=3;while(row>=0){if(blockpattern[rot][i][row]==1){ if(map.get(x+row+1,y+i)!=0){check=false;}row=-1;}else{row--;}}}}returncheck;}publicvoidmove(intdirect){if(direct==1){x=x-1;}else{x=x+1;}}publicintgetY(){returny;}publicvoidfixBlock(){for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blockpattern[rot][i][j]==1){map.set(x+j,y+i,pattern);}} }}}KetrisCanvas类:importjavax.microedition.lcdui.*;publicclassKetrisCanvasextendsCanvasimplementsCommandListener,Runnable{protectedxuqhketris;protectedCommandexitCmd;protectedCommandstartCmd;protectedintgame;protectedKetrisBlockblock;protectedKetrisMapmap;protectedThreadthread;protectedintcounter;protectedintmaxCount;protectedfinalintGAME_INIT=0;protectedfinalintGAME_RUN=1;protectedfinalintGAME_OVER=4;protectedfinalintGAME_START_DEMO=9;protectedfinalintGAME_SUSPEND=9;protectedbooleanstartDemoFlag;privatestaticintmainWidth;privatestaticintmainHeight;publicstaticintGAMEAREA_X;publicstaticintGAMEAREA_Y;publicstaticintBRICK_WIDTH;publicstaticfinalintBACKGROUD=0x00000000; publicKetrisCanvas(xuqhketris){this.ketris=ketris;init();map=newKetrisMap();block=newKetrisBlock(map);startCmd=newCommand("开始",Command.OK,0);exitCmd=newCommand("退出",Command.EXIT,0);addCommand(startCmd);addCommand(exitCmd);setCommandListener(this);thread=newThread(this);thread.start();}protectedvoidinit(){this.mainHeight=getHeight();this.mainWidth=getWidth();intmin=mainWidth;if(mainHeight=0;min--){if(min%16==0){break;}}BRICK_WIDTH=min/16;GAMEAREA_X=(mainWidth-min)/2;GAMEAREA_Y=(mainHeight-min)/2;startDemoFlag=false;game=GAME_START_DEMO; }publicvoidrun(){while(true){try{thread.sleep(50);}catch(InterruptedExceptione){break;}repaint();}}publicvoidcommandAction(Commandc,Displayabled){if(c==exitCmd){ketris.destroyApp(false);ketris.notifyDestroyed();}elseif(c==startCmd){if(startDemoFlag==false||game==GAME_OVER){startDemoFlag=true;game=GAME_INIT;}else{if(game==GAME_SUSPEND){game=GAME_RUN;}elseif(game==GAME_RUN){game=GAME_SUSPEND;}} }}protectedsynchronizedvoidkeyPressed(intkeyCode){intaction=getGameAction(keyCode);if(action==Canvas.LEFT&&game==GAME_RUN){if(block.checkMove(1)){block.move(1);}}elseif(action==Canvas.RIGHT&&game==GAME_RUN){if(block.checkMove(2)){block.move(2);}}elseif(action==Canvas.UP&&game==GAME_RUN){if(block.checkRot()){block.rotBlock();}}elseif(action==Canvas.DOWN&&game==GAME_RUN){if(block.checkDown(false)){block.down();}}elseif(action==Canvas.FIRE&&game==GAME_RUN){if(block.checkRot()){block.rotBlock();}}} publicvoidpaint(Graphicsg){if(game==GAME_START_DEMO){if(!startDemoFlag){g.setColor(BACKGROUD);g.fillRect(0,0,this.mainWidth,this.mainHeight);g.setColor(0,255,0);g.setFont(Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font.SIZE_LARGE));g.drawString("欢迎进入俄罗斯方块世界",mainWidth/2,this.mainHeight/4,g.BASELINE|g.HCENTER);Fontf2=Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_PLAIN,Font.SIZE_MEDIUM);g.setFont(f2);g.drawString("Author1:浙江万里学院",mainWidth/2,mainHeight/2,g.BASELINE|g.HCENTER);g.drawString("Author2:徐钱浩(314024484@qq.com)",mainWidth/2,mainHeight/2+f2.getHeight(),g.BASELINE|g.HCENTER);g.drawString("Version:1.0",mainWidth/2,mainHeight/2+f2.getHeight()*2,g.BASELINE|g.HCENTER);g.drawString("2003-04-17",mainWidth/2,mainHeight/2+f2.getHeight()*3,g.BASELINE|g.HCENTER);}} elseif(game==GAME_INIT){map.init();map.paint(g);block.init();block.drawBlock(g);block.drawNextBlock(g);counter=0;maxCount=8;game=GAME_RUN;}elseif(game==GAME_RUN){counter++;if(counter>=maxCount){if(block.checkDown(true)){block.down();block.paint(g);}else{inty=block.getY();block.paint(g);block.fixBlock();if(map.check(g,y)){map.repaintMap(g);}block.init();y=block.getY();if(y<0){game=GAME_OVER;}block.drawBlock(g); block.drawNextBlock(g);}counter=0;}else{block.paint(g);}}elseif(game==GAME_OVER){g.setColor(BACKGROUD);g.fillRect(KetrisCanvas.GAMEAREA_X,KetrisCanvas.GAMEAREA_Y,16*KetrisCanvas.BRICK_WIDTH,16*KetrisCanvas.BRICK_WIDTH);g.setColor(255,0,0);g.setFont(Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE));g.drawString("GameOver",KetrisCanvas.GAMEAREA_X+8*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+4*KetrisCanvas.BRICK_WIDTH,g.BASELINE|g.HCENTER);}}publicstaticvoidclear(Graphicsg){g.setColor(0xffffff);g.fillRect(0,0,mainWidth,mainHeight); g.setColor(BACKGROUD);g.fillRect(KetrisCanvas.GAMEAREA_X,KetrisCanvas.GAMEAREA_Y,16*KetrisCanvas.BRICK_WIDTH,16*KetrisCanvas.BRICK_WIDTH);}}KetrisMap类:importjavax.microedition.lcdui.*;importjava.io.IOException;importjavax.microedition.media.Manager;importjavax.microedition.media.MediaException;importjavax.microedition.media.Player;importjava.io.InputStream;publicclassKetrisMap{protectedintmapdata[][];protectedbooleanmapBlockExist[];privateintscore;publicstaticfinalFontSCOREFONT=Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,Font.SIZE_LARGE);publicstaticPlayerplayer;static{try{InputStreamis=KetrisMap.class.getResourceAsStream("/chimes.wav");player=Manager.createPlayer(is,"audio/x-wav");} catch(IOExceptionioe){ioe.printStackTrace();}catch(MediaExceptionme){me.printStackTrace();}}publicKetrisMap(){mapdata=newint[16][12];mapBlockExist=newboolean[16];}publicvoidinit(){score=0;for(inti=0;i<16;i++){for(intj=0;j<12;j++){mapdata[i][j]=0;}mapBlockExist[i]=false;}for(inti=0;i<16;i++){mapdata[i][0]=8;mapdata[i][11]=8;}for(inti=0;i<12;i++){mapdata[15][i]=8;}mapBlockExist[15]=true;}publicintget(intx,inty){intdata=mapdata[y][x]; returndata;}publicvoidset(intx,inty,intval){if(x>=0&&y>=0){mapdata[y][x]=val;mapBlockExist[y]=true;}}publicvoidpaint(Graphicsg){KetrisCanvas.clear(g);for(inti=0;i<16;i++){for(intj=0;j<12;j++){if(mapdata[i][j]==8){KetrisBlock.drawBrick(KetrisCanvas.GAMEAREA_X+j*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+i*KetrisCanvas.BRICK_WIDTH,g,7);}}}}publicbooleancheck(Graphicsg,introw){booleandeleteFlag=false;inttmpRowNo;if(row+4>=15){tmpRowNo=15;}else{tmpRowNo=row+4;} for(inty=row;y0;i--){inttmp;if(mapBlockExist[i]){if(!mapBlockExist[i+1]){tmp=i+1;if(!mapBlockExist[i+2]){tmp=i+2;if(!mapBlockExist[i+3]){tmp=i+3; }}deleteRow(g,i);for(intj=1;j<11;j++){mapdata[tmp][j]=mapdata[i][j];mapdata[i][j]=0;}mapBlockExist[i]=false;mapBlockExist[tmp]=true;drawBlock(g,tmp);}}}}publicvoiddrawBlock(Graphicsg,inty){ for(intx=1;x<11;x++){if(mapdata[y][x]!=0){KetrisBlock.drawBrick(KetrisCanvas.GAMEAREA_X+x*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+y*KetrisCanvas.BRICK_WIDTH,g,mapdata[y][x]-1);}}}privatevoidpaintScore(Graphicsg){g.setColor(KetrisCanvas.BACKGROUD);g.fillRect(KetrisCanvas.GAMEAREA_X+12*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+6*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.BRICK_WIDTH*4,KetrisCanvas.BRICK_WIDTH*4);g.setColor(0,255,0);g.setFont(SCOREFONT);g.drawString(""+score,KetrisCanvas.GAMEAREA_X+14*KetrisCanvas.BRICK_WIDTH,KetrisCanvas.GAMEAREA_Y+8*KetrisCanvas.BRICK_WIDTH,g.BASELINE|g.HCENTER);}} 附录2毕业设计作品说明书一、作品名称基于J2ME平台的俄罗斯方块游戏二、作品功能1、能产生7种形状的下坠物,而每次下坠物产生的形状由这7种形状中随机产生。2、当任何一层被填满时,该层会消失,最多一次可以同时消除四层。3、当游戏屏幕的顶端被下坠物接触到且无法继续下落,则游戏结束,屏幕显示“Gameover”字样。4、游戏具有暂停功能。5、具有积分功能,每次消除任何一行积满行,都会得到相应的分数。三、运行环境硬件环境支持J2ME的无线移动网络端设备或PC机。软件环境需要安装JDK(JavaDevelopmentKit),JavaMEWirelessToolkit。四、操作步骤1、首先选择xuqh,按启动按钮进入游戏欢迎界面。2、然后选择开始,游戏开始后控制手机按键上边的下左右来控制下坠物的方向,左右控制方块左右移动,而向下为让方块加速下落,向上按钮则控制方块翻转。3.、当要暂停游戏时,只需按下右边的开始按钮,则进入挂起状态,再按下开始按钮游戏则继续进行。4、若要结束游戏,只需按下左边的结束按钮,让游戏结束,游戏欢迎界面、游戏运行状态和游戏挂起状态均可以按结束按钮直接结束游戏。五、注意事项1、运行游戏须同时满足硬件坏境和软件环境。2、本游戏没有胜利,如果游戏不输或玩家不退出游戏,则游戏会一直进行下去。