从零开始Android游戏编程(第二版).docx
从零起先Android嬉戏编程(其次版)作拧:邢野时间:2009-9-25MSN:xingye(at)sohu书目隔言3第一章搭建开发环境6其次年创建第一个程序He1.1.Onnk10第三欧显示文字和图片17第四章响应用户事务30第五章小结一一扫雷嬉戏的实现36第六章SUrfaCeVieW动Si39笫七章精灵、帧动画与碰撞检测46第八章地图的设计和实现62第九格嬉戏程序的生命周期75第十余嬉戏循环的设计86第I章演员(Actor),视口(ViewWindow),演出起先88笫卜二章音乐与f效94没想到重新打开这篇文档己经是一年之后了.去年三月,我停止了这一系列文理的写作.六月.点开了工作了五年的公司.作为公司的创始人和业务主管,我不能容忍它发展的如此馍慢,而合伙人却很享受这种慢节奏的生活,九月底,去了西一如期盼中的蓝天白云,宏伟的布达拉宫,漂亮的雅烈渣布江和梢微的高原反应,开车的刘师傅是个很懂生活的人,当他用个急转号将羊卓雍错推入我们眼帘的时候,林个人都惊呆了。原来照片上的颜色不是PS出来的!世界上真的有这么漂亮的湖!从高原下来到成都、长沙、武汉,问到了久违的母校,见到了阔别多年的队长和同学.才发觉不光是高原的美景能让人爬掩,久别的重逢一样能冲击人的心灵.当那"青春的记忆一瞬间被撩起,不知是不足暧和,不知是不是凌;.人,也笑了.酒,也醉了“南巡”归来,心中一卜少了许多杂念,或许是江山如画让人更觉人生苦短吧。既然自己对移动开发这么感受好,何不干脆寄情于此,忘掉什么web,忘掉什么ERP.于是IPad-MacBook隹上了书案,多年不用的C语言IR新检起,armXtoo1.cain.xcode,跨平台、交叉编译。生疏,熟识,可憎,M爱。突然发觉,原来自己还是喜爱学习,一把年纪了,还能觉得汲取学问是一个欢乐的过程,过程虽然曲折,前途却有光明.看到同一个程序在WindOWs.mac.ios.android都可以运行的时候,自己都有点“马在里不思议”的博觉.两个来月的学习、尝试最终有所收挨,恰在这时,又一封关于这一教程的掘件出现在了我的邮箱。犹如前面全部的邮件样,Xiangyang也想知道这个系列教程还彳i没有续集。很缺愣,它没有.自从我下定决心制作一个腌平分的框架之后,就放弃了对javaSDK的探究.我再爱java的干件快捷,但是我想更集中精力.当取得了阶段性成果之后,我很想让自己紧绷的神经放松一下,于是我对Xiangyang说“用一周的时间完成这个教程,以削然读者的缺憾”,这也就是大家在后面将看到的.些变更:从现在起先,不再运用OPhoneSDK、GoOgIe的新工具特别好,可以管理多个SDK版本,运用起来特别便利.而相比之卜OPhOne老海就太不给力了,还在吃CUpCake吧,别吃了.再吃噎到了.另外,我重新整理了随书源码.让大家运用起来更便利.呆络,许多人希望我能有个b1.og以便利沟通,所以本文将通过我的CSdn博客取新发布。其实我以前在javaeye卜.发过,可没想到javaeyeI:竟然行那么多脑残.看到OPhone就像看到他母亲的裸照一样不能容忍,纷纷想拿五毛钱买回去珍藏!?你啮不起它并不代表你就比它优秀,口的.邢好2011-1-10第一版前言什么是OPhOneOPhone是基于1.inUX、面对移动互联网的终端基础软件及系统解决方案.OPhOneSDK是专为OPhone平台设计的软件开发套件,它包括。PhOneAPI.OPhone模拟S.开发工具,示例代码和帮助文档(摘自OPone官方网站:).简而言之,OPhone是个移动终端的授作系统,移动终端包括手机、MID.NetBOok等等,与其他领域的编程一样.OPhone编程并没有什么神奇之处,只需筒沾的学习就可以驾驭大部分的概念,剩下的就是尽情发挥你的想象力了。写作本文的目的为(普及OPhone娟程的基本学问,并通过立刻一个坦克大战嬉戏让读者/解2D附戏编程的简洁思路.文中的程序结构和实现方法并非最优,希里能起到一个弛砖引玉的作用,让更多的人加入到OPhone开发的行列中来。询适合阅读本文虽然本文叫做“从零起先OPhOne编程”,但并不能面对那快时编程一窍不通的读者。事实上,本文要求读者了解java谓古的基本学问,以好会运用ec1.ipse.在文章的每个港节都标有难度,有实力的读者完全可以跳过相对简洁的奉节干脆阅读自己感爱好的内容。本文的时效性本文只适合当前版本的OPhoneSDK(v1.O),本文的代码、图片'链接可能会因时间推移而失效.第一章搭建开发环境难度:商洁工欲善其技必先利其涔.我们要做的第件事就是搭建Androki开发环境.本文只介绍Windows下的安装方法,Unux下的安笠方法请参考官方网站的介绍.与PC编程略有不问的是,Android的程序须要在模拟器中运行.因此,我们须要一个集成开发环境,一个SDK和一个模拟器,因为Android编程运用java语言,所以我们还须要JDK.最好运用安装版本0选用JDK6Update16Windows版即叽集成开发环境我们选用edipse.可以运用ec1.ipse3.3到3.5的加意版本O最好下毂JDT集成版。然后我们可以从Android官方网站。卜载AndrOidSDK(当然,假如你不能翻墙.可以到国内的网站下载).SDK全部安装完毕之后,还须要安装ec1.ipse插件.插件是用来扩展ec1.ipse功能的.开发AndrOidM的抽件叫ADT<AndroidDeve1.oper1.bo1.s),它可以帮助我们完成创建项目,向模拟器部署并运行程序,调试程序等工作。关于ADT的功能,在后面运用中我们会渐渐熟识.安装ADT的方法如下(以edipse3.4为例:后动ec1.ipse.选择菜堆中的He1.p->SoftwareUpdates点击AddSite点击Archive.找到OPhOneSDK安装竹目下too1.sophoneADT.z1.p(因为我己经安装好了ADT,所以出现了用复UR1.的提示),点击OK即可起先安装ADT安装完毕后还要简洁配置一下,打开菜单中的WindoW->Preferences找到Android项,通过BrowSe按钮指定AndroidSDK的安装位置JPreferencestypcEtAndroid«E.gGgngrdAndPreferencesJMSCK1.ocobon:MdevX84RCwSe.He)至此为止,Android的安装环境就全部搭建完毕了.下,章节,我们会遇见经典的he1.1.owor1.d.下空见!第二章创建第一个程序He1.1.oTank难度:简洁现在起先,我们要我正写作AndrOid程序广.虽然前面安奘过程那么困雄,但是写起程序来却是特别简洁.而口为了让大家有一个直观的相识,本文不会叙述大段的原理,而於在编码的过程中海透对原理、概念的讲解。让我们打开ec1.ipse,选择菜单中的Fi1.e->New->Project.选择Android->AndroidProjectwizards:FypefftcrtextfSaGencrdB2>AndroidAndroidProct出EcipseModeingvamewcxk由2Java0JavaScrjpt&eWcb三SVriget由<5Exage4下面须要我们输入项目的一些信息因为我们要复刻经典嬉戏坦克大战,所以我们的程序毁取名1nk这样,一个Android项H就创建完成了.我们UJ以在ec1.ipse的PackageExp1.orer看到我们的项目干(口JeSt口JmpG1.a(fdJcdct在;=ApDemoQdof1.ex由酒OouOiZhu&KetnsE',Md"QmineWServers1.CB>k(<STai白KSrCB田org.yex1.f>g.a±c4d.games.tank团E)Main.Java由E)R.>vaEAndroid1.brary&rc$S<>drawabteff1.1.ayoutWVdkJCS(QAndradManifestxmIJ托ADT的福虽然我伴只愉入了几个名字,但这个项目事实上已经可以运行了.右击项目名,选择RunAs->AndroidApp1.ication口皆:10口田testC1.oseWre1.atedProjectstest.AssgnWorbngSets.R>erv口Sbsr0三:aCopyQuaiftedNyneRaSte×QdeteCtr1.+VDetete;s-IIBuidPothSourceAfshft+5W.G3.RedactorAMSWfT*jImport.S(zExpQft.Eg11/RetrwhF5三(OpenProjectG.C1.OieProject不出意外的话,你会看到一个手机模拟器被启动,而我们刚刚建立的程序会被运行起来假如你发觉模拟器启动了,而程序弁没有被运行,可能须要F工总动程序.这里我们刖到个重饕的工具DDMS*Dav1.ikDebugManager).运行DDMS快捷方法是点击ec1.ipse右上角的OpenPerspective,假如在弹出的列表中没仃DDMS,服么点击OtherStte)选挣DDMS这样我们就打开了DDMS界面.这个:只我们以后会.常常用到.GN&CCC*arMB虫J1.J11WIcmm-BW*.O:-><-TKj>X刚刚说到模拟器启动了而程序并没有被运行,很可能是在模拟器扇动过程中DDMS失去了与模拟器的链接,解决方法很简沾:点击Devices标签下的工具栏,选择Resetadb然后右击项目名称,RunAs->AndroidApp1.ication.除了右击运行项I1.还UJ以通过工具栏上的运行按钮启动程序ksrcorgy>dn9ardroid*netd11icMainJava-rceRefactorHarv1.gateSaa,chProjectRunWrda*OI田G£4*PcdcageITark2NchitW3Sst-GRXdJcdctnoRunAsRuqConhgurabons.OfanCeFavorites.1在运行按用左边的是Debug按钮.这两个我们以后也会常常用到.现在我们己经有了第一个可以运行的AndrOid,虽然你可能对ADT生成的一堆文件感到一头雾水.也不知道程序界面上那一句"He1.1.oWorid,Main”是从哪里来的,但是没关系.随着本义的深化你会渐渐熟识AndrOId项目的书目结构,程序设计的原则和方法,以及调试和部署的方法.现在读者UJ以自己熟识一卜模拟器的操作,让我们下章再见。第三章显示文字和图片难度:简洁从本龙起先,读者就要媪写代码了.依据作者的原则少一些理论,多一些实践,代码中可能会有跳动的地方,但是请大家不要焦急,随着学习的深化,你很快就会了解我中的奇妙.不过在起先之前,我们还是要先来理地一下思路,看君完成一个坦克大战嫡戏须要哪线工作:首先,我们须要一个基本的程序,这个程序能够在Android上运行:这个程序要能膨显示图形包括地图,主角和NPC等等;程序能够接受用户的输入,限制主角移动:程序要能弗限制NPC和子弹的移动;程序还能时各种事务做出推断,比如击中敌人,获得初品,成功或者失败.现在我们就从基本程序起先,一步一步实现它.首先,让我们看一下刚刚生成的文件书目TankB-SrCB由org.yexing.android.Qamcs.tar由r3n,ava由£)R.)avaKaAndroid1.trary&assetsB6re$2>drawaWe1.ayout(S*va1.uesGAndrOidMWfes1.Xni在源文件书目下,只有MainJaVa和R.java两个文件,刚刚被我们命名成MainJava的文件就是程序的入U文件.而R.java是由插件来维护的资源定义文件.我们先不管它.Mainjava内容如下:packageorg.yexingandroidgames.tank;importandroid.ap-Activity;importandroid.os.Bund1.e;pub1.icc1.assMainextendsActivity(*Ca1.1.edwhentheactivityisfirstcreated./GOverridepub1.icvoidOnCreate(Bund1.eSavedInstanceState)super.onCreate(SavedInstanceState);SetContentView(R.1.ayout.main);)I很幸运,MainJava的代码特别之少,而且还行一段注择,以致我们很简洁知道函数Onereate的作用,须要说明的只是SetContentViewO.先不要管注择中提到的Activity和SetContentVIew的参数R.1.ayout.ma1.n.我们运用SetContentView的另一种形式:SetCOntentVieW(VieWview)SetCOntentVieW的作用是设定之前运用的视图即VieW(依此理解,可以彳!"许多个View.须要用哪个就可以把他作为SetContentView的参数显示出来).View是一个特别更要的殂件,它可以用来显示文字,图片,也可以接收客户的操作,比如触摸屏,城盘等等,而我们的婚戏中正是须要绘图和交互,看来VieW很符合我们的须要(但是请留意,运用VieW并不是我们的最终方案,缘由会在后面说明,此处介绍VieW是为了讲解基础的图形和用户限制.下面我们就要订制一个处F自己的View,可以通过继承自系统供应的View,并正我相关的函数来实现.创建类的方法如卜丁右击包名New->C1.ass*i«rerc«_rcApCWJC1.<k4¼啰DoUDehU口KetmMtfchRCJmnek?Jecvers曰SMrMhOCC's1.>ui>1.cc1.assBainextendsActivityNeNJXvePh>Wrm依!InstancesKate;,<k»1.ntoOpeninwWrxtow<*QTypeXerChyF4ShOttinAt÷SWt÷W士P*MQeG1.nte<fce,GEM名ArrMiW©SooCtRiMrFotoerE71皿3Vt台舟iWGrHCCopyQuaAedFiarre7RdrteGrt÷V×QMtCWt团MiTi.所0三团RMVGa.上一一.*3*W*WMfWF白StiS(resQAnodXWert.x«W5hBE.他口一C1.mj*dPh赳SWectc*»At÷t÷S»at÷wt+»HeUntriedTextFfe1.MtTwtC»eijaInpcrt.tiExport."t.,1.QhtrCfrkNRre11CMM我们将这个VieW类命名为GameViewJ1.fIiandroid.viev.View继承点击FiniSh,一个VieW类就创建好了。这里是第一次创隹类,以后就不会有图片演示了,请大家记住的这个方法.GameView创建好了,但是代码还有一些猫误,这里介绍一下edipse的运用技巧,将鼠标悬停在有错误的位置,或者将光标件在有错误的行,然后按CtrI+1键,就会出现修改建议,大部分时候,运用脩改隹议都可以改正我们的错误,如图pub1.icc1.assGwne5$,evextendsView<GIgDtsuperc5tructorViewoKnotSsHeforddconstructor.Mustde6ncconstructor4quickfesava1.atte:<fAddCCCNrUCS1.Qrne¾M)'rcrhrtf2Gmew(CtCXtY>zi.D11jC,j<AddCon5。Ua0'8meMew(CCnteX1.Attibutefetj110'可以看出来,刚刚的错误是因为没孑j创建构造函数,选择修改建议的其次项,增加个构造南数pub1.icGaineView(Contextcontext)(super(context);/TODOAuto-generatedconstructorstub我们的VIeV/就创建好了。W1.到MainJava,刚刚说了,只要将VieW作为SetContentVieW的参数,这个VieW就可以被显示出来:pub1.icvoidOnCreateiBund1.eSavedInstanceStateI(super.onCreate(SavedInstanceState);SetContentView(newGameView(this);现在让我们运行模拟器.价价程序变成什么样子(启动模拟器的方法见其次章).不要意外,屏邦上就是一片空白.因为我们创建了一个View,但是没有让它显示任何内容.下面我们就会在VieW上显示一段文字和一张图片。让View显示内容也很简洁.只须要'RCcView的OnDraw函数,把相应的语句写入OnDIBw中即可。打开GameVieWJava.点击菜单Source->Override/Imp1.ementMethod.Java-TanksrcorgyexingadroidganestankMai.fava-R1.eEditSOUr8RedactorNa¼geeSearchRroectRunWhdIr”;YOggbCommentAddBhdXcmrner/:QrWCtd÷Shft+/亡W字RemoveBtockCcffmcntQd+SMt+GenerateEJmcrComcrtA1.t+Shft÷JShftRightStjft1.cftCorrectMenfcabonFcrmatFOfTn成EtemeQJQJari三-2ECM÷ICtr1+Shft÷F1.三AjImportOrganizeJnportsSfifttrrbcrs.CteanuPCM+Shft÷MCtH+5hft+0OverrkfeJInroIementMethods.IkA1&由心a<.f.S猥MGenerateGettersand5ters.GenerateDetegaCeMethods.GenerXehshCode()Sdequak().GenerateConstructorusingAdds.GenerateConstructorsfromSuperc1.ass.i日后!USirrcwndWhAJt+Shift+ZCt:Extemoizcarngs.FndB*c<Externa1.zed9zngs选中onDraw点击OKSetectmethodstooverrideorimp1.ement:pvArt±dToW11dow()CnereeteConteXtMenU(CoNeXtMenU)OCreatoCabfeState<nt)OSDetaChedFfcmWkndowO±1=二ES OCnFniShInf1.ateo GCCFOaJSChargeaboOiean,叫Rect)口KeyDown(ir,KeyfvcnQ CnKey冲JE1.e(Int,i*KeyEvent)ZJ<I2J*OverrideZImpIenientMethodtSeiert61QesdectAJIInsertionpoint:After'GameVBcw(Context)*3VGeneaemethodcommentsTheforma1.erfthemethodstubsmaybeconfiguredontheCOdeTerrC)欣Upreferencepoge.i1.of229se1.ected.下面这段代码就会被加入到程序当中,全部与显示有关的代码都会在这里面完成0OverrideprotectedvoidonDrawICanvascanvas)(I1.TODOAuto-generatedmethodstubsuper.onDraw(canvas);J这里我们遇到广乂个特别重要的类CanVas.Canvas股御洋成画布,全部的绘图操作都是通过CanVaS中的函数来完成的,比如显示文字的函数CanVaS.drawText(),显示位图的函ftCanvas.drawBitmap()»以及各种绘制图形的函数如Canvas.drawRect().Canvas.drawArc()等等.下面让我们显示段文字在屏幕上:protectedvoidonDraw(Canvascanvas)(/TODOAuto-generatedmethodstubsuper.onDraw(canvas);canvas.drawTe×t(*!j,SO.SOrnewPaint();18:44CZJEI川CmaMobi1.eCMCC一一I.IQI1.R坦克大联坦克大战四个字己经出现在了屏幕上。让我们来具体6下这条语句;CanVaS.drawText(,'坦克大叔",50,50,newPaint<);笫一个参数是要显示的文字,其次、第三个参数是文字在屏林上的坐标,说到坐标得多讲两句.在2D编程中.疥幕坐标的原点是屏传的左上角,横向向右增大,纵向向下刷大,如上图所示。域终一个多数是Paint,通常的锋成画佬,它确定了文字或图形的颜色,字体,戏条粗细等等,后面用到相应屈性的时候会具体介绍.那么这条i音句就是在屏幕上(50.50)的位较用缺省的画笔写出“坦克大战”四个字.另外假如ec1.ipse提示代码错误,不要忘了用Ctr1.+1.有了文字,下面就是图像了。显示图像比显示文字略做困难一些,首先我们要打算张位图,图片必需是Png格式的,文件名只能是小写字母,数字和卜划线。CITVbattiedty.png然后将这张图片py到J:程的res/drawab1.e书目下.可以干脆在ec1.ipse的书目树中菇贴.6(29SrCffiofg.yexng.androri.games.tank用近GafheVieWJaVa©工Man.java三i£RJaVaMAndroidUtxeryBassetsF1.&re$drwab1.e battiecty.png ko.png显示位图的函数是Canvas.drawB<tmap().drawBitm叩行许多种形态,我们先看其中最徇沽的一种canvas.drawBitmapIbitmapr1.eft,toprpaint)乍哧似乎和drawText更不多,4个参数行三个都相同,但这第一个参数bitmap要比文本困难得多,首先,他是个BitmaP类实例,因为我们现在还不须要这个类的其他功能,所以不过多介绍Bitmap,只考虑它是怎么来的。得到BitmaP实例的方法也有许多种,这里只介绍其中的一种SitmapE-actory.decodeResourceres,id);此方法可以返回一个bitmap实例,但是这个函数还须要两个梦数res和idresResources实例,而id是一个整数,下面让我们分别了情这两个参数.res的地位跟bitmap差不多.只须要作为卷数被运用,因此,只要得到实例就可以了,获得ReSoUrCeS实例的方法如下:res-context.getResources(>天加,事情越来越困难九因为这段代眄里面有多了一个生Xfi而孔context,contextConteXt实例,COntext通常翻译做上下文,这个名称似乎有点膨涩,他原委是什么呢?让我们回头看看写好的程序pub1.icGameView(Contextcontext)(super(context);/TODOAuto-generatedconstructoratb这时候我们有一个COnteXt实例,接着朔源而上,在MainJaVa中pub1.icvoidOnCreateBund1.eSavedInstanceState)(super.onCreate(SavedInstanceState);SetContentView(newGameView(this);原来,context折向Main类.好心我们最终找到res的源头了.还有另外一个分支其次个参数id.BitmapE,actory.decodeResource<resrid);id是一个整形,它究竟是谁的id呢?我们还是得往前面找,还记汨我们笫软见到函数SetContentVieW用什么样子么SetContentView(R.1.ayout.main);时,他的参数是R.1.ayout.ma1.n,后来被我们牌换成了GameVieW实例,RJayout.main就是个整数。它被定义在文件RJdVa中,我们前面讲过RJaVa是由插件维护的资源定义文件,说到这里大家应当猜到了吧C让我们打开RjaVa文件pub1.icfina1.c1.assR(pub1.icstaticfina1.c1.assattr)pub1.icstaticfina1.c1.assdrawab1.e(pub1.icstaticfina1.Intbatt1.ecity=0×7f020000;pub1.icstaticfina1.inticoni-07f020001;)pub1.icstaticfina1.c1.ass1.ayout(pub1.icstaticfina1.intmain-0×7f030000;Jpub1.icstaticfina1.c1.assstring(pub1.icstaticfina1.intapp_nacne-0x7f040001;pub1.icstaticfina1.inth1.1.o=07f040000;)果真,住图文件battedty.png在:这里面也被安排了一个id:R,drawab1.e.batt1.ecity,没出.就是它了.这就是我们要找的id,至此为止.我们最终可以运用CiQwBitmdp1.时于次创建,多次运用的资源,我们把他放到构造函数出面,增加了图形显示的GameVieW如下:pub1.icc1.assGameViewextendsViewBitmapbmp;pub1.icGameView(Contextcontext>(supercontext);/TODOAuto-generatedconstructorstubResourcesrescontext.getResources();bmp=Bit11xapFactory.dcodeRsource(resfR.draNab1.e.batU1.euity);eOverrideprotectedvoidonDraw(Canvascanvas)(/TODOAuto-generatedmethodstubsuper.onDraw(canvS);canvas.drawText(mXS,Or50rnewPaint);canvas.drawBitmap(b<npr0,100rnewPaint();运行效果OwmMocaiCMCCTank第四章响应用户事务上一章介绍了如何显示文字和图片,一般来说,下一步就该讲到动画了0可是我们前面说了,运用VieW不足最终的选择,要实现动画还须要许多困难的代码.相对来说,学习如何响应用户事务要简洁些,本章前半部分讲解按键事务的响应,但是这也不是最终方案,因为事实上的手机可能没布硬键盘,须要运用虚拟键盘,所以后半部分我们会讲解湿拟键盘的设计和实现,同绘图一样,View也是通过IU1.调函数来响应用户耶务的.谈盘事务的回门函数有多个,以对应不同的事务,我们短哲只用到OnKeyDOWn,对应按键被按卜的事务,其他函数以后用到再介绍.让我们重载OnKeyDown(理我一个函数的方法前而章节仃介绍):0Overridepub1.icboo1.eanOnKeyDown<intkeyCoderKeyEventevent)/TODOAuto-generatedmethodstubreturnsuper.OnKeyDown(keyCodejevent);JOnKeyDOVmfj两个参数:keyCodeevent.通过keyCode能推I折是哪个犍被按下,event比较困难,包含了这次按键更多的信息,我们短的先不考虑它。现在我们要通过按键限制主角向四个方向移动,所训移动,就足将主角的图像在不同的位置显示出来,也就是变更函数drawBitmap中的其次、第三个参数,比如用户按下右方向键,我们就把横坐标增加,这样下次显示出来的时候,主角就会往右一点。为了节约时间,我们就把刚巧显示的图片BattieCity作为主角好/首先定义两个全局变量X和.然后在OnKeyDOWn中变更x、y的伯,然后也绘View.因为代码没有什么难度,所以不做讲解了.pub1.icc1.assGameViewextendsView(intx=0,y三0;GOverrideprotectedvoidonDraw(Canvascanvas)(canvas.drawBit11ap(kxnprxry,newPaint()>JeOverridepub1.icboo1.eanOnKeyDown(intkeyCoderKeyEventevent>/TODOAuto-generatedmethodstubswitchIkeyCode)caseKeyEvent.KEYCODE_DPAD_UP:y-=10;break;caseKeyEvent.KEYCoDE_DPAJDOWN:y+=10;break;caseKeyEvent.KBYCODE_DPAD_1.EFT:x-三10;break;caseKeyEvent.KBYCODE_DPAD_RIGHT:×+-10;break;)POSCInva1.idate();通知系线,SViewreturnsuper.OnKeyDown(keyCodezevent);J完成后我们确定很想测状一下,但是此时你会发觉,按键根本没有任何反应。这就是我们要特殊指出的地方.VieW被显示时.胡省状况下没行获得焦点,就是说.按犍动作没有发送给VieW,所以须要在构造函数中增加句pub1.icGameView(Contextcontext)(SetFocusab1.e(true);再运行程序,看看图片是否依据我们的指令运动起来(.前面说过,许多手机没彳i硬键盘,所以我们须要一个软选做的解决方案,软键盘就是在疥恋上显示一个键盘,然后响应用户的触摸屏操作,模拟成携盘操作.对于坦克人战,我们只须要在屏招上显示一个模拟的嬉戏手柄(显示图片的方法大家没彳r遗忘吧,显示位置可以依抠模拟器白行调整):在用户触摸模拟手柄上的方向雄和开火犍时进行相应的撩作,我们拿方向便做演示,步骤如K:首先确定四个方向键在屏林上的区域(上图的红色方框),然后在触摸屏事务的响应南数中推断东务是否发生在方向键区域中.最终假如事务发生在区域中进行相应的操作.下面,我们引入一个特别有用的类ReCt(ReaF与Rea基本相同,不过以f1.oat作为坐标卷数),rect是rectang1.e的简写.顾名思义,这个类代表一个矩形.Rect通过掂形4个边来定义这个矩形的范围他们分别是Ief1.right,top.bottom.如图所示:转化为屏嘉坐标,top是矩形坐上角的纵坐标.Ieft是矩形坐上角的横坐标,right是矩形右下角的横坐标,buttom是右下角的纵坐标.有了Reet我们就可以便利的表示虚拟手柄各个道的位置,同时ReCt还供应了一线很有用的函数,其中ReCtContainS(x,y)能终推断点(x,y)是否在矩形框中,正好是我们纪要的.现在我们就可以起先桀码了,首先为虚拟谈笈的方向键创建ReCt(可以用绘图工具测砥坐标):ReCtrKeyUp=newRect(56,290/86r320);RectIKeyDoWn=newRect<56r350,86,380);RectrKey1.eft-newRect(26r320,56,350);RectCKeyRightnewReCt(86,320,116,350>然后重载触摸辨响应函数:9Overridepub1.icboo1.eanOnTouchEvent(MotionEventarg)I1.TODOAUto-generatedmethodstubreturnsuper.OnTouchEvent(arg);下面我的要做的是首先推断触摸屏操作是不是按下下如是.下得坐标(X.y).然后推断坐标所在的按键,做出相应的操作®Overridepub1.icboo1.eanOnTouchEvent(Mo