仿雷霆战机光影空战二级课题报告.docx
《仿雷霆战机光影空战二级课题报告.docx》由会员分享,可在线阅读,更多相关《仿雷霆战机光影空战二级课题报告.docx(62页珍藏版)》请在冰豆网上搜索。
仿雷霆战机光影空战二级课题报告
中原工学院软件学院
二级实践课题设计任务书
姓名
王彦培
RB软件专业Java124班
题目
光影空战
设
计
任
务
仿雷霆战机设计出一款射击类游戏,游戏是在雷霆战机上有所修改,设计绚丽的移动式背景,精彩的玩家战机与敌机对抗画面,玩家战机移动和发射子弹都是依靠键盘,在战斗过程中,还伴随有一定的音乐效果。
时
间
进
度
第1周(九月二号~~九月六号):
第2周(九月九号~~九月十三号):
第3周(九月十六号~~九月二十号):
原主
始要
资参
料考
与文
献
[01]MichaelMorrison著李强译J2ME手机游戏编程入门.人民邮电出版社.2005.7
[02]米川英树著博硕文化译J2MEMIDP手机游戏程序设计:
中国铁道出版社.2004.12
[03]梁勇著.李娜译.Java语言程序设计(基础篇):
机械工业出版社.2011.5
指导教师签字:
年月日
光影空战
摘要
在我国信息产业有着举足轻重的地位,随着3G时代的的到来,除了无线通讯业务外,短信业务、手机游戏等增值业务都有着广阔的发展空间。
手机以其便携性,多功能性已经和广大群众的日常生活密不可分。
手机游戏更成为闲暇时人们的挚爱。
随着技术对游戏的促进,无线设备和移动电话成为游戏开发领域的游戏平台。
最直接的游戏开发模式是在手机设备提供的操作系统平台上直接进行游戏开发。
本课题开发的是仿雷霆战机游戏手机游戏,就是一个略微复杂的J2ME游戏。
本文首先简单介绍了Java编程语言及其技术发展对其中主要针对手机软件开发的J2ME体系结构和J2ME的无线工具包WTK进行了概述。
然后具体介绍了开发工具Eclipse开发环境的基础、下载与安装、必要的配置及J2ME插件Eclipse的安装、配置。
进而从手机游戏开发的需求分析着手,根据现有的雷霆战机射击类游戏的需求,提出了怎样进行手机游戏的策划和手机游戏实现的具体设计,论及到游戏框架的设计、系统结构设计和系统详细设计,并落实到手机游戏设计的实现中去。
J2ME的广泛应用,极大地推动了移动通讯行业和手机游戏行业的发展,对手机游戏软件的开发提供了一个很好的技术平台和完整的开发、部署的环境。
关键词:
J2ME;Java仿雷霆游戏;手机游戏;
第一章需求分析
1.1项目背景
随着科学技术的发展,人们的工作和生活方式发生了巨大的变革。
人们开始充分利用日益发展的计算机信息技术和网络技术,设计开发各种在线服务系统,这些在线系统影响着人们的方方面面,给人们带来了极大的便利,同时给人们带来了一种新兴的娱乐方式,如电子游戏,电脑游戏网络游戏等。
由于通信技术的升级发展,手机走进了中国千家万户,与一万人们的现代生活紧密结合在一起。
随着科技信息技术及硬件技术的飞速发展,使原来只有通讯功能的手机,增大了对应程序的支持,使在手机中玩游戏成为可能。
手机的普及,也必然使得这种游戏平台(J2ME)得到迅速普及手机游戏开发成为了游戏行业的最新的热点。
1.2问题描述
手机的小巧方便成为人们最普及的随身携带的个人通讯物品在闲暇之余,手机游戏也受到了手机用户的欢迎。
它可以随时随地的进行娱乐消遣。
这一庞大的手机用户群体,对于手机游戏的需求会很大,这位手机游戏的发展前景、为手机游戏开发商以及整个游戏行业的发展及经济效益的提升,带来了巨大的商机和发展空间。
手机游戏也有它的局限性:
就目前来看,手机游戏仍然与pc机游戏的功能有一定的差距,原因是:
(1)手机的体积有限,手机中的处理芯片处理能力有限,这就限制游戏开发者所能编制的游戏类型。
(2)由于手机的视频屏幕较小,就不可能编制复杂的游戏软件,和获得较逼真的效果。
(3)网络传输速度在手机的设计上也受到限制,是网络互动方面受到一定影响。
(4)有限的手机内存配置,也使手机游戏的色彩和音效都不能尽如人意
1.3技术分析
光影空战是在雷霆战机的基础上进行修改,所使用的思想也是根据雷霆战机而设计,为编写代码奠定了基础。
1.3.1开发环境
仿雷霆战机小游戏开发环境是在操作系统MicrosoftWindowsXP,程序语言Java,开发包SunJava(TM)WirelessToolkit2.5.2forCLDC,IDEEclipse3.2
1.3.2J2ME技术和Eclipse的介绍
Java2MicroEdition,是Sun微系统公司流行Java编程语言紧凑的版本。
以J2ME来对移动设备进行编程。
J2ME包括一组开发工具和丰富的应用程序接口(API)以供开发手机应用程序,人们称之为MIDlet,它负责协助java字节码在每个具体手机上的执行,J2ME开发包工具可以被绑定在这些集成开发环境中,进一步提高开发效率。
Eclipse是一个开放源代码,基于Java的可扩展开发平台。
就其本身而言,它是一个标准的插件集。
包括Java开发工具。
Eclipse是一个开放源代码的软件开发项目专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。
它主要由Eclipse项目、Eclipse工具项目和Eclipse技术项目三个项目组成具体包括四个部分组成——EclipsePlatform、JDT、CDT和PDE.JDT支持Java开发、CDT支持C开发、PDE用来支持插件开发EclipsePlatform则是一个开放的可扩展IDE提供了一个通用的开发平台。
它提供建造块和构造并运行集成软件开发工具的基础。
1.3.3可行性研究
1、技术可行性:
仿雷霆战机游戏——光影空战是一款较为小型的手机游戏,适合现代人的生活的方式,为以后的智能手机的硬件平台提供应用软件,根据已有的手机游戏设计经验,利用J2ME来实现游戏的功能。
2、操作可行性:
该游戏在所有的支持Java的手机平台上都可以运行,按键简单,易于操作简单,背景绚丽,趣味性强。
3、功能需求分析:
功能需求分析是整个项目开发的重要阶段,是游戏开发的重要一步,分析成功与否,将决定着整个项目的功能的完善性以及稳定性。
这个阶段中,我们要确定整个游戏的功能需求,并且将抽象的想象实现具体化操作。
第二章游戏结构
2.1功能结构
我们组的游戏是依据在雷霆战机的的基础上设置的光影空战,游戏规则非常简单,玩家进入游戏之后,先于小Boss进行战斗,再与大Boss进行战斗。
实现游戏代码所使用的类和方法他们分别是:
GameMain(),KeyboardPanel(),Bullet(),imageArray(),constant()
表2.1光影空战使用类
GameMain()
系统自带的类:
Java.applet.Applet
Java.applet.AudioClip;
Java.awt.Color;
Java.io.file;
Java.swing.JFrame;
在主类GameMain()中构造KeyboardPanel(),AudiocipBackMusic的循环loop()和播放play()两种方法。
下面是对GameMain()中的每一个方法和类的具体介绍:
Java.applet.AudioClip:
AudioClip接口是用于播放音频剪辑的简单抽象。
多个AudioClip项能够同时播放,得到的声音混合在一起可产生合成声音。
Loop()方法是以循环方式开始播放此音频剪辑。
Play()方法是开始播放此音频剪辑。
每次调用此方法时,剪辑都从头重新开始播放。
Color类用于封装默认sRGB颜色,或者用于封装由ColorSpace标识的任意颜色空间中的颜色。
每种颜色都有一个隐式的alpha值1.0。
或者有一个在构造方法中提供的显式的alpha值。
alpha值定义了颜色的透明度,可用一个在0.0-1.0或0-255范围内的浮点值表示它。
alpha值为1.0或255则意味着颜色完全是不透明的,alpha值为0或0.0则意味着颜色是完全透明的。
在使用显式的alpha值构造Color时,或者在获取某个Color的颜色/alpha分量时,从不将颜色分量预乘alpha分量。
文件和目录路径的抽象表示形式。
用户界面和操作系统使用与系统相关的路径名用字符串来命名文件和目录,此类呈现分层路径名的一个抽象的、与系统无关的视图。
抽象路径名有两个组件:
一个可选的与系统有关的前缀字符串,比如盘符“/”表示UNIX中的根目录,“\\\\”表示MicrosoftWindowsUNC路径名。
零个或更多字符串名称的序列。
抽象路径名中的第一个名称是目录名,对于MicrosoftWindowsUNC路径名则是主机名。
抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。
空抽象路径名没有前缀和名称序列。
路径名字符串与抽象路径名之间的转换与系统有关。
将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符隔开。
默认名称分隔符由系统属性file.separator定义,可通过此类的公共静态字段separator和separatorChar使其可用。
将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。
无论是抽象路径名还是路径名字符串,都可以是绝对路径名或相对路径名。
绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。
相反,相对路径必须使用取自其他路径名字的信息进行解释。
默认情况下,java.io包中的类总是根据当前用户目录来解析相对路径名。
此目录由系统属性user.dir指定,通常是Java虚拟机的调用目录。
调用此类的getParent()方法可以获取抽象路径名的父路径名,它由路径名前缀以及路径名名称序列中的每个名称(最后一个除外)组成。
对于任何具有绝对抽象路径名的File对象,如果其绝对抽象路径名以某个目录的绝对路径名开头,那么该目录的绝对路径名是该File对象的祖先。
例如,抽象路径名"/usr表示的目录是路径名"/usr/local/bin"所表示目录的一个祖先。
在处理UNIX平台的根目录,以及MicrosoftWindows平台的盘符、根目录和UNC路径名时,将用到前缀这一概念。
如下所示:
对于UNIX平台,绝对路径名的前缀始终是"/"。
相对路径名没有前缀表示根目录的绝对路径名的前缀为"/"且名称序列为空。
对于MicrosoftWindows平台,包含盘符的路径名前缀由驱动器号和一个":
"组成。
如果路径名是绝对路径名,还可能后跟"\\"。
UNC路径名的前缀是"\\\\";主机名和共享名是名称序列中的前两个名称。
没有指定驱动器的相对路径名没有前缀。
此类的实例可能表示(也可能不表示)实际文件系统对象,如文件或目录。
如果它表示这种对象,那么该对象驻留在一个分区中。
分区是文件系统特定于操作系统的存储分区。
一个存储设备(例如,物理磁盘驱动器、闪存、CD-ROM)可以包含多个分区。
对象(如果有)将驻留在此路径名(绝对形式)某个祖先指定的分区上。
文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。
这些限制统称为访问权限。
文件系统可以对一个对象设置多个访问权限。
例如,一个设置可能适用于对象的所有者,另一个设置则可能适用于所有其他用户。
对象上的访问权限可能导致此类的某些方法执行失败。
File类的实例是不可变的;也就是说,一旦创建,File对象表示的抽象路径名将永不改变。
JFrame类与Frame轻微不兼容。
与其他所有JFC/Swing顶层容器一样,JFrame包含一个JRootPane作为其唯一的子容器。
根据规定,根窗格所提供的内容窗格应该包含JFrame所显示的所有非菜单组件。
这不同于AWTFrame。
为了方便地使用add及其变体,已经重写了remove和setLayout,以在必要时将其转发到contentPane。
这意味着可以编写:
frame.add(child);子级将被添加到contentPane。
内容窗格始终是非null的。
试图将其设置为null会导致JFrame抛出异常。
默认的内容窗格上会设置有BorderLayout管理器。
有关添加、移除和设置JFrame的LayoutManager的详细信息,请参阅RootPaneContainer。
与Frame不同,当用户试图关闭窗口时,JFrame知道如何进行响应。
用户关闭窗口时,默认的行为只是简单地隐藏JFrame。
要更改默认的行为,可调用方法setDefaultCloseOperation(int)。
要使JFrame的行与
Frame实例相同,请使用setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)。
有关内容窗格和根窗格提供的其他功能的更多信息,请参阅TheJavaTutorial中的UsingTop-LevelContainers一节。
在多屏幕环境中,可以在不同的屏幕设备上创建一个JFrame。
在游戏源代码中,在主类GameMian()中首先创建了JFrame窗体类,在窗体类中又增加KeyboarsPanel()面板类;而在构造函数中add()方法中调用了面板类创建的对象keyboardPanel,同时还在构造函数中添加了音乐对象BackMusic(),并且在该对象包括了Applet.newAudioClip(newFile(“src/image/1.mid”).toURL());同时也使用了try——catch()处理异常,这样能够保障音乐能从文件中顺利播放。
NewFile(“src/image/1.mid”)是音乐导入类文件。
接着介绍游戏中的第二大类KeyboardPanel(),这个面板类就是和我们平时的容器差不多,能够将游戏中的图像及它们的动画效果都在此完成;
表2.2KeyboardPanel()面板类
KeyboardPanel()面板类
java.awt.Graphics绘制图形类
java.awt.event.ActionEvent;内部类监听器
java.awt.event.KeyAdapter;处理按键输入类
java.awt.event.KeyEvent;事件监听类
javax.swing.Timer;监听类
Bullet子弹类
keyPressed()按键触发器方法
getKeyCode()获取按键代码方法
repaint();重画方法
drawImage();画图方法
在Graphics类中提供了绘制字符串、直线、矩形、椭圆、多边形、折线的方法,可以将GUI组建中做成一张纸,而将Graphics看做铅笔或画刷。
可以应用Graphics类中的方法在不同的平台的显示屏上显示图像或图形,任何时候需要显示组件时,JVM都会自动在本地平台上为该组件创建一个Graphics对象,然后传递这个对象来调用paintComponent(Graphicsg),这个定义在JComponent类中的方法是在第一次显示组件或重新显示组件时调用的。
Graphics类是所有图形上下文的抽象类的基类,允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
Graphics对象封装了Java支持的基本呈现操作所需的状态信息。
此状态信息包括:
要在其上绘制的Component对象;呈现和剪贴坐标的转换原点;当前剪贴区;当前颜色;当前字体;当前逻辑像素操作函数;当前XOR交替颜色。
所有作为Graphics对象方法的参数而出现的坐标,都是相对于调用该方法前的此Graphics对象转换原点的,所有呈现操作仅修改当前剪贴区所限定区域内的像素,此剪贴区是用户空间中的Shape指定的,并通过使用Graphics对象的程序来控制。
此用户剪贴区被换到设备空间中,并与设备剪贴区组合,后者是通过窗口可见性和设备范围定义的。
用户剪贴区和设备剪贴区的组合定义复合剪贴区,复合剪贴区确定最终的剪贴区域。
用户剪贴区不能由呈现系统修改,以反映得到的复合剪贴区。
用户剪贴区只能通过setClip或clipRect方法更改,所有的绘制或写入都以当前的颜色、当前的绘图模式和当前的字体来完成。
PublicabstractBooleandrawImage(Imageimg,intx,inty,intwidth,intheight,ImageObserverobserver),绘制指定图像中已经缩放到适合指定的矩形内部的图像,图像绘制在此图形的上下坐标之间的指定矩形内部,如果需要,则进行缩放。
透明像素不影响该处已经存在的像素。
此方法在任何情况下都立刻返回,甚至在整个图像没有针对当前输出设备完成缩放、抖动或者转换的情况下也是如此。
如果当前输出表示形式尚未完成,则drawImage返回false,随着更多的图像可用,加载图像的进程将通过调用图像的观察者的imageUpdate方法来通知它。
缩放的图像不一定立刻可用,因为已经针对此输出设备构造了非缩放的图像。
每种大小的图像可以被分别缓存,并由各自图像产生序列中的原始数据生成,
参数代表含义:
img—要绘制的指定图像。
如果img为null,则此方法不执行任何操作;X-x坐标;Y—y坐标;width—举行的高度;height—举行的高度;observer—转换了更多图像时要通知的对象。
返回:
如果图像像素仍然在改变,则返回false;否则返回ture。
下面是光影空战的主界面的设置
图2.2光影空战
ActionEvent的使用:
publicclassActionEventextendsAWTEvent指示发生了组建的动作的语义事件。
当特定于组建的动作(比如被按下)发生时,由组件(比如Button)生成此高级别事件。
事件被传递给每一个ActionListener对象,这些对象是使addActionListener方法注册的,用以接收这类事件。
要使用键盘在Button上触发ActionEvent,请使用空格键。
实现ActionListener接口的对象在发生事件时获取此ActionEvent。
因此,侦听器不必处理个别鼠标移动和鼠标单击的细节,而是可以处理像“有意义”(语义)事件。
java.awt.event.ActionEvent;一个内部监听器类当触发器每隔一定的时间都会触发ActionEvent,而监听器会自动调用repaint()方法重新绘制画板。
当绘制好一个面板,它的x坐标就会增加。
publicinterfaceActiveEvent
知道如何对自身进行指派的事件的接口。
通过实现此接口,可以使用EventDispatchThread将一个事件放置到事件队列,并且指派该事件时将调用其dispatch()方法。
这是一种非常有用的避免死锁的机制。
如果线程正在执行某个关键部分(即它已经进入了一个或多个监视器),调用其他同步代码可能导致死锁。
为了避免潜在的死锁,可以创建一个ActiveEvent,以便以后运行代码的第二部分。
如果存在监视器争用,那么在第一个线程已经完成工作并退出监视器之前,第二个线程将一直处于阻塞状态。
出于安全性考虑,使用ActiveEvent来避免从一个关键线程中调用不受信任的代码通常是很值得的。
例如,同位体实现可以使用此设施来避免从系统线程调用用户代码。
这样做可以避免潜在的死锁和拒绝服务攻击。
代码如下
classTimerListenerimplementsActionListener{
PublicvoidactionPerformed(ActionEvente){repaint();
}
}
java.awt.event.KeyAdapter;处理按键输入类具体如下:
publicabstractclassKeyAdapter
extendsObject
implementsKeyListener
接收键盘事件的抽象适配器类。
此类中的方法为空。
此类存在的目的是方便创建侦听器对象。
扩展此类即可创建KeyEvent侦听器并重写所需事件的方法。
(如果要实现KeyListener接口,则必须定义该接口内的所有方法。
此抽象类将所有方法都定义为null,所以只需针对关心的事件定义方法。
)
使用扩展的类可创建侦听器对象,然后使用组件的addKeyListener方法向该组件注册此侦听器对象。
当按下、释放或键入某个键时,将调用该侦听器对象中的相应方法,并将KeyEvent传递给相应的方法。
java.awt.event.KeyEvent;publicclassKeyEvent
extendsInputEvent
表示组件中发生键击的事件。
当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。
该事件被传递给每一个KeyListener或KeyAdapter对象,这些对象使用组件的addKeyListener方法注册,以接收此类事件。
(KeyAdapter对象实现KeyListener接口。
)发生事件时,所有此类侦听器对象都将获得此KeyEvent。
“键入键”事件是高级别事件,通常不依赖于平台或键盘布局。
输入Unicode字符时生成此类事件,它们被认为是发现字符输入的最佳方式。
最简单的情况是,按下单个键(如"a")将产生键入键事件。
但是,字符经常是通过一系列按键(如‘shift’+‘a’)产生的,按下键事件和键入键事件的映射关系可能是多对一或多对多的。
键释放通常不需要生成键入键事件,但在某些情况下,只有释放了某个键后才能生成键入键事件(如在Windows中通过Alt-Numpad方法来输入ASCII序列)。
对于不生成Unicode字符的键是不会生成键入键事件的(如动作键、修改键等等)。
getKeyChar方法总是返回有效的Unicode字符或CHAR_UNDEFINED。
KEY_TYPED事件报告字符输入:
KEY_PRESSED和KEY_RELEASED事件不必与字符输入关联。
因此,可以保证getKeyChar方法的结果只对KEY_TYPED事件有意义。
对于按下键和释放键事件,getKeyCode方法返回该事件的keyCode。
对于键入键事件,getKeyCode方法总是返回VK_UNDEFINED。
“按下键”和“释放键”事件是低级别事件,依赖于平台和键盘布局。
只要按下或释放键就生成这些事件,它们是发现不生成字符输入的键(如动作键、修改键等等)的惟一方式。
通过getKeyCode方法可指出按下或释放的键,该方法返回一个虚拟键码。
虚拟键码用于报告按下了键盘上的哪个键,而不是一次或多次键击组合生成的字符(如"A"是由shift+"a"生成的)。
例如,按下Shift键会生成keyCode为VK_SHIFT的KEY_PRESSED事件,而按下'a'键将生成keyCode为VK_A的KEY_PRESSED事件。
释放'a'键后,会激发keyCode为VK_A的KEY_RELEASED事件。
另外,还会生成一个keyChar值为'A'的KEY_TYPED事件。
按下和释放键盘上的键会导致(依次)生成以下键事件: