仿雷霆战机——光影空战_二级课
报告
姓名:王彦培 课题名称:仿雷霆战机——光影空战
核准通过,归档资
料。
未经允许,请勿外
传~
摘 要 ............................................................................................................................................. 1
第一章 需求分析 ........................................................................................................................... 2
1.2问题描述 ........................................................................................................................... 2
1.3技术分析 ........................................................................................................................... 2
1.3.1开发环境 ................................................................................................................ 3
1.3.2 J2ME技术和Eclipse的介绍................................................................................ 3
第二章 游戏结构 ........................................................................................................................... 5
2.1功能结构 ........................................................................................................................... 5 第三章 总结 ................................................................................................................................. 33
I
姓名:王彦培 课题名称:仿雷霆战机——光影空战
中原工学院软件学院
二级实践课题
任务书
姓 名 王彦培 RB软件 专业 Java124 班 题 目 光影空战
仿雷霆战机设计出一款射击类游戏,游戏是在雷霆战机上有所修改,设计绚丽的设
计 移动式背景,精彩的玩家战机与敌机对抗画面,玩家战机移动和发射子弹都是依任
靠键盘,在战斗过程中,还伴随有一定的音乐效果。 务
第1周(九月二号~~九月六号):
第2周(九月九号~~九月十三号):
第3周(九月十六号~~九月二十号): 时
间
进
度
[01]Michael Morrison著 李强 译J2ME手机游戏编程入门.人民邮电出版
原 主 社.2005.7
始 要 [02]米川英树 著博硕文化 译 J2ME MIDP手机游戏程序设计:中国铁道出版资 参
料 考 社.2004.12
与 文 [03]梁勇著.李娜 译.Java语言程序设计(基础篇):机械工业出版社.2011.5 献
指导教师签字: 年 月 日
I
姓名:王彦培 课题名称:仿雷霆战机——光影空战
光影空战
摘 要
在我国信息产业有着举足轻重的地位,随着3G时代的的到来,除了无线通讯业务外,短信业务、手机游戏等增值业务都有着广阔的发展空间。手机以其便携性,多功能性已经和广大群众的日常生活密不可分。手机游戏更成为闲暇时人们的挚爱。随着技术对游戏的促进,无线设备和移动电话成为游戏开发领域的游戏平台。最直接的游戏开发模式是在手机设备提供的操作系统平台上直接进行游戏开发。
本课题开发的是仿雷霆战机游戏手机游戏,就是一个略微复杂的J2ME游戏。本文首先简单介绍了Java编程语言及其技术发展对其中主要针对手机软件开发的J2ME体系结构和J2ME的无线工具包WTK进行了概述。然后具体介绍了开发工具Eclipse开发环境的基础、下载与安装、必要的配置及J2ME插件Eclipse的安装、配置。进而从手机游戏开发的需求分析着手,根据现有的雷霆战机射击类游戏的需求,提出了怎样进行手机游戏的策划和手机游戏实现的具体设计,论及到游戏框架的设计、系统结构设计和系统详细设计,并落实到手机游戏设计的实现中去。
J2ME的广泛应用,极大地推动了移动通讯行业和手机游戏行业的发展,对手机游戏软件的开发提供了一个很好的技术平台和完整的开发、部署的环境。
关键词: J2ME; Java 仿雷霆游戏;手机游戏;
1
姓名:王彦培 课题名称:仿雷霆战机——光影空战
第一章 需求分析
1.1项目背景
随着科学技术的发展,人们的工作和生活方式发生了巨大的变革。人们开始充分利用日益发展的计算机信息技术和网络技术,设计开发各种在线服务系统,这些在线系统影响着人们的方方面面,给人们带来了极大的便利,同时给人们带来了一种新兴的娱乐方式,如电子游戏,电脑游戏网络游戏等。
由于通信技术的升级发展,手机走进了中国千家万户,与一万人们的现代生活紧密结合在一起。随着科技信息技术及硬件技术的飞速发展,使原来只有通讯功能的手机,增大了对应程序的支持,使在手机中玩游戏成为可能。手机的普及,也必然使得这种游戏平台(J2ME)得到迅速普及手机游戏开发成为了游戏行业的最新的热点。
1.2问题描述
手机的小巧方便成为人们最普及的随身携带的个人通讯物品在闲暇之余,手机游戏也受到了手机用户的欢迎。它可以随时随地的进行娱乐消遣。这一庞大的手机用户群体,对于手机游戏的需求会很大,这位手机游戏的发展前景、为手机游戏开发商以及整个游戏行业的发展及经济效益的提升,带来了巨大的商机和发展空间。
手机游戏也有它的局限性:就目前来看,手机游戏仍然与,;机游戏的功能有一定的差距,原因是:(,)手机的体积有限,手机中的处理芯片处理能力有限,这就限制游戏开发者所能编制的游戏类型。(,)由于手机的视频屏幕较小,就不可能编制复杂的游戏软件,和获得较逼真的效果。(,)网络传输速度在手机的设计上也受到限制,是网络互动方面受到一定影响。(,)有限的手机内存配置,也使手机游戏的色彩和音效都不能尽如人意
1.3技术分析
光影空战是在雷霆战机的基础上进行修改,所使用的思想也是根据雷霆战机而设计,为编写代码奠定了基础。
2
姓名:王彦培 课题名称:仿雷霆战机——光影空战
1.3.1开发环境
仿雷霆战机小游戏开发环境是在操作系统 Microsoft Windows XP ,程序语 言Java ,开发包 Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC,IDE
Eclipse 3.2
1.3.2 J2ME技术和Eclipse的介绍
Java 2Micro Edition,是Sun微系统公司流行Java编程语言紧凑的版本。以J2ME来对移动设备进行编程。J2ME包括一组开发工具和丰富的应用程序接口(API)以供开发手机应用程序,人们称之为MIDlet,它负责协助java字节码在每个具体手机上的执行,J2ME开发包工具可以被绑定在这些集成开发环境中,进一步提高开发效率。
Eclipse是一个开放源代码,基于Java的可扩展开发平台。就其本身而言,它是一个
的插件集。包括Java开发工具。
Eclipse是一个开放源代码的软件开发项目 专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。它主要由Eclipse项目、Eclipse工具项目和Eclipse技术项目三个项目组成 具体包括四个部分组成——Eclipse Platform、JDT、CDT和PDE.JDT支持Java开发、CDT支持C开发、PDE用来支持插件开发 Eclipse Platform则是一个开放的可扩展IDE 提供了一个通用的开发平台。它提供建造块和构造并运行集成软件开发工具的基础。 1.3.3可行性研究
1、技术可行性:仿雷霆战机游戏——光影空战是一款较为小型的手机游戏,适合现代人的生活的方式,为以后的智能手机的硬件平台提供应用软件,根据已有的手机游戏设计经验,利用J2ME来实现游戏的功能。
3
姓名:王彦培 课题名称:仿雷霆战机——光影空战
2、操作可行性:该游戏在所有的支持Java的手机平台上都可以运行,按键简单,易于操作简单,背景绚丽,趣味性强。
3、功能需求分析:功能需求分析是整个项目开发的重要阶段,是游戏开发的重要一步,分析成功与否,将决定着整个项目的功能的完善性以及稳定性。这个阶段中,我们要确定整个游戏的功能需求,并且将抽象的想象实现具体化操作。
4
姓名:王彦培 课题名称:仿雷霆战机——光影空战
第二章 游戏结构
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(),Audiocip
BackMusic的循环loop()和播放play()两种方法。
下面是对GameMain()中的每一个方法和类的具体介绍:
Java.applet.AudioClip:
AudioClip接口是用于播放音频剪辑的简单抽象。多个AudioClip项能够同时播放,得到的声音混合在一起可产生合成声音。
Loop()方法是以循环方式开始播放此音频剪辑。
Play()方法是开始播放此音频剪辑。每次调用此方法时,剪辑都从头重新开始播
5
姓名:王彦培 课题名称:仿雷霆战机——光影空战
放。
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中的根目录,“\\\\”表示Microsoft Windows UNC路径名。零个或更多字符串名称 的序列。抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC 路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。空 抽象路径名没有前缀和名称序列。 路径名字符串与抽象路径名之间的转换与系统有关。将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符 隔开。默认名称分隔符由系统属性 file.separator 定义,可通过此类的公共静态字段 separator 和 separatorChar 使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。无论是抽象路径名还是路径名字符串,都可以是绝对 路径名或相对 路径名。绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。相反,相对路径必须使用取自其他路径名字的信息进行解释。默认情况下,java.io 包中的类总是根据当前用户目录来解析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。调用此类的 getParent() 方法可以获取抽象路径名的父 路径名,它由路径名前缀以及路径名名称序列中的每个名称(最后一个除外)组成。对于任何具有绝对抽象路径名的 File 对象,如果其绝对抽象路径名以某个目录的绝对路径名开头,那么该目录的绝对路径名是该 File 对
6
姓名:王彦培 课题名称:仿雷霆战机——光影空战
象的祖先。例如,抽象路径名 "/usr表示的目录是路径名 "/usr/local/bin" 所表示目录的一个祖先。在处理 UNIX 平台的根目录,以及 Microsoft Windows 平台的盘符、根目录和 UNC 路径名时,将用到前缀这一概念。如下所示:
对于 UNIX 平台,绝对路径名的前缀始终是 "/"。相对路径名没有前缀表示根目录的绝对路径名的前缀为 "/" 且名称序列为空。
对于 Microsoft Windows 平台,包含盘符的路径名前缀由驱动器号和一个 ":" 组成。如果路径名是绝对路径名,还可能后跟 "\\"。UNC 路径名的前缀是 "\\\\";主机名和共享名是名称序列中的前两个名称。没有指定驱动器的相对路径名没有前缀。
此类的实例可能表示(也可能不表示)实际文件系统对象,如文件或目录。如果它表示这种对象,那么该对象驻留在一个分区 中。分区是文件系统特定于操作系统的存储分区。一个存储设备(例如,物理磁盘驱动器、闪存、CD-ROM)可以包含多个分区。对象(如果有)将驻留在此路径名(绝对形式)某个祖先指定的分区上。
文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。这些限制统称为访问权限。文件系统可以对一个对象设置多个访问权限。例如,一个设置可能适用于对象的所有者,另一个设置则可能适用于所有其他用户。对象上的访问权限可能导致此类的某些方法执行失败。File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变。
JFrame 类与 Frame 轻微不兼容。与其他所有 JFC/Swing 顶层容器一样,JFrame 包含一个 JRootPane 作为其唯一的子容器。根据规定,根窗格所提供的内容窗格应该包含 JFrame 所显示的所有非菜单组件。这不同于 AWT Frame。为了方便地使用 add 及其变体,已经重写了 remove 和 setLayout,以在必要时将其转发到 contentPane。这意味着可以编写: frame.add(child);子级将被添加到 contentPane。内容窗格始终是非 null 的。试图将其设置为 null 会导致 JFrame 抛出异常。默认的内容窗格上会设置有 BorderLayout 管理器。有关添加、移除和设置 JFrame 的 LayoutManager 的详细信息,请参阅 RootPaneContainer。 与 Frame 不同,当用户试图关闭窗口时,JFrame 知道如何进行响应。用户关闭窗口时,默认的行为只是简单地隐藏 JFrame。要更改默认的行为,可调用方法
7
姓名:王彦培 课题名称:仿雷霆战机——光影空战
setDefaultCloseOperation(int)。要使 JFrame 的行与
Frame实例相同,请使用 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)。有关内容窗格和根窗格提供的其他功能的更多信息,请参阅 The Java Tutorial 中的 Using Top-Level Containers 一节。在多屏幕环境中,可以在不同的屏幕设备上创建一个 JFrame。
在游戏源代码中,在主类GameMian()中首先创建了JFrame窗体类,在窗体类中又增加KeyboarsPanel()面板类;而在构造函数中add()方法中调用了面板类创建的对象keyboardPanel,同时还在构造函数中添加了音乐对象BackMusic(),并且在该对象包括了Applet.newAudioClip(newFile(“src/image/1.mid”). toURL());同时也使用了try——catch()处理异常,这样能够保障音乐能从文件中顺利播放。New File(“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 类中的方法在不同的平台的显示屏上显示图像或图形,任何时候需
8
姓名:王彦培 课题名称:仿雷霆战机——光影空战
要显示组件时,JVM都会自动在本地平台上为该组件创建一个Graphics对象,然后传递这个对象来调用paintComponent(Graphics g),这个定义在JComponent类中的方法是在第一次显示组件或重新显示组件时调用的。
Graphics类是所有图形上下文的抽象类的基类,允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
Graphics对象封装了Java支持的基本呈现操作所需的状态信息。此状态信息包括:要在其上绘制的Component对象;呈现和剪贴坐标的转换原点;当前剪贴区;当前颜色;当前字体;当前逻辑像素操作函数;当前XOR交替颜色。
所有作为Graphics对象方法的参数而出现的坐标,都是相对于调用该方法前的此Graphics 对象转换原点的,所有呈现操作仅修改当前剪贴区所限定区域内的像素,此剪贴区是用户空间中的Shape指定的,并通过使用Graphics对象的程序来控制。此用户剪贴区被换到设备空间中,并与设备剪贴区组合,后者是通过窗口可见性和设备范围定义的。用户剪贴区和设备剪贴区的组合定义复合剪贴区,复合剪贴区确定最终的剪贴区域。用户剪贴区不能由呈现系统修改,以反映得到的复合剪贴区。用户剪贴区只能通过setClip或clipRect方法更改,所有的绘制或写入都以当前的颜色、当前的绘图模式和当前的字体来完成。
Public abstract Boolean drawImage(Image img,int x,int y,int
width,int height,ImageObserver observer),绘制指定图像中已经缩放到适合指定的矩形内部的图像,图像绘制在此图形的上下坐标之间的指定矩形内部,如果需要,则进行缩放。透明像素不影响该处已经存在的像素。此方法在任何情况下都立刻返回,甚至在整个图像没有针对当前输出设备完成缩放、抖动或者转换的情况下也是如此。如果当前输出表示形式尚未完成,则drawImage返回false,随着更多的图像可用,加载图像的进程将通过调用图像的观察者的imageUpdate方法来通知它。
缩放的图像不一定立刻可用,因为已经针对此输出设备构造了非缩放的图像。每种大小的图像可以被分别缓存,并由各自图像产生序列中的原始数据生成,
参数代表含义:img—要绘制的指定图像。如果img为null,则此方法不执行任何操作;X-x坐标;Y—y坐标;width—举行的高度;height—举行的高度;observer—转换了更多图像时要通知的对象。返回:如果图像像素仍然在改变,
9
姓名:王彦培 课题名称:仿雷霆战机——光影空战
则返回false;否则返回ture。下面是光影空战的主界面的设置
图2.2光影空战
ActionEvent的使用:public class ActionEvent extends AWTEvent 指示发生了组建的动作的语义事件。当特定于组建的动作(比如被按下)发生时,由组件(比如Button)生成此高级别事件。事件被传递给每一个ActionListener对象,这些对象是使addActionListener 方法注册的,用以接收这类事件。要使用键盘在Button上触发ActionEvent,请使用空格键。
实现ActionListener接口的对象在发生事件时获取此ActionEvent。因此,侦听器不必处理个别鼠标移动和鼠标单击的细节,而是可以处理像“有意义”(语义)事件。
java.awt.event.ActionEvent;一个内部监听器类当触发器每隔一定的时间都会触发ActionEvent,而监听器会自动调用repaint()方法重新绘制画板。当绘制好一个面板,它的x坐标就会增加。public interface ActiveEvent
知道如何对自身进行指派的事件的接口。通过实现此接口,可以使用 EventDispatchThread 将一个事件放置到事件队列,并且指派该事件时将调用其 dispatch() 方法。
这是一种非常有用的避免死锁的
。如果线程正在执行某个关键部分(即它已经进入了一个或多个监视器),调用其他同步代码可能导致死锁。为了避免潜在的死锁,可以创建一个 ActiveEvent,以便以后运行代码的第二部分。如果存在监视器争用,那么在第一个线程已经完成工作并退出监视器之前,第二个线程将一直处于阻塞状态。
10
姓名:王彦培 课题名称:仿雷霆战机——光影空战
出于安全性考虑,使用 ActiveEvent 来避免从一个关键线程中调用不受信任的代码通常是很值得的。例如,同位体实现可以使用此设施来避免从系统线程调用用户代码。这样做可以避免潜在的死锁和拒绝服务攻击。代码如下
class TimerListener implements ActionListener{
Public void actionPerformed(ActionEvent e){ repaint();
}
}
java.awt.event.KeyAdapter;处理按键输入类具体如下:
public abstract class KeyAdapter
extends Object
implements KeyListener
接收键盘事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
扩展此类即可创建 KeyEvent 侦听器并重写所需事件的方法。(如果要实现 KeyListener 接口,则必须定义该接口内的所有方法。此抽象类将所有方法都定
null,所以只需针对关心的事件定义方法。) 义为
使用扩展的类可创建侦听器对象,然后使用组件的 addKeyListener 方法向该组件注册此侦听器对象。当按下、释放或键入某个键时,将调用该侦听器对象中的相应方法,并将 KeyEvent 传递给相应的方法。
java.awt.event.KeyEvent;public class KeyEvent
extends InputEvent
表示组件中发生键击的事件。
当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener 方法注册,以接收此类事件。(KeyAdapter 对象实现 KeyListener 接口。)发生事件时,所有此类侦听器对象都将获得此 KeyEvent。
“键入键”事件 是高级别事件,通常不依赖于平台或键盘布局。输入 Unicode 字符时生成此类事件,它们被认为是发现字符输入的最佳方式。最简单的情况是,按下单个键(如 "a")将产生键入键事件。但是,字符经常是通过一
11
姓名:王彦培 课题名称:仿雷霆战机——光影空战
系列按键(如‘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 事件。
按下和释放键盘上的键会导致(依次)生成以下键事件:
KEY_PRESSED
KEY_TYPED(只在可生成有效 Unicode 字符时产生。)
KEY_RELEASED
但在某些情况下(例如,在激活自动重复或输入方法时),该顺序可能会有所不同(并且与平台有关)。
注:
不产生 Unicode 字符的键组合(如 F1 和 HELP 键等动作键)不会生成
12
姓名:王彦培 课题名称:仿雷霆战机——光影空战
KEY_TYPED 事件。
并非所有键盘和系统都能够生成所有的虚拟键码。在 Java 中不会尝试人为地生成这些键。
虚拟键码不标识物理键:它们取决于平台和键盘布局。例如,使用美国键盘布局时生成 VK_Q 的键在使用法国键盘布局时将生成 VK_A。
并非所有的字符都有与之关联的 keycode。例如,没有用于问号的 keycode,因为没有在主层上显示问号的键盘。
为了支持平台无关的动作键处理,Java 平台为某些功能使用少量附加虚拟键常量,否则必须通过解释虚拟键码和修饰符来识别这些功能。例如,对于日文 Windows 键盘,返回 VK_ALL_CANDIDATES 而不是 VK_CONVERT 加 ALT 修饰符
正如 Focus Specification 中指定的那样,默认情况下键事件被指派给焦点拥有者。
警告:除了 Java 语言定义的这些键之外(VK_ENTER、VK_BACK_SPACE 和 VK_TAB),不要依赖 VK_ 常量值。Sun 保留将来根据需要更改这些值的权利,以适应更大范围的键盘。
Javax.swing.Timer:public class Timer extends Object implements
Serializable , 在指定时间间隔触发一个或多个 ActionEvent。一个示例用法是动画对象,它将 Timer 用作绘制其帧的触发器。
设置计时器的过程中包括创建一个Timer对象,在该对象上注册一个或多个动作侦听器,以及使用start方法启动该计时器,尽管所有 Timer 都使用一个共享线程(由第一个执行操作的 Timer 对象创建)执行等待,但是 Timer 的动作事件处理程序还会在其他线程(事件指派线程上)执行。这意味着 Timer 的操作处理程序可以安全地在 Swing 组件上执行操作。但是,它也意味着处理程序必须快速执行以保证 GUI 作出响应。
在 1.3 版本中,向 Java 平台添加了另一个 Timer 类:java.util.Timer。该类和 javax.swing.Timer 的基本功能相同,但是 java.util.Timer 更常用,功能更多。javax.swing.Timer 有两个特征,它们可以让使用 GUI 更方便。首先,其事件处理程序都是 GUI 程序员所熟悉的,并且可以更简单地处理事件指
13
姓名:王彦培 课题名称:仿雷霆战机——光影空战
派线程。第二,其自动线程共享意味着不必采取特殊步骤来避免生成过多线程。相反,计时器使用同一个线程让光标闪烁、使工具提示显示等等。
警告:此类的序列化对象与以后的 Swing 版本不兼容。当前序列化支持适用于短期存储,或适用于在运行相同 Swing 版本的应用程序之间进行 RMI(Remote Method Invocation,远程方法调用)。从 1.4 版本开始,已在 java.beans 包
TM中添加了支持所有 JavaBeans 长期存储的功能 。
Bullet子弹类:在本游戏中子弹是有空格键控制的,是一个动画控制类,它上继承了constant常量类,另外还包含了Graphics类,先定义了一个无参数的构造方法,又定义一个没有返回值的move().
图2.3 各类子弹图片
在此方法内部有调用了Graphics类中drawImage()方法。我们对此方法作进一步的介绍;绘制指定图像中已缩放到适合指定矩形内部的图像。 图像绘制在此图形上下文坐标空间的指定矩形内部,如果需要,则进行缩放。透明像素不影响该处已存在的像素。
此方法在任何情况下都立刻返回,甚至在整个图像没有针对当前输出设备完成缩放、抖动或转换的情况下也是如此。如果当前输出表示形式尚未完成,则 drawImage 返回 false。随着更多的图像可用,加载图像的进程将通过调用图像观察者的 imageUpdate 方法来通知它。
缩放的图像不一定立刻可用,因为已经针对此输出设备构造了非缩放的图像。每种大小的图像可以被分别缓存,并由各自图像生产序列中的原始数据生成;用这些方法我们实现了背景有净变动的由单一到多元的转变。如背景一部分代码 y001++;
14
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if ( y001 > 800) y001 = 0;
g.drawImage(backimage7,x001,y001,560,750,null);
背景的纵坐标y001每增加一个单位长度if(){
}条件语句就会判断一次是否满则件语句体,对y001重新初始化,若是不满足则不执语句体。知道满足为止,但无论是否满足条件,都必须执行行g.drawImage(backimage7,x001,y001,560,750,null);
此语句,就这就初步实现了图像的动态化。当然这些方法的使用是依照其功能而定的。
Constant常量类
本类中的常量的类型都是int;
int x;int y;玩家图像纵横坐标
int xball ;int yball;子弹纵横坐标
int x001 ;int y001 ; //背景一坐标
int x002 ; int y002; //背景二坐标
int x003; int y003;//背景三坐标
imageArray()
Image是图形图像的所有类的超类
ImageIcon()绘制图像类
抽象类 Image 是表示图形图像的所有类的超类。必须以特定于平台的方式获取图像。
ImageIcon imageicon1 = new ImageIcon("src/image/enemyA.gif");
Image enemyAimage1 = imageicon1.getImage();
src/image/enemyA.gif 本代码是某一个图片的绝对路径。
new ImageIcon("src/image/enemyA.gif");从上面的路径中获取图片。
ImageIcon imageicon1 = new ImageIcon("src/image/enemyA.gif");将获取的图像存到imageicon1中;
Image enemyAimage1 = imageicon1.getImage()显示图像语句;
15
姓名:王彦培 课题名称:仿雷霆战机——光影空战
2.2游戏程图
否
游戏开始
是
敌人与玩家战机
进行战斗
游戏结束 玩家战机是
否能把大
Boss打死 图2.1光影空战流程图
该游戏一共可以分为三个步骤,第一步是运行程序显示主界面,实现游戏玩家进入游戏的过程,随后游戏会直接进入游戏状态;第二步是进入战斗的阶段,各种Boss的子弹是由代码设置之后自动发出,而玩家的战机则是由玩家通过键盘操作发射子弹,玩家战机的移动是由键盘上的上下左右键操控,发射子弹是由玩家失败 玩家获胜 16
姓名:王彦培 课题名称:仿雷霆战机——光影空战
空格键和Z键控制,玩家先与各种小Boss进行战斗,当游戏快结束的时候,会出现大Boss,在与其战斗之后游戏就随机结束。
2.3功能描述
仿雷霆战机游戏——光影空战的主要功能包括
1、 动画效果:背景移动,给人一种战机在空中飞行战斗的错觉感; 2、 视觉效果好:背景图片绚丽而又大气,星际之间的旋转,使玩家真正体会到
在浩瀚宇宙游玩的快感。
3、 玩家与Boss之战:使玩家体会到惊险而又刺激的画面
4、 添加音乐效果:快节奏的音乐为游戏增添了一份节奏快感。
2.4设计原则
光影空战是适合现代人的一款游戏。游戏操作简单,容易被人接受,可靠性比较强。该游戏采用模块设计,每个类的每一个具体方法就是一个方法块,可以方便以后的维护和测试。另外,系统中的每个类都具有一定的独立的性质,各自分工和实现的效果不一样。各类之间存在一定的关系,但是依赖性不强,这样可以避免子程序之间的复杂关系产生更多不必要的错误。
2.4.1游戏代码分析
我们的游戏光影空战是一款仿雷霆战机游戏,游戏想要真正的实现必须要进行战斗,所以就必须能让游戏运行起来,有一个可以显示它的舞台,这个舞台就是能让游戏的窗体。
GameMain frame=new GameMian();创建一个窗体类,GameMain()继承了JFrame窗体类,创建了一个方法保存在其创建的对象中,frame.setTitle(“光影空战”),设置了窗体名称;frame.setSize(560,700),设置了窗体大小;frame.setLocationRelativeTo(null),设置了窗体在屏幕中显示的中央。Frame.setDefaultCloseOperation(JFrame.EXIT.ON.CLOSE);设置了窗体的开关;frame.setVisible(true),设置了窗体的可视性。
17
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.4窗体截图
该框架是在GameMain()函数中实现的,为后期游戏开发和代码的实现打造了一个平台。
移动Move()类,void move(Graphics g) {
y001++;
if ( y001 > 800)
y001 = 0;
g.drawImage(backimage7,x001,y001,560,750,null);//背景一
y002++;
if ( y002 > 800)
y002 = y001;
g.drawImage(backimage8,x002,y002,560,750,null);//背景二
y003++;
if ( y003 > 800)
y003 = 0;
g.drawImage(backimage9,x003,y003,560,750,null); //背景三
y004++;
18
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if ( y004 > 1600)
y004 = -1600;
g.drawImage(backimage10,x004,y004,560,750,null); //背景四
if ( y002 > 2400)
y002 = -2400;
g.drawImage(backimage8,x002,y002,560,750,null);
}
进入move()方法中,当图像传给Graphics 类型的对象g时,就进入该方法中了,在方法体中,先设置图像的坐标位置,接着g.drawImage()会显示当前的坐标传递出来的图像,坐标每改动一次,程序会让super.paintComponent(g)方法来进行一次刷屏,repaint()是重画背景坐标,即实现了背景图片的动态效果,更加让游戏富有了新意之处。
图2.5背景图片一
19
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.6背景图片二
图2.6背景图片三
20
姓名:王彦培 课题名称:仿雷霆战机——光影空战
以上三张图片是我们组游戏光影空战的全部背景,背景逐渐向下移动,能够让人在太空中感受飞向移动的快乐。
想要准确的让游戏中的背景和子弹能够准确无误的按照自己的意愿来设置和移动,就必须拥有控制这样源代码,下面就来分析一下由键盘控制的部分 源代码:
public KeyboardPanel() {
timer.start();
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
y += 20;
if (y > 580)
y = 580;
break;
case KeyEvent.VK_UP:
y -= 20;
if (y < 0)
y = 0;
21
姓名:王彦培 课题名称:仿雷霆战机——光影空战
break;
case KeyEvent.VK_LEFT:
x -= 20;
if (x < 0)
x = 0;
break;
case KeyEvent.VK_RIGHT:
x += 20;
if (x > 500)
x = 500;
break;
case KeyEvent.VK_SPACE:
isTrue = true;
is = true;
break;
case KeyEvent.VK_Z:
IsTrue = true;
Is = true;
break;
}
}
22
姓名:王彦培 课题名称:仿雷霆战机——光影空战
由于程序从键盘上输入,因此,监听键盘事件KeyEvent,并且扩展KeyAdapter来处理按键输入,当按下一个键时,,就会调用KeyPressed处理器。程序使用e.getKeyCode()方法获取按键代码,每按一次移动键相应的坐标就会改变。当然为了不让图像一处平面,我们用if条件语句加以限制;以确保无论玩家图像如何移动都会显示在此平面上;
图2.7发射子弹图一
23
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.8子弹发射图二
源代码运行成功后,自动进入游戏状态,玩家和Boss的各种战机就自动出
现在屏幕中间,玩家的子弹由空格键和Z键可以发射两种不同的子弹。 addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
y += 20;
if (y > 580)
y = 580;
break;
case KeyEvent.VK_UP:
y -= 20;
if (y < 0)
y = 0;
break;
case KeyEvent.VK_LEFT:
x -= 20;
if (x < 0)
x = 0;
24
姓名:王彦培 课题名称:仿雷霆战机——光影空战
break;
case KeyEvent.VK_RIGHT:
x += 20;
if (x > 500)
x = 500;
break;
case KeyEvent.VK_SPACE:
isTrue = true;
is = true;
break;
case KeyEvent.VK_Z:
IsTrue = true;
Is = true;
break;
}
}
});
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
repaint();
25
姓名:王彦培 课题名称:仿雷霆战机——光影空战
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
bullet.move(g);
g.drawImage(image0, x, y, 80, 80, null);
if (is) {
is = false;
xball = x - 190;
yball = y;
}
if (isTrue) {
g.drawImage(ballRedimage5_1, xball + 220, yball, 60, 60, null);
g.drawImage(ballRedimage5_1, xball + 190, yball, 60, 60, null);
g.drawImage(ballRedimage5_1, xball + 200, yball, 60, 60, null);
g.drawImage(ballRedimage5_1, xball + 210, yball, 60, 60, null);
26
姓名:王彦培 课题名称:仿雷霆战机——光影空战
yball -= 90;
}
if (Is) {
Is = false;
ximage10_1 = x - 210;
yimage10_1 = y;
}
if (IsTrue) {
g.drawImage(image10_1, ximage10_1 + 220, yimage10_1, 60,
60, null);
g.drawImage(image10_1, ximage10_1 + 190, yimage10_1, 60,
60, null);
g.drawImage(image10_1, ximage10_1 + 200, yimage10_1, 60,
60, null);
g.drawImage(image10_1, ximage10_1 + 210, yimage10_1, 60,
60, null);
yimage10_1 -= 100;
}
}
}
玩家子弹的发射是由空格键和Z键来执行boolean语句,当条件为真时就会执行if条件语句中的Bullet方法g.drawImage( )来显示子弹图像。
在光影空战中,有三种小Boss和一个大Boss。下面介绍怎样将大小Boss导入界面之中。
27
姓名:王彦培 课题名称:仿雷霆战机——光影空战
Image image0 = imageicon0.getImage();
ImageIcon imageicon1 = new ImageIcon("src/image/enemyA.gif");
Image enemyAimage1 = imageicon1.getImage();
ImageIcon imageicon2 = new ImageIcon("src/image/enemyB.gif");
Image enemyBimage2 = imageicon2.getImage();
ImageIcon imageicon2_1 = new ImageIcon("src/image/enemyC.gif");
Image enemyAimage2_1 = imageicon2_1.getImage();
ImageIcon imageicon2_2 = new ImageIcon("src/image/enemyD.gif");
Image enemyBimage2_2 = imageicon2_2.getImage();
图2.9大Boss图片
28
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.10小Boss图
29
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图3.11小Boss图
图2.12小Boss图
30
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.13Boss图
31
姓名:王彦培 课题名称:仿雷霆战机——光影空战
图2.14战机图
32
姓名:王彦培 课题名称:仿雷霆战机——光影空战
第三章 总结
三周的事件转瞬即逝,不知不觉中我们二级课题的也接近了尾声。从这三个星期的学习中,让我的受益匪浅。
今年的二级课题是在网上同意选报的,我们组也是有两个人合作完成的。各自都有一些侧重点的分工,我们组选报的是仿雷霆战机游戏——光影空战。由于做游戏时要用到很多界面、按钮、和动态的画面,而我们作为刚刚进入大二的学生,做起来难免有点吃力。刘老师也知道大部分学生的情况,所以提前给我们一份雷霆战机的源代码,让我们仔细分析了雷霆战机代码,刚接触到源代码让我感觉到一头雾水,由于假期将近两个月没有接触到课本,上学期学的Java基础知识都差不多忘完了,刚开始真的很吃力。
这次的二级课题是一个团队合作的项目,从这三个星期的课题实践中,让我体会到团队合作的重要性,只有团结合作才能战胜一切不可战胜的困难。在这三个星期中,从源代码分析到编写代码,中间肯定会有困难和挫折,这就激发了我们对知识的渴求和想战胜困难的勇气,所以就去图书馆借书查资料,和上网查阅各种各样的资料。
当然,虽说大学是一个没人监督学习的场所,其实我们每个人都知道,没有规矩就不成方圆,所以为了自我约束和能互相督促学习,刘老师还给我们都建了一个二级课题的QQ 群,方便我们讨论问题,能够在尽可能短的时间内完成尽可能多的工作。刘老师还特意给我们演讲的时间,让同学们都来参与讨论遇到的问题 。
最后谢谢老师的精心辅导.
33
姓名:王彦培 课题名称:仿雷霆战机——光影空战 附录1参考文献
[01]Michael Morrison著 李强 译J2ME手机游戏编程入门.人民邮电出版社.2005.7
[02]米川英树 著博硕文化 译 J2ME MIDP手机游戏程序设计:中国铁道出版社.2004.12
[03]梁勇著.李娜 译.Java语言程序设计(基础篇):机械工业出版社.2011.5
工作日志:
上午 下午
2:40进机房,3:30-5:20,在1#将雷霆战机源代码导入楼会议室开会,老 师介绍三周Eclipse, 进行初步熟悉了九月二号 工作学习流程,向课题老师汇报解源代码。并制定下近期计我组 划 的
。
首先把工作进一步细化,分
配各自任务。并向辅导老师重新将工作计划规划,并对各个九月三号 汇报了我组的初步计划建角色进行量的细化, 立游戏界面图,并导入
This.jpg图片
设置游戏的GameMain,并且创建九月四号 学习Frame方法 用户框架
搜索战机图片,并对图片进行修九月五号 请假 改
对昨天内容进一步完善,搜设计面板类keyboardPanel,并九月六号 索射击思路和步骤,并参考用Timer类进行监听 一下源代码
上午 下午
九月九号 迎新 迎新
九月十号 迎新 迎新
34
姓名:王彦培 课题名称:仿雷霆战机——光影空战
参考源代码版面类的设编写面板类代码和设置,键盘监听参考子弹设九月十一号 置为键盘监听,子弹移置类的源代码,及子弹移动的代码 动的源代码
九月十二号 上网搜索资料 设置图片和子弹图片 九月十三号 图书馆查资料 写报告
上午 下午 九月十六号 实现键盘监听 查看资料
实现玩家战机,各种,,九月十七号 参考资料书 ,,子弹发射
九月十八号 实现动态背景效果图; 写报告 九月十九号 增加音乐效果,制ppt 汇报验收,写报告 九月二十号 汇报验收,写报告 写报告
附录2 游戏代码
package simple;
import java.applet.Applet; import java.applet.AudioClip; import java.awt.Color;
import java.io.File;
import java.net.MalformedURLException;
35
姓名:王彦培 课题名称:仿雷霆战机——光影空战
import javax.swing.JFrame;
public class GameMain extends JFrame {
private static final long serialVersionUID =
5444035349167086790L;
private KeyboardPanel keyboardPanel = new KeyboardPanel();
public static AudioClip BackMusic;
@SuppressWarnings("deprecation")
public GameMain(){
keyboardPanel.setBackground(Color.black);
try {
BackMusic = Applet.newAudioClip(new File("src/image/1.mid").toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
add(keyboardPanel);
BackMusic.loop();
BackMusic.play();
keyboardPanel.setFocusable(true);
}
public static void main(String[] args) {
36
姓名:王彦培 课题名称:仿雷霆战机——光影空战
GameMain frame = new GameMain();
frame.setTitle("光影空战 ");
frame.setSize(560, 700);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
package simple;
import java.awt.Graphics;
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent;
import javax.swing.*;
public class KeyboardPanel extends constant{
private static final long serialVersionUID =
-7820830326982686769L;
private static boolean isTrue = false;
private static boolean is = false;
private static boolean IsTrue = false;
private static boolean Is = false;
Timer timer = new Timer(delay,new TimerListener());
//键盘监听方法
Bullet bullet = new Bullet();
37
姓名:王彦培 课题名称:仿雷霆战机——光影空战
public KeyboardPanel() {
timer.start();
addKeyListener( new KeyAdapter(){
public void keyPressed(KeyEvent e){
switch (e.getKeyCode()){
case KeyEvent.VK_DOWN : y += 20;
if(y > 580)
y = 580;
break;
case KeyEvent.VK_UP : y -= 20;
if(y < 0)
y = 0;
break;
case KeyEvent.VK_LEFT : x -= 20;
if(x < 0)
x = 0;
break;
case KeyEvent.VK_RIGHT: x += 20;
if(x > 500)
x = 500;
break;
case KeyEvent.VK_SPACE: isTrue = true;
is = true;
break;
case KeyEvent.VK_Z: IsTrue = true;
Is = true;
break;
}
}
38
姓名:王彦培 课题名称:仿雷霆战机——光影空战
});
}
class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
repaint();
}
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
bullet.move(g);
g.drawImage(image0, x, y,80,80,null);
if (is){
is = false;
xball = x-190;
yball = y;
}
if (isTrue){
g.drawImage(ballRedimage5_1, xball+220, yball,60,60, null);
g.drawImage(ballRedimage5_1, xball+190, yball,60,60, null);
g.drawImage(ballRedimage5_1, xball+200, yball,60,60, null);
g.drawImage(ballRedimage5_1, xball+210, yball,60,60, null);
yball -= 100;
}
39
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if (Is){
Is = false;
Xball = x-210;
Yball = y;
}
if (IsTrue){
g.drawImage(enemyBimage2_3, Xball+220,
Yball,60,60, null);
g.drawImage(enemyBimage2_3, Xball+190, Yball,60,60, null);
g.drawImage(enemyBimage2_3, Xball+200, Yball,60,60, null);
g.drawImage(enemyBimage2_3, Xball+210, Yball,60,60, null);
Yball -= 100;
}
}
}
package simple;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class imageArray extends JPanel {
private static final long serialVersionUID = 9193602567989822345L;
ImageIcon imageicon0 = new ImageIcon("src/image/boss.gif");
40
姓名:王彦培 课题名称:仿雷霆战机——光影空战
Image image0 = imageicon0.getImage();
ImageIcon imageicon1 = new
ImageIcon("src/image/enemyA.gif");
Image enemyAimage1 = imageicon1.getImage();
ImageIcon imageicon2= new
ImageIcon("src/image/enemyB.gif");
Image enemyBimage2 = imageicon2.getImage();
ImageIcon imageicon2_1 = new
ImageIcon("src/image/enemyC.gif");
Image enemyAimage2_1 = imageicon2_1.getImage();
ImageIcon imageicon2_2= new
ImageIcon("src/image/enemyD.gif");
Image enemyBimage2_2 = imageicon2_2.getImage();
ImageIcon imageicon2_3= new
ImageIcon("src/image/enemyBullet2.png");
Image enemyBimage2_3 = imageicon2_3.getImage();
ImageIcon imageicon5 = new
ImageIcon("src/image/enemyBullet1.png");
Image ballBlueimage5 = imageicon5.getImage();
ImageIcon imageicon5_1 = new
ImageIcon("src/image/enemyBullet4.png");
Image ballRedimage5_1 = imageicon5_1.getImage();
41
姓名:王彦培 课题名称:仿雷霆战机——光影空战
ImageIcon imageicon6 = new
ImageIcon("src/image/BulletImg3.png");
Image ballgreenimage6 = imageicon6.getImage();
ImageIcon imageicon6_2 = new
ImageIcon("src/image/enemyBullet6.png");
Image enemyBimage6_2 = imageicon6_2.getImage();
ImageIcon BigBossimageicon= new
ImageIcon("src/image/bossA.gif");
Image BigBossimage = BigBossimageicon.getImage();
ImageIcon enemyBulletimageicon= new
ImageIcon("src/image/enemyBullet2.png");
Image enemyBulletimage = enemyBulletimageicon.getImage();
ImageIcon imageicon7 = new ImageIcon("src/image/04.jpg");
Image backimage7 = imageicon7.getImage();
ImageIcon imageicon8 = new ImageIcon("src/image/06.jpg");
Image backimage8 = imageicon8.getImage();
ImageIcon imageicon9 = new ImageIcon("src/image/08.jpg");
Image backimage9 = imageicon9.getImage();
ImageIcon imageicon10 = new ImageIcon("src/image/02.jpg");
Image backimage10 = imageicon10.getImage();
42
姓名:王彦培 课题名称:仿雷霆战机——光影空战
}
package simple;
class constant extends imageArray {
private static final long serialVersionUID =
5213376169587631914L;
int x = 260;
int y = 580;
int count = 0;//大boss移动计数器
int delay = 50;
int xball = 250;
int yball = 500;
int Xball = 250;
int Yball = 500;
int x001 = 0; //背景一坐标
int y001 = 0;
int x002 = 0; //背景二坐标
int y002 = -700;
int x003 = 0; //背景三坐标
int y003 = -1400;
43
姓名:王彦培 课题名称:仿雷霆战机——光影空战
int x004 =0;
int y004 =0;
int ySpeedA1 = 50;
int xbossA1 = 0, xbossA2 = 50, xbossA3 = 450, xbossA4 = 500;
int ySpeedA = 50;
int xbossC1 = 0, xbossC2 = 50, xbossC3 = 500, xbossC4 = 450;
int xenemy1 = 20,yenemy1 = -100,xenemy2 = 400,yenemy2 = -500;
int xbossB = 0,xbossB1 = 40, xbossB3 = 460,xbossB2 =500;
int ySpeedB = 0;
int xBigBoss ;
int yBigBoss=-1000 ;
int xenemyBulletimage =330;
int yenemyBulletimage ;
int xballBlue1 = 15;
int yballBlue1 = 90;
int xballBlue2 = 65;
int yballBlue2 = 90;
44
姓名:王彦培 课题名称:仿雷霆战机——光影空战
int xballBlue3 = 515;
int yballBlue3 = 90;
int xballBlue4 = 465;
int yballBlue4 = 90;
int xballGreen = 60;
int yballGreen =40;
int xballGreen1 = 460;
int yballGreen1 = 40;
int xballGreen2 = 500;
int yballGreen2 = 40;
int xballGreen3 = 100;
int yballGreen3 = 40;
int xenemyimage5_1 ;
int yenemyimage5_1 = 90 ;
int xenemyimage5_2 =500 ;
int yenemyimage5_2 ;
}
package simple;
import java.awt.Graphics; public class Bullet extends constant{
45
姓名:王彦培 课题名称:仿雷霆战机——光影空战
private static final long serialVersionUID = -9182340349162680102L;
public Bullet(){
}
void move(Graphics g) {
y001++;
if ( y001 > 800)
y001 = 0;
g.drawImage(backimage7, x001, y001,560,750,null);//
背景一
y002++;
if ( y002 > 800)
y002 = y001;
g.drawImage(backimage8, x002, y002,560,750,null);//
背景二
y003++;
if ( y003 > 800)
y003 = 0;
g.drawImage(backimage9, x003, y003,560,750,null);
//背景三
y004++;
if ( y004 > 1600)
y004 = -1600;
46
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(backimage10, x004, y004,560,750,null);
//背景四
if ( y002 > 2400)
y002 = -2400;
g.drawImage(backimage8, x002, y002,560,750,null);//
背景二
ySpeedA1 += 15;
xbossA1 = xbossA1 + 4 ;
xbossA2 = xbossA2 + 2 ;
xbossA3 = xbossA3 - 4 ;
xbossA4 = xbossA4 - 6 ;
if ( ySpeedA1 > 600)
ySpeedA1 = -500;
if (xbossA1 > 400)
xbossA1 = 400;
if (xbossA2 > 300)
xbossA2 = 300;
if (xbossA3 < 200)
xbossA3 =200;
if(xbossA4 < 100 )
xbossA4 = 100;
47
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(enemyAimage1,xbossA1 ,ySpeedA1, 40,40,null);
g.drawImage(enemyAimage1,xbossA2 ,ySpeedA1, 40,40,null);
g.drawImage(enemyAimage1,xbossA3 ,ySpeedA1, 40,40,null);
g.drawImage(enemyAimage1,xbossA4 ,ySpeedA1, 40,40,null);
yballBlue1 += 33;
if ( yballBlue1 > 800)
yballBlue1 = ySpeedA1;
xballBlue1 = xbossA1;
g.drawImage(ballBlueimage5, xballBlue1 , yballBlue1 ,
45,45,null);
yballBlue2 += 25;
if ( yballBlue2 > 800)
yballBlue2 = ySpeedA1;
xballBlue2 = xbossA2;
g.drawImage(ballBlueimage5, xballBlue2 , yballBlue2 ,
45,45,null);
yballBlue3 += 25;
if ( yballBlue3 > 800)
48
姓名:王彦培 课题名称:仿雷霆战机——光影空战
yballBlue3 = ySpeedA1;
xballBlue3 = xbossA3;
g.drawImage(ballBlueimage5, xballBlue3 , yballBlue3 ,
45,45,null);
yballBlue4 += 33;
if ( yballBlue4 > 800)
yballBlue4 = ySpeedA1;
xballBlue4 = xbossA4;
g.drawImage(ballBlueimage5, xballBlue4 , yballBlue4 ,
45,45,null);
ySpeedB += 10;
xbossB += 2;
xbossB2 -= 2;
if ( ySpeedB > 800)
ySpeedB = -300;
if( xbossB > 500)
xbossB = 500;
if(xbossB2 <= 0)
xbossB2 = 0;
g.drawImage(enemyBimage2,xbossB , ySpeedB,40,40,null);
49
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(enemyBimage2,xbossB1,ySpeedB,40,40,null);
g.drawImage(enemyBimage2,xbossB2,ySpeedB,40,40,null);
g.drawImage(enemyBimage2,xbossB3,ySpeedB,40,40,null);
yballGreen1 +=20;
if (yballGreen1 == 800)
yballGreen1 = ySpeedB +20;
xballGreen1 = xbossB;
g.drawImage(enemyBimage6_2, xballGreen1 + 10 , yballGreen1 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen1 + 50 , yballGreen1 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen1 - 30 , yballGreen1 , 45,45,null);
yballGreen2 += 20;
if ( yballGreen2 > 800)
yballGreen2 = ySpeedB +20;
xballGreen2 = xbossB1;
g.drawImage(enemyBimage6_2, xballGreen2 + 10 ,yballGreen2 , 45,45,null);
50
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(enemyBimage6_2, xballGreen2 + 50, yballGreen2 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen2 - 30, yballGreen2 , 45,45,null);
yballGreen3 +=20;
if( yballGreen3 > 800){
yballGreen3 = ySpeedB +20;
xballGreen3 = xbossB2 ;
}
g.drawImage(enemyBimage6_2, xballGreen3 + 10, yballGreen3, 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen3 + 50, yballGreen3, 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen3 - 30, yballGreen3, 45,45,null);
yballGreen +=20;
if( yballGreen > 800)
yballGreen = ySpeedB +20 ;
xballGreen = xbossB3 ;
g.drawImage(enemyBimage6_2, xballGreen + 50,
51
姓名:王彦培 课题名称:仿雷霆战机——光影空战 yballGreen , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen - 30,
yballGreen , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen - 50,
yballGreen , 45,45,null);
ySpeedA += 10;
xbossC1 += 10;
xbossC2 += 10;
xbossC3 -= 10;
xbossC4 -= 10;
if(ySpeedA > 700)
ySpeedA = -300;
if(xbossC1 > 600)
xbossC1 = -400;
if(xbossC2 >600)
xbossC2 = -400;
if(xbossC3 < -400)
xbossC3 = 600;
if(xbossC4 <-400)
xbossC4 = 600;
if(yball == ySpeedA){
ySpeedA = -100;
}
g.drawImage(enemyAimage2_1, xbossC1, ySpeedA , 40, 40,
null);
g.drawImage(enemyAimage2_1, xbossC2, ySpeedA , 40, 40,
null);
52
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(enemyAimage2_1, xbossC3, ySpeedA , 40, 40, null);
g.drawImage(enemyAimage2_1, xbossC4, ySpeedA , 40, 40, null);
yenemyimage5_1 +=20;
xenemyimage5_1 +=10;
xenemyimage5_2 -=10;
if(yenemyimage5_1 > 700)
yenemyimage5_1 = ySpeedA;
if(xenemyimage5_1 > 600 )
xenemyimage5_1 = xbossC1;
g.drawImage(ballgreenimage6,xenemyimage5_1 -
10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 30,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 50,yenemyimage5_1, 60,60,null);
if(yenemyimage5_1 < -50)
yenemyimage5_1 = ySpeedA;
if(xenemyimage5_2 < -50 )
xenemyimage5_2 = xbossC3;
g.drawImage(ballgreenimage6,xenemyimage5_2 + 10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 -
53
姓名:王彦培 课题名称:仿雷霆战机——光影空战
10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 -
30,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 -
50,yenemyimage5_1, 60,60,null);
{
yBigBoss +=5;
if(yBigBoss > 100)
yBigBoss = 100;
if(count % 2 == 0){
xBigBoss +=5;
if(xBigBoss >= 280)
count ++;
}
else
{
xBigBoss -=5;
if(xBigBoss <= 0)
count ++;
}
g.drawImage(BigBossimage,xBigBoss,yBigBoss,
260,150,null);
if(yBigBoss == 100){
yenemyBulletimage+=40;
54
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if( yenemyBulletimage >=100 && yenemyBulletimage > 700)
yenemyBulletimage = yBigBoss;
xenemyBulletimage = xBigBoss;
g.drawImage(enemyBulletimage,xenemyBulletimage + 70,yenemyBulletimage + 120, 60,60,null);
g.drawImage(enemyBulletimage,xenemyBulletimage + 90,yenemyBulletimage + 120, 60,60,null);
g.drawImage(enemyBulletimage,xenemyBulletimage + 110,yenemyBulletimage+ 120, 60,60,null);
g.drawImage(enemyBulletimage,xenemyBulletimage + 130,yenemyBulletimage + 120, 60,60,null);
}
}
}
}
package simple;
import java.awt.Graphics;
public class Bullet extends constant{
private static final long serialVersionUID = -9182340349162680102L;
public Bullet(){
}
void move(Graphics g) {
55
姓名:王彦培 课题名称:仿雷霆战机——光影空战
y001++;
if ( y001 > 800)
y001 = 0;
g.drawImage(backimage7, x001, y001,560,750,null);//背景一
y002++;
if ( y002 > 800)
y002 = y001;
g.drawImage(backimage8, x002, y002,560,750,null);//背景二
y003++;
if ( y003 > 800)
y003 = 0;
g.drawImage(backimage9, x003, y003,560,750,null);
//背景三
y004++;
if ( y004 > 1600)
y004 = -1600;
g.drawImage(backimage10, x004, y004,560,750,null);
//背景四
if ( y002 > 2400)
y002 = -2400;
g.drawImage(backimage8, x002, y002,560,750,null);//
56
姓名:王彦培 课题名称:仿雷霆战机——光影空战
背景二
ySpeedA1 += 15;
xbossA1 = xbossA1 + 4 ;
xbossA2 = xbossA2 + 2 ;
xbossA3 = xbossA3 - 4 ;
xbossA4 = xbossA4 - 6 ;
if ( ySpeedA1 > 600)
ySpeedA1 = -500;
if (xbossA1 > 400)
xbossA1 = 400;
if (xbossA2 > 300)
xbossA2 = 300;
if (xbossA3 < 200)
xbossA3 =200;
if(xbossA4 < 100 )
xbossA4 = 100;
g.drawImage(enemyAimage1,xbossA1 ,ySpeedA1,
40,40,null);
g.drawImage(enemyAimage1,xbossA2 ,ySpeedA1,
40,40,null);
g.drawImage(enemyAimage1,xbossA3 ,ySpeedA1,
40,40,null);
g.drawImage(enemyAimage1,xbossA4 ,ySpeedA1,
57
姓名:王彦培 课题名称:仿雷霆战机——光影空战
40,40,null);
yballBlue1 += 33;
if ( yballBlue1 > 800)
yballBlue1 = ySpeedA1;
xballBlue1 = xbossA1;
g.drawImage(ballBlueimage5, xballBlue1 , yballBlue1 ,
45,45,null);
yballBlue2 += 25;
if ( yballBlue2 > 800)
yballBlue2 = ySpeedA1;
xballBlue2 = xbossA2;
g.drawImage(ballBlueimage5, xballBlue2 , yballBlue2 ,
45,45,null);
yballBlue3 += 25;
if ( yballBlue3 > 800)
yballBlue3 = ySpeedA1;
xballBlue3 = xbossA3;
g.drawImage(ballBlueimage5, xballBlue3 , yballBlue3 ,
45,45,null);
yballBlue4 += 33;
if ( yballBlue4 > 800)
58
姓名:王彦培 课题名称:仿雷霆战机——光影空战
yballBlue4 = ySpeedA1;
xballBlue4 = xbossA4;
g.drawImage(ballBlueimage5, xballBlue4 , yballBlue4 , 45,45,null);
ySpeedB += 10;
xbossB += 2;
xbossB2 -= 2;
if ( ySpeedB > 800)
ySpeedB = -300;
if( xbossB > 500)
xbossB = 500;
if(xbossB2 <= 0)
xbossB2 = 0;
g.drawImage(enemyBimage2,xbossB ,
ySpeedB,40,40,null);
g.drawImage(enemyBimage2,xbossB1,ySpeedB,40,40,null);
g.drawImage(enemyBimage2,xbossB2,ySpeedB,40,40,null);
g.drawImage(enemyBimage2,xbossB3,ySpeedB,40,40,null);
yballGreen1 +=20;
59
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if (yballGreen1 == 800)
yballGreen1 = ySpeedB +20;
xballGreen1 = xbossB;
g.drawImage(enemyBimage6_2, xballGreen1 + 10 , yballGreen1 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen1 + 50 , yballGreen1 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen1 - 30 , yballGreen1 , 45,45,null);
yballGreen2 += 20;
if ( yballGreen2 > 800)
yballGreen2 = ySpeedB +20;
xballGreen2 = xbossB1;
g.drawImage(enemyBimage6_2, xballGreen2 + 10 ,yballGreen2 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen2 + 50, yballGreen2 , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen2 - 30, yballGreen2 , 45,45,null);
yballGreen3 +=20;
if( yballGreen3 > 800){
60
姓名:王彦培 课题名称:仿雷霆战机——光影空战
yballGreen3 = ySpeedB +20;
xballGreen3 = xbossB2 ;
}
g.drawImage(enemyBimage6_2, xballGreen3 + 10, yballGreen3, 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen3 + 50, yballGreen3, 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen3 - 30, yballGreen3, 45,45,null);
yballGreen +=20;
if( yballGreen > 800)
yballGreen = ySpeedB +20 ;
xballGreen = xbossB3 ;
g.drawImage(enemyBimage6_2, xballGreen + 50, yballGreen , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen - 30, yballGreen , 45,45,null);
g.drawImage(enemyBimage6_2, xballGreen - 50, yballGreen , 45,45,null);
ySpeedA += 10;
xbossC1 += 10;
xbossC2 += 10;
61
姓名:王彦培 课题名称:仿雷霆战机——光影空战
xbossC3 -= 10;
xbossC4 -= 10;
if(ySpeedA > 700)
ySpeedA = -300;
if(xbossC1 > 600)
xbossC1 = -400;
if(xbossC2 >600)
xbossC2 = -400;
if(xbossC3 < -400)
xbossC3 = 600;
if(xbossC4 <-400)
xbossC4 = 600;
if(yball == ySpeedA){
ySpeedA = -100;
}
g.drawImage(enemyAimage2_1, xbossC1, ySpeedA , 40, 40,
null);
g.drawImage(enemyAimage2_1, xbossC2, ySpeedA , 40, 40,
null);
g.drawImage(enemyAimage2_1, xbossC3, ySpeedA , 40, 40,
null);
g.drawImage(enemyAimage2_1, xbossC4, ySpeedA , 40, 40,
null);
yenemyimage5_1 +=20;
xenemyimage5_1 +=10;
62
姓名:王彦培 课题名称:仿雷霆战机——光影空战
xenemyimage5_2 -=10;
if(yenemyimage5_1 > 700)
yenemyimage5_1 = ySpeedA;
if(xenemyimage5_1 > 600 )
xenemyimage5_1 = xbossC1;
g.drawImage(ballgreenimage6,xenemyimage5_1 -
10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 30,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_1 + 50,yenemyimage5_1, 60,60,null);
if(yenemyimage5_1 < -50)
yenemyimage5_1 = ySpeedA;
if(xenemyimage5_2 < -50 )
xenemyimage5_2 = xbossC3;
g.drawImage(ballgreenimage6,xenemyimage5_2 + 10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 - 10,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 - 30,yenemyimage5_1, 60,60,null);
g.drawImage(ballgreenimage6,xenemyimage5_2 - 50,yenemyimage5_1, 60,60,null);
{
yBigBoss +=5;
63
姓名:王彦培 课题名称:仿雷霆战机——光影空战
if(yBigBoss > 100)
yBigBoss = 100;
if(count % 2 == 0){
xBigBoss +=5;
if(xBigBoss >= 280)
count ++;
}
else
{
xBigBoss -=5;
if(xBigBoss <= 0)
count ++;
}
g.drawImage(BigBossimage,xBigBoss,yBigBoss, 260,150,null);
if(yBigBoss == 100){
yenemyBulletimage+=40;
if( yenemyBulletimage >=100 && yenemyBulletimage > 700)
yenemyBulletimage = yBigBoss;
xenemyBulletimage = xBigBoss;
g.drawImage(enemyBulletimage,xenemyBulletimage + 70,yenemyBulletimage + 120, 60,60,null);
g.drawImage(enemyBulletimage,xenemyBulletimage + 90,yenemyBulletimage + 120, 60,60,null);
64
姓名:王彦培 课题名称:仿雷霆战机——光影空战
g.drawImage(enemyBulletimage,xenemyBulletimage + 110,yenemyBulletimage+ 120, 60,60,null);
g.drawImage(enemyBulletimage,xenemyBulletimage + 130,yenemyBulletimage + 120, 60,60,null);
}
}
}
}
65