基于J2ME平台的手机游戏程序开发 (手机游戏)毕业设计及论文_第1页
基于J2ME平台的手机游戏程序开发 (手机游戏)毕业设计及论文_第2页
基于J2ME平台的手机游戏程序开发 (手机游戏)毕业设计及论文_第3页
基于J2ME平台的手机游戏程序开发 (手机游戏)毕业设计及论文_第4页
基于J2ME平台的手机游戏程序开发 (手机游戏)毕业设计及论文_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGE基于J2ME平台的手机游戏程序开发摘要随着手机的日益普及、Java功能在移动设备上的实现,Java应用程序产生的手机增值服务逐渐体现出其影响力,对丰富人们的生活内容、提供快捷的资讯起着不可忽视的作用。本篇论文共分为五个部分:包括引言、J2ME技术概览、开发环境及相关技术、游戏设计和具体设计。其中具体设计是本篇论文的重点。整篇论文都是围绕着这一部分来展开论述的,在这一部分里详细介绍一款借助J2ME的MIDP类库开发手机游戏的全过程。关键词:手机游戏J2MEMIDPAbstractMobilephonevalue-addedservicehasbeenmakinganonnegligibleimpactonenrichingpeople'slivesandsupplyingfastinformationsasresultofincreasingpopularityofmobilephoneandimplementationofJavatechnologyonmobileequipment.Thispaperisdividedintofiveparts:includingintroduction,J2MEtechnologyoverview,developmentenvironmentandrelatedtechnology,gamedesign,andthespecificdesign.Onespecificdesignisthekeypartinthispaper.ThewholethesisisbasedonthisparttodiscusswhichdetailsthefullprocessofcellphonegamedevelopmentbasedontheMIDPclasslibraryofJ2ME.Keywords:mobilegameJ2MEMIDP

目录1.绪论 11.1J2ME的背景与应用现状 11.2手机游戏的发展现状 21.3研究目的与内容 22.J2ME技术概览 32.1J2ME简介 32.2J2ME体系结构 32.2.1 JVM(虚拟机) 32.2.2J2ME配置 42.2.3 J2ME简表 42.3移动设备上游戏的限制 52.3.1 内存 62.3.2 手机的界面 62.3.3 缺少库文件支持 63.开发环境及相关技术 83.1游戏开发环境 83.2关于WirelessToolKit 84.《勇闯伏魔洞》RPG游戏设计 94.1游戏简介 94.2游戏的流程和类结构 94.2.1游戏的基本运行流程 94.2.2游戏的类结构 94.3图像和动画渲染 104.3.1 GameCanvas 104.3.2 Layer 114.3.3 LayerManager 114.3.4 Sprite 114.3.5 TiledLayer 124.4游戏画布类Game_Canvas的实现 124.4.1Game_Canvas继承GameCanvas类,用来实现整个游戏的主界面 124.4.2此游戏画布类中主要的实现 144.5游戏的运行 235.总结 25谢辞 26参考文献 27XXXXXXXXXXX毕业论文-PAGE27-1.绪论1.1J2ME的背景与应用现状自Java问世以来,SunMicrosystems已成功地将Java平台技术推广到台式机及服务器。随着移动电话和个人数字助理(PDA)的日益普及和性能的不断提高,将Java技术应用于移动设备这个发展方向,将在未来得到更高的重视。J2ME(Java2MicroEdition)是为小型设备设计的Java平台。它包含专门设计的轻量级虚拟机,一个最小化的核心库和标准Java库的轻量级替代物。J2ME是无线PDA和高性能的移动电话的理想移动客户机平台。SunMicrosystems将J2ME定义为“一种以广泛的消费性产品为目标的高度优化的Java运行时环境,包括寻呼机、移动电话、可视电话、数字机顶盒和汽车导航系统。”自从1999年DeveloperConferencence上声明之后,J2ME为小型设备带来了Java语言的跨平台功能,允许移动无线设备共享应用程序。在另一方面,随着移动通信技术的高速发展,移动设备的性能日益提高,同时用户对于移动设备上应用程序的需求也越来越多。但是,移动设备制造商本身的软件开发能力和资源都有限,无法充分满足用户的需要。同时,由于以前主要移动设备上的程序主要用C语言开发,并釆用专用的操作系统,其他众多软件开发商也无法为其开发新的应用程序。这种两难的局面严重的限制了移动设备上新应用的推广于普及。Java技术的开放性、安全性和庞大的社会己有资源,以及其跨平台性,即“编写一次,到处运行”的特点,使Java技术成为智能手机软件平台的事实标准。采用Java技术后,编写应用程序和提供服务的人就不必关心接受其服务的手机采用的是什么操作系统和芯片,只要按照Java的要求写出的程序就可以运行;同样,生产手机的厂商也不必顾虑将来谁来提供增值服务。可以看出,釆用Java技术,可以建立完整、高效的无线数据增值服务产业链,从而为用户提供灵活、个性化、内容方式多样的服务。如今支持Java己经成了主流手机的标准,支持下载新的Java应用也是手机的一个重要卖点。到2005年6月,全世界已经有大约1亿部Java手机在使用,除中国大陆外共有53个移动运营商正式推出了基于Java技术的无线数据增值服务。在国内,中国移动通信集团已经建立了无线Java增值服务体系,并推出了“百宝箱”等服务品牌,包括游戏百宝箱、娱乐百宝箱、商务百宝箱、生活百宝箱等,己经于2003年中国联通公司也正在其CDMAIX网络上建立无线Java增值服务体系,目前系统正在建设过程中,并且2003年9月26日中国联通、北京振戎融通公司和Sun公司在人民大会堂宣布联合发起成立“UniJa技术联盟”1.2手机游戏的发展现状所谓“手机游戏”,就是依托移动通信网络运行在手机终端上的游戏。从诞生到现在,手机游戏经历了从最初的简单文字类游戏、简单的图形界面游戏到可下载的单机版游戏再到大型手机网络游戏的发展历程,手机游戏的业务形态日益成熟,展示出广阔的市场前景。有关机构预测,在未来5年里,手机游戏将在欧洲形成30亿欧元的大市场。另据IDC预测,到2006年,手机游戏业务的软件、硬件及服务所带来的收入将达到40亿美元。近两年来,手机游戏业务在日韩等国已经显示出勃勃生机,成为一个潜力巨大的文化产业。以日本NTTDoCoMo目前的经营状况为例,移动游戏己经成为该公司的重要收入来源。日本最大的游戏网站BanDai拥有200多万用户,每个用户每月平均花2.75美元在i-mode手机上玩游戏,这为DoCoMo和BanDai带来约550万美元的收入。与日、韩等国相比,中国的手机游戏市场起步比较晚,但中国有一个巨大的手机用户群,手机游戏拥有广阔的市场前景。目前,在中国有8000多万电脑网络用户,而中国的手机用户却已经超过3亿。与PC游戏不同,手机游戏摆脱了线缆的束缚,具有随时、随地、随身的特点,更适合人们在移动中休闲和娱乐。显然,手机游戏产业一旦启动,其能量将不亚于目前的电脑网络游戏。数据显示,2004年中国手机游戏市场规模超过8亿元人民币,预计在2005年手机游戏产业市场规模将达到14.41亿元人民币。虽然目前手机游戏用户数只占3亿用户的很小一部分,但随着手机游戏产业发展环境的日益成熟,其发展速度将一日千里。1.3研究目的与内容基于移动设备的应用软件,从以前的只提供基本的语音,通讯录和SMS功能,到后来提供WAP(WirelessApplicationProtocol)等基本的附加应用,再到目前逐渐丰富的各种应用。J2ME平台的出现,为第三方软件开发商为移动设备开发应用软件带来了极大的便利,开发商可以方便的将应用软件移植到移动设备上。丰富的Java资源和Java开发人员,可以大大的缩短开发周期。同时也可以为移动应用提供在线升级和动态下载的服务。本次研究的目的主要在于分析基于J2ME平台进行手机游戏开发所用到的核心技术,如绘图、图形与动画显示,响应用户输入,网络通讯。并且还要针对J2ME平台本身的缺点,以及具体的应用,提出自己的改进方法和解决方案。2.J2ME技术概览2.1J2ME简介SunMicrosystems公司将J2ME定义为“一种以广泛的消费性信息产品为目标的,高度优化的java运行时环境”。它主要针对消费类电子设备,例如,蜂窝电话和可视电话、数字机顶盒、汽车导航系统等。J2ME技术在1999年的JavaOneDeveloperConference大会上正式推出,它将Java语言与平台无关的特性移植到小型潜入式设备上,允许移动无线设备之间共享应用程序。在消费电子和嵌入式设备领域,内存从几百KB到几十MB,从没有屏幕到Web-TV,CPU从低功耗的嵌入式处理器到几百MHz的RISC处理器,硬件条件的差异是相当大的。这就使得J2ME的标准需要有不同的层次和类别来适应这个复杂的领域,因此相比之下J2ME就比J2SE和J2EE的标准要复杂得多。尽管如此,J2ME在适用于这些设备的同时也保留了Java的传统特性,即代码具有可移植性、部署灵敏性、安全的网络传输性和代码的稳定性等。因此,J2ME目前已经被广泛应用于消费类嵌入式设备,成为嵌入式开发的一种标准。2.2J2ME体系结构从整体看,J2ME平台由以下几部分组成:●Java虚拟机,针对不同的嵌入式设备以及为了满足不同的需要,提供了KVM和CVM两大虚拟机。●配置(configuration),它是将某一类特定应用范畴的设备的共性提取出来形成的规范。为开发人员提供了最基础,能在所有平台上通用的核心API类库。●简表(profile),它是将某一个特殊行业或领域内的设备的特性提取出来,形成对特定领域特性的总结,是作为配置的一个补充。●一些可选包,主要包括设备厂商提供的OEM的API类库。其中前三项组成了J2ME的基本运行环境。其中Java虚拟机是运行环境的核心,其运行于设备中的操作系统之上,再往上是具体的J2ME配置,包括更具设备的资源需要而提供的基本核心API类库,配置的上面是一个或者多个针对不同应用领域而设置简表。JVM(虚拟机)JVM是专门为微型电子设备与资源受限设备如:手机、寻呼机、移动互联网设备、家用微电子设备等设计的一种轻便、紧凑的JAVA虚拟机。JVM可以为微型电子设备提供一个完整的JAVA运行环境,除了一些微型设备所必需的适当的功能有所不同外,它是由JAVA虚拟机规范定义的真实的JAVA虚拟机。它是专门为那些受资源限制,只有几百K字节内存的微型设备设计的。基于上述原因,JVM具有以下几个特点:(1)小,仅具有40KB至80KB的静态内存;(2)轻便、精巧;(3)模块化并可定制;(4)尽可能完全紧凑的完成设计目的。2.2.2J2ME配置配置是将基本运行的环境定义为一套核心类和一个运行在特定类型设备上的特定的虚拟机。J2ME中提供了两种配置:CLDC和CDC。CDC针对的设备主要是数字电视、机顶盒、网络电话、车载计算设备,特点是有线连接,稳定而持续的电源供应,设备资源比较受限。CLDC支持的设备主要包括无线电话、手机、PDA以及小型零售支付段等。处理能力较弱,只包含程序运行所需要的最小类库。J2ME简表简表是面向配置之上纵向设备,建立在配置的顶部,定义了配置之上受支持设备的类型。目前J2ME领域里使用最广泛的是移动信息设备简表(MIDP),主要针对手机和其他双向移动通信设备而设计的。MIDPlet的开发环境需要有java2SDK1.3版以上与MIDP的类库、以及后述的运行前验证工具三种。在J2MEWTK中除了包括MIDP的类库、运行前验证工具之外,还会把编译与包装(JAR文件化)、JAD文件的创建、模拟器的启动等在开发MIDP需要用到的操作加以集成。当完成了JDK1.4以及J2MEWTK的安装以后,就可以开始对游戏项目进行创建了。MIDlet开发的基本开发流程如下:(1)编写MIDlet程序源代码;(2)编译MIDlet程序;(3)对编写后的类文件进行预校验;(4)编写清单文件MANIFEST.MF;(5)对MIDlet程序进行打包;(6)编写Java应用程序描述符(jad)文件。MIDlet文件的构成:(1)JAR(JavaARchive)文件:集成了ClassFile与图像、声音等内容的数据文件,虽然与J2SE的文件相同,但是列表的文件内容不同;(2)JAD(JavaApplicationDescriptor)文件:指定启动的MIDlet类名称或是数据文件大小、版本等信息;(3)KDDI的地方,使用组合了JAR文件与JAD文件的KDDI专用的KJK(KDDIJavaeXtension)。生命周期是指程序从开始执行到退出的生命过程。MIDlet是以下列的生命周期来运行的:(1)系统调用继承自MIDlet类的默认构造方法,创建对象;(2)系统进入MIDlet生命周期的暂停状态,这个是MIDlet生命周期的第一个状态;(3)系统调用startAPP()方法,然后进入MIDlet的运行状态,程序正常执行;(4)如果在暂停转台或者运行状态下发生错误,则程序会调用destoryAPP()方法,然后进入销毁状态。整个过程如图2-1所示:图2-22.3移动设备上游戏的限制在开发J2ME移动游戏过程中,开发人员面对的最大的困难和障碍是,本来在PC机和控制台上习以为常的应用在移动设备上却遇到各种限制,包括内存的、屏幕尺寸的、甚至色彩的限制。由于游戏中的用户输入、图形图像、动画、声音和振动的高交互性,这种限制在移动游戏中表现得比移动应用程序更加明显。此外,不仅要注意不同制造商之间产品的不同,也要了解同一个制造商的不同移动设备模型的差别。不同手机的模式在内存、色彩、屏幕尺寸和用户界面等各个方面都有很多不同。内存一般情况下,内存被认为是内存区域中的堆栈,在游戏执行的时候储存信息,在游戏终止后被释放。显而易见,手机上可以使用的内存总量要比PC机上少的多,因此在开发游戏的时候,要先查看所针对机型的内存容量,注意自己程序内存使用情况,已防止需要的内存空间超过可以分配的大小。另外的存储空间包括RMS(RecordManagementSystem)。它可以用来存储玩家的最高分数或者上次保存的设置。可供使用的RMS大小也是要注意的。PC机上的硬盘和内存在使用一段时间后就会出现碎片,在手机的存储空间上也会出现这种情况。例如需要写一个大的对象到内存中,但是却找不到足够的一整块连续的空间,于是系统就将它分成几块分别存储在内存的各个空闲空间中。这不但会导致存储空间访问时间的增加,当内存中大的对象被清除后会留下很多内存空洞,从而导致新的对象被存储时也会遍布内存各处。手机的界面最近几年,各个手机制造商开始放弃传统的手机界面,进而追求更为个性化的按键和控制,这归结于制造商对更加友好的用户界面的孜孜不倦的追求。虽然一些制造商已经意识到没有绝对最好的用户界面,只有对某些有特殊需求的特定的群体比较好的用户界面,这主要取决于用户除了使用手机打电话外还做什么,比如听音乐、玩游戏、或这记录商业事件。当然,新界面的设计也扩展了手机市场的边界和吸引力。这意味着又增加了开发者需要考虑的一个因素,比如,把数字键“5”设定为攻击,但是也许在某些手机上这个键不是很方便就可以按到的。缺少库文件支持由于J2ME是J2SE的子集,所以它并没有包含所有的包和类。也就是说要么不使用这些类,要么自己扩展所需要的类。例如,J2ME中不支持浮点数(float),故不能进行小数运算,也不能使用sin、cos和tan运算,但是在游戏开发中,小数是经常要用到的。然而,可以用定点数学运算的方式来代替小数运算。比方说,如果想精确到小数点后三位,可以用1000来表示1.000。在变换的过程中要不断的乘以或者除以10,以得到正确的结果。至于角度可以用0、30、60、90、120、150、180、210、240、270、300、330、360这种对应角度值的整数值来代替,事实上由于移动设备的屏幕往往都很小,所以太精确的计算也是没有意义的。3.开发环境及相关技术3.1游戏开发环境操作系统:MicrosoftWindowsXP程序语言:Java2开发包:Java(TM)2StandardEdition(5.0)SunMicro.J2MEWirelessToolKit2.23.2关于WirelessToolKitWTK(WirelessToolKit)是Sun公司针对J2ME推出的用于手机和Palm等移动设备的开发包,是除手机厂商的专用开发包外唯一的手机模拟器开发包。它通用性高,开发出的应用程序可保证能运行在大部分设备上,而不像专用厂商具有一定的不兼容性。虽然它没有强大的功能和完善的调试手段,但它提供运行模拟器的最基本组件,是其他IDE需集成采用的必备元素。目前我们可以获取的有四个版本,分别是1.0.4,2.0,2.1和2.2。每个版本都包括英语,日语,简体中文,繁体中文4个语种包。(1)1.0.4版只能够开发MIDP1.0(2)2.0版只能够开发MIDP2.0应用程序;(3)2.1版则可以同时开发MIDP1.0、JTWI(CLDC1.0,MIDP2.0,WMA1.1)可改用CLDC1.1或加入MMAPI1.1,自定义(自己随机组合Configuration,Profile以及OptionalPackage)三种环境下的应用程序;(4)2.2版中,WTK全面的支持JTWI规范。具体的说,即MIDP2.0,CLDC1.1,WMA2.0,MMAPI1.1,WebServices(JSR172),FileandPIMAPIs(JSR75),BluetoothandOBEXAPIs(JSR82),and3DGraphics(JSR184);同时您也可以使用该版本开发面向CLDC1.0和MIDP1.0的应用程序。系统要求上,WTK2.2至少需要50MB可用硬盘,128MB系统RAM和800MHZPentiumIIICPU。4.《勇闯伏魔洞》RPG游戏设计4.1游戏简介这是一款益智游戏与RPG角色扮演类的结合,主要还是以RPG类型为主,利用益智游戏的休闲可玩性和RPG角色扮演的故事扩展性相结合,把益智游戏的玩点和RPG的耐玩结合到一起,给玩家一个全新的感受。游戏的主要情节是游戏中的主角不经意间通过一款网络游戏穿越来到了西元一九五年的西凉召德村中,无意间卷入了一场鬼魅的阴谋之中,从此背负了一个巨大的使命——拯救所有被鬼魅抓走的人。游戏通过做指定的几个任务,完成任务通过游戏。游戏采用“踩地雷”遇敌方式,同时进入战斗场面,进行游戏。游戏中玩家需要和各个NPC对话找到相应的任务线索完成任务,其中共有十一个NPC,主角根据NPC的对话找出线索完成任务,其中与三个NPC对话会进入相应的任务场景,需要玩家自己和NPC对话找到。这样设计是为了增加游戏的可玩性和故事性。为了增加游戏的难度我们特意设计了人工智能这个功能,在游戏战斗的界面中加入了npc的行为判定,主动攻击型,玩家进入任务场景时敌人进行追击和攻击。判断检测范围,当主角与敌人的距离小于64像素是敌人对主角进行追击,当主角与敌人的距离小于16像素是敌人对主角进行攻击。这样也增加了不同关卡游戏的难度性和可玩性。4.2游戏的流程和类结构4.2.1游戏的基本运行流程本游戏的基本运行流程是在MIDlet启动后把整个画布作为一个线程,随时准备响应用户按键操作的KeyPressed()方法。在主角进入到主场景时开启与主场景NPC的对话方式,执行主角行走移动方法。通过与NPC对话方式进入任务场景1,当主角击败人物场景1所有怪物时,开启任务场景1NPC对话方式进入任务场景2,失败则游戏结束。当主角进入任务场景2时,击败所有敌人则通过任务场景2的NPC对话系统回到主场景。主角回到主场景后可加血后通过NPC进入任务场景3.当主角进入任务场景3时,击败所有怪物则游戏胜利,反之游戏结束。4.2.2游戏的类结构MyMIDlet:游戏的主入口,开始游戏Game_Canvas:游戏类,用于游戏运行的类,实现游戏中的显示Player:主角类Enemy:敌人类MyMap:地图类Dialog:对话类Music:音乐类,实现游戏所有音乐,包括初始化和播放。MyMIDMyMIDletMyCanvasGame_CanvasEenmyPlayerMusicDialogMyMap4.3图像和动画渲染MIDP2.0相对于1.0来说,最大的变化就是新添加了用于支持游戏的API,它们被放在javax.microedition.lcdui.game包中。游戏API包提供了一系列针对无线设备的游戏开发类。由于无线设备仅有有限的计算能力,因此许多API的目的在于提高Java游戏的性能,并且把原来很多需要手动编写的代码如屏幕双缓冲、图像剪裁等都交给API间接调用本地代码来实现。各厂家有相当大的自由来优化它们。游戏API使用了MIDP的低级图形类接口(Graphics,Image,等等)。整个game包仅有5个Class。GameCanvas这个类是LCDUI的Canvas类的子类,为游戏提供了基本的“屏幕”功能。除了从Canvas继承下来的方法外,这个类还提供了游戏专用的功能,如查询当前游戏键状态的能力,同步图像输出;这些功能简化了游戏开发并提高了性能。GameCanvas类提供了基本的游戏用户接口。除了从Canvas继承下来的特性(命令,输入事件等)以外,它还提供了专门针对游戏的功能,比如后备屏幕缓冲和键盘状态查询的能力。每个GameCanvas实例都会有一个为之创建的专用的缓冲区。因为每个GameCanvas实例都会有一个唯一的缓冲区。可以从GameCanvas实例获得其对应的Graphics对象,而且,只有对Graphics对象操作,才会修改缓冲区的内容。外部资源如其他的MIDlet或者系统级的通知都不会导致缓冲区内容被修改。LayerLayer类代表游戏中的一个可视化元素,例如Sprite或TiledLayer是它的子类;这个抽象类搭好了层(Layer)的基本框架并提供了一些基本的属性,如位置,大小,可视与否。出于优化的考虑,不允许直接产生Layer的子类(不能包外继承)。LayerManager对于有着许多Layer的游戏而言,LayerManager通过实现分层次的自动渲染,从而简化了游戏开发。它允许开发者设置一个可视窗口(ViewWindow),表示用户在游戏中可见的窗口;LayerManager自动渲染游戏中的Layer,从而实现期望的视图效果。LayerManager管理一系列的Layer。LayerManager简化了這染每个Layer的过程,每个添加的Layer都将在正确的区域并以正确的顺序被渲染。LayerManager维护一个顺序列表,以便管理如何追加、插入和删除Layer。一个Layer的索引号关联了它的Z轴位置(z-order);索引号为0的Layer最接近用户,索引号越大的Layer离用户越远。索引号永远是连续的,即,如果一个Layer被删除,后面的Layer的索引号都将调整使得索引号保持连续。SpriteSprite又称“精灵”,也是一种Layer,可以显示一帧或多帧的连续图像。但所有的帧都是相同大小的,并且由一个Image对象提供。Sprite通过循环显示每—顿,可以实现任意顺序的动画;Sprite类还提供了许多变换(翻转和旋转)模式和碰撞检测方法,能大大简化游戏逻辑的实现。Sprite是一个基本的可视元素,可以用存储在图像中的一帧或多帧来渲染它;轮流显示不同的帧可以令Sprite实现动画。翻转和旋转等几种变换方式也能应用于Sprite使之外观改变。作为Layer子类,Sprite的位置可以改变,并且还能设置其可视与否。TiledLayerTiledLayer又称“砖块”,这个类允许开发者在不必使用非常大的Image对象的情况下创建一个大的图像内容。TiledLayer有许多单元格构成,每个单元格能显示由一个单一Image对象提供的一组贴图中的某一个贴图。单元格也能被动画贴图填充,动画贴图的内容能非常迅速地变化;这个功能对于动画显示非常大的一组单元格非常有用,例如一个充满水的动态区域。TiledLayer由一系列单元格组成,单元格可被一组贴图填充。这个类允许不必使用特别大的图像来创建大的虚拟层。这个技术在2D游戏中被广泛用于创建特别大的可卷动的背景。在游戏中,某些方法如果改变了Layer,LayerManager,Sprite和TiledLayer对象的状态,通常并不能立刻显示出视觉变化。因为这些状态仅仅存储在对象里,只有当随后调用我们自己的paimo方法时才会更新显示。这种模式非常适合游戏程序,因为在一个游戏循环中,一些对象的状态会更新,在每个循环的最后,整个屏幕才会被重绘。基于轮询也是现在视频游戏的基本结构。由上面的这5个类就能够实现基本的图像和动画的显示功能。由Sprite类来创建动画元素,它可以显示PNG格式文件的某一部分,作为动画的某一帧。可以方便的对它进行帧的切换,屏幕上位置的变化。以此来显示游戏中人物、怪物等可移动的部分。用TiledLayer来创建游戏的背景。它能够将屏幕分割成等大的若干部分,每一部分都可以用PNG文件的一部分来填充。这就可以方便的画出游戏需要的背景图片。还可以根据某一块部分时候填充了图片,来和Sprite类进行碰撞检测。Sprite类和TiledLayer类都是Layer类的子类,而LayerManager可以管理这些Layer。它能够添加和移除一个Layer,也可以对这些Layer进行排序,从而在重画的时候达到需要的叠加效果。这样,对于一些小游戏来说,完全可以满足要求,并且能够提供相当强的兼容性和可移植性。4.4游戏画布类Game_Canvas的实现4.4.1Game_Canvas继承GameCanvas类,用来实现整个游戏的主界面⑴显示主场景的方法publicvoidpaint(Graphicsg){ }⑵图层管理器publicvoidLayer_Manager(){ }⑶主场景扫描publicvoidsetViewWindow(){ }⑷主角移动publicvoidPlayer_Move(){ }⑸定义各场景碰撞层publicvoidcollides(){ }⑹主角碰撞后的移动publicvoidpz_move(){ }⑺主角与NPC的碰撞publicvoidcollides_npc(){ }⑻加载任务场景各图层publicvoidLayer_renwu(){ }⑼绘制血量框publicvoiddraw_hp(){ }⑽怪物的碰撞检测publicvoidguai_pz(){ }⑾主角攻击怪物publicvoidpengzhuang_guai(){ }⑿显示怪物publicvoidhuaguai(){ }⒀按键响应publicvoidkeyPressed(intkey){ }4.4.2此游戏画布类中主要的实现地图的铺设主场景和任务场景包括以下这些图层:背景层(地表层)TiledLayertl_bj=null;碰撞层(建筑层)TiledLayertl_pz=null;NPC(N层)、主角层publicstaticint[]NPC1={0};主场景和任务场景地图数组文件的制作:新建类MyMap,继承自CameCanvaspublicclassMyMapextendsGameCanvas{ }定义主场景背景层和碰撞层数组publicstaticintmap_bj[][]={}publicstaticintmap_pz[][]={}显示主场景:定义控制各场景是否可见的状态变量booleanview_main=false; booleanview_renwu1=false; booleanview_renwu2=false; booleanview_renwu3=false;定义初始化主场景和任务场景的方法publicvoidinit_zhuchangjing(){ try{ map=Image.createImage("/dituw.png"); }catch(IOExceptione){ e.printStackTrace(); } tl_bj=newTiledLayer(53,20,map,16,16); tl_pz=newTiledLayer(53,20,map,16,16); for(inti=0;i<20;i++){ for(intj=0;j<53;j++){ if(map_bj[i][j]!=0){ tl_bj.setCell(j,i,map_bj[i][j]); } if(map_pz[i][j]!=0){ tl_pz.setCell(j,i,map_pz[i][j]);}}}}publicvoidinit_renwu(){ try{ map1=Image.createImage("/renwu1.png"); map2=Image.createImage("/renwu2.png"); map3=Image.createImage("/renwu3.png"); }catch(IOExceptione){ e.printStackTrace(); } if(view_renwu1){ tl1_bj=newTiledLayer(25,20,map1,16,16); tl1_pz=newTiledLayer(25,20,map1,16,16); for(inti=0;i<20;i++){ for(intj=0;j<25;j++){ if(renwu1_bj[i][j]!=0){ tl1_bj.setCell(j,i,renwu1_bj[i][j]); } if(renwu1_pz[i][j]!=0){ tl1_pz.setCell(j,i,renwu1_pz[i][j]); } } } tl1_bj.setPosition(53*16,0); tl1_pz.setPosition(53*16,0); } if(view_renwu2){ tl2_bj=newTiledLayer(25,20,map2,16,16); tl2_pz=newTiledLayer(25,20,map2,16,16); for(inti=0;i<20;i++){ for(intj=0;j<25;j++){ if(renwu2_bj[i][j]!=0){ tl2_bj.setCell(j,i,renwu2_bj[i][j]); } if(renwu2_pz[i][j]!=0){ tl2_pz.setCell(j,i,renwu2_pz[i][j]); } } } tl2_bj.setPosition(78*16,0); tl2_pz.setPosition(78*16,0); } if(view_renwu3){ tl3_bj=newTiledLayer(30,20,map3,16,16); tl3_pz=newTiledLayer(30,20,map3,16,16); for(inti=0;i<20;i++){ for(intj=0;j<30;j++){ if(renwu3_bj[i][j]!=0){ tl3_bj.setCell(j,i,renwu3_bj[i][j]); } if(renwu3_pz[i][j]!=0){ tl3_pz.setCell(j,i,renwu3_pz[i][j]); } } } tl3_bj.setPosition(103*16,0); tl3_pz.setPosition(103*16,0); } }④定义地图资源图片:map=Image.createImage("/dituw.png");map1=Image.createImage("/renwu1.png"); map2=Image.createImage("/renwu2.png"); map3=Image.createImage("/renwu3.png");实例化背景层和碰撞层(屏幕分割20*53,图片切割16*16)tl_bj=newTiledLayer(53,20,map,16,16); tl_pz=newTiledLayer(53,20,map,16,16);填充背景层和碰撞层(填充图层)for(inti=0;i<20;i++){ for(intj=0;j<53;j++){ if(map_bj[i][j]!=0){ tl_bj.setCell(j,i,map_bj[i][j]); } if(map_pz[i][j]!=0){ tl_pz.setCell(j,i,map_pz[i][j]); } } }将主场景加入图层管理器:通过图层管理器的方法setViewWindow()来设置可视窗口实例化地图对象和图层管理器MyMapmymap=newMyMap();LayerManagerlm=newLayerManager();各个图层的切换是通过图层管理器的remove()和append()方法来实现的将主场景的背景层和碰撞层加入图层管理器lm.append(mymap.tl_pz);lm.append(mymap.tl_bj);与NPC的对话定义碰撞NPC的方法publicvoidpz_move(){ switch(orietation){ caseO_UP: player.spPlayer.move(0,6); break; caseO_DOWN: player.spPlayer.move(0,-6); break; caseO_LEFT: player.spPlayer.move(6,0); break; caseO_RIGHT: player.spPlayer.move(-6,0); break; } }确定要和哪些NPC对话,对话内容publicstaticStringdlg[]=newString[]{ "主角:你好,这里是哪里啊?", "小兔:你好,欢迎来到西凉召德村,我是小兔。", "主角:我叫袁熙,我怎么在这里,太奇怪了,我好饿啊,请问哪里有吃的东西?", "小兔:前方有一家客栈,你可以在那里休息。", "主角:谢谢啊。", "主角:老板,你这里有什么吃的啊,我好饿啊!!!", "老板:孩子,这里只有牛肉面了,别的都刚刚卖完。", "主角:好吧,来3碗。", "老板:孩子,看你这么能吃,想必武功也很好吧?", "主角:还行吧,我练过点功夫。", "老板:太好了,最近村长遇到点麻烦,你去帮帮他吧。", "主角:好啊,吃饱了也该练练功夫了。", "主角:村长,我叫袁熙,我听说您遇上了麻烦,我看看您怎么了?", "村长:哎,最近后山出现了很多妖怪,我们的村民都不敢去后山砍柴、采药了,这可怎么办啊!", "主角:哦,我去后山看看吧。希望能帮助你们。", "村长:孩子,太谢谢你了。你和边上的黑衣人说话,他会放你去后山的。", "主角:你好,我去后山帮村长杀妖怪,你让我过去吧。", "黑衣人:好吧,后山山路崎岖,你可要小心啊。", "主角:没问题,呵呵。", "小姑娘:救命啊!救命啊!!!", "主角:小姑娘,你来这荒郊野岭的地方干嘛,有什么能帮助你的吗?", "小姑娘:我爸爸是村里的铁匠,我来这里帮我爸爸找玄铁,没想到遇到了一群强盗把我找的玄铁都抢走了,我们家就靠这点微薄的收入支撑生活了!你能帮帮我吗?", "主角:好的,没问题,你看到那些强盗从哪里逃走了吗?","小姑娘:他们刚从这里的山洞逃走了,你快点去追吧!", "主角:好的,你先回到村里安全的地方吧,我一定帮你找回玄铁的!", "主角:请问你是西凉召德村的李铁匠吗?","铁匠:是。", "主角:这个给你,你的女儿让我帮你从强盗那抢回玄铁,她现在已经回家了,你也快回家吧这里太不安全了!", "铁匠:太感谢你了,你真是个好人啊!", "主角:呵呵,别这么说这都是我应该做的!", "铁匠:你回村找那个神秘人吧,他会在洞口等你的!", "神秘人:年轻人,你怎么受了这么重的伤啊,前面有个医生你可以找她去看看!", "主角:谢谢了!", "主角:我受伤了你这有什么药能给我治一治吗?", "医生:看你脸色这么苍白一定是失血过多,赶快把这颗药丸吃了吧!", "主角:谢谢!", "医生:不客气,东面武官门口有个村民好像很着急的在等人,不会是等你呢吧!", "主角:那我去看看!", "村民:铁匠和他的女儿都安全的回家了,但是还有很多村民被鬼魅抓到了小岛上,希望你能救救他们!", "主角:怎么才能去那个小岛呢?", "村民:你就沿着这条小路走南拐就能看到有个码头了,你可以坐船去那个小岛上。", "主角:好的,我一定会救出他们的!", "村民:谢谢你了,年轻人!", "主角:你能带我去这附近的小岛上吗?", "船夫:那里很危险的,据说还着这一个很凶猛的怪物,你一定要去那里吗?", "主角:我要去那里救人,很多村民都被那个怪物抓走了,我不能看他们就这样被吃掉!", "船夫:那好吧,小伙子看你这么善良我就破例带你去吧!",};一一检测碰撞,通过布尔值区别碰到哪个NPC了游戏中一共十一个NPC,主角通过collidesWith()方法判断是否与NPC碰撞,如碰撞上第一个NPC则开启第一个NPC的对话功能。对话顺序如下:knpc8,knpc4,knpc6,knpc5,knpc2,knpc11,knpc7,knpc9,Knpc1,knpc3。设置主角的碰撞区域player.spPlayer.defineCollisionRectangle(18,50,28,10);检测碰撞并通过drawString()方法显示对话内容if(player.spPlayer.collidesWith(player.npc8,true)){ lm.insert(player.spPlayer,0); if(knpc8){ g.drawImage(duihuakuang,0,240,0); Dialog.DrawString(Dialog.dlg[count],font,230,g,7,246); if(this.getKeyStates()==GameCanvas.FIRE_PRESSED){ count++; if(count>=5){ knpc8=false; knpc4=true; } } }}敌人的人工智能判断检测范围,检测范围内敌人向主角移动if(this.getX()>(hero_x-64)&&this.getX()<(hero_x+64) &&this.getY()>(hero_y-64)&&this.getY()<(hero_y+64)){//在检测范围内 if(this.getX()<hero_x&&this.getY()<hero_y){//如果在左上角 //向右移 orietation=O_RIGHT; this.move(this.speed,0); this.Enemy_zhen(moveright); } if(this.getX()>hero_x&&this.getY()<hero_y){//如果在右上角 //向下移动 orietation=O_DOWN; this.move(0,this.speed); this.Enemy_zhen(mo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论