摘要
编程语言从机器语言,汇编语言,再到现在的高级语言,一步步发展到现
在已经形成了一个完善语言的体系。就像是各个国家都有自己的语言一样,编
程语言也有许多不同的语言,而每种语言的出现都是为了迎合不同的需求,也
都有自己独特的语言魅力,Java也不例外,它的出现迎合了人们对应用程序跨平台运行的需求。
而且Java现在是全球流行的开发工具之一,它拥有了一套庞大且完善的类库,内置了其他语言需要靠库甚至是操作系统才能支持的功能,拥有一个虚拟机。
本文在开始先对Java语言做了初步的介绍,即针对Java的特点做了详细
的描述,同时也针对Java程序的运行机制做了描述;开发环境做了简单的介绍。
接下来是对编写的软件的描述,对Java API的应用,对Java语言的继承、方法的重写、接口和抽象类的使用。
绪论
第一章系统开发环境
1.1开发工具
1.2应用环境
第二章系统需求分析
2.1需求分析
2.2可行性分析
第三章系统概要设计
3.1设计目标
3.2系统功能模块
第四章系统详细设计
4.1程序设计
4.2各功能界面截图
第五章系统测试
5.1测试的意义
5.2测试过程
5.3测试结果
第六章总结
参考文献
绪论
Java语言简介
Java的发展和历史
Java的诞生得益于对家用电器的芯片的研制,开始时,开发者想用C++
语言来开发电器的芯片,但是,由于芯片的种类各不相同,因此,程序要进行多次编译。尤其是C++中的指针操作,稍有不慎,就会出现问题。程序可以出错,但是家用电器不能出错误,为此,开发者将C++语言进行简化,去掉指针操作,去掉运算符重载,去掉C++中的多继承,得到了Java语言,将它变成了一种解
释执行的语言,并在每个芯片上装上一个Java虚拟机。刚开始时,Java语言
被称为Oak语言(橡树语言)
Java语言现在逐渐成熟起来,它的类也已经进千个了,而且还可以通过
第三方购买中间件,为Java语言的发展提供了良好的发展前景,同时它也是跨平台的语言,因此许多软件开发商及硬件开发商也争先恐后地想搭上Java语言的快车,都声称支持Java语言,它对微软发起了有力的挑战,而且Sun公司正努力开发Java芯片
Java语言的特点
Java是一种简单的,面向对象的,分布式的,健壮的,安全的,与平台无
关的,多线程的,高性能的,动态程序设计语言。
1.简单易学
Java语言虽起源于C++,但是去掉了C++语言中难于掌握的指针操作,内
存管理非常简单,如果要释放内存资源,你仅需要让其对象的引用等于null,
这样就使操作变得异常简单
2.面向对象
Java语言是面向对象的编程语言。面向对象技术很好的解决了当今软件开
发过程中新出现的种种传统的面向过程语言所不能处理的问题,包括软件开发
的规模扩大,升级加快,维护量增大以及开发分工日益细化,专业化和标准化等。面向对象技术的核心是以更接近于人类思维的方式建立计算机模型,它利
用类和对象的机制将数据与其上的操作封装在一起,并通过统一的接口与外界
交互,是反映现实世界实体的个各类在程序中能够独立、自治和继承。
3.分布式
Java包括一个支持HTTP(超文本传输协议)和FTP(文件传输协议)
等基于TCP/IP协议的子库,因此,Java应用程序可凭借URL(统一资源定位符)打开并访问网络上的对象,其访问方式与访问本地文件系统几乎完全相同。为
分布式环境尤其是Internet提供了动态内容,无疑是一项非常宏达的工程,但是Java的语法特性可以很容易实现这项目标。
4.健壮性
Java致力于检查程序在编译和运行时的错误。类型检查可以检查出许多开
发早期出现的错误。Java自行操作内存,减少了内存错误的可能性。Java还实
现了真数组,避免了覆盖数据的可能。这些功能特征大大缩短了开发Java应用程序的周期。Java提供null指针检测数组边界,进行异常出口字节代码校验。
5.安全稳定
对网络上应用程序的另一个要求是较高的安全可靠性。用户通过网络获取
并在本地运行的应用程序必须是可信赖的,不会充当病毒或者其他恶意操作的
传播者而攻击本地的资源,同时它还应该是稳定的,轻易不会产生死机等错误,使得用户乐意使用。
6.平台无关
Java语言独特的运行机制使得它具有良好的二进制的可移植性,利用Java,开发人员可以编写出与具体平台无关,普遍适用的应用程序,大大降低了开发、维护和管理的开销,也就是一次编译,随处运行。
7.支持多线程
多线程是当今软件开发技术的又一重要成果,已成功应用在操作系统和应
用开发等多个领域。多线程技术允许同一个进程有两个或两个以上的执行线索,即同时做两件或多件事情,满足了一些复杂软件的需求。Java不但内置多线程
功能,而且定义了一些用于建立、管理多线程的类和方法,使得开发具有多线
程功能的程序变得简单、容易和有效。
8.高性能
如果解释器的速度快,Java可以在运行时直接将目标代码翻译成机器指令。Sun用直接解释器一秒钟内可调用300 000个过程。翻译目标代码的速度与C++的性能没什么区别。
9.动态性
Java的动态性是其面向对象设计方法的扩展,它允许程序动态地装入运行
过程中所需要的类。Java编译器将符号引用信息在字节码中保存下来并传递给
解释器吗,再由解释器完成动态连接类后,将符号引用信息转换为数值偏移量。这样,一个在存储器生成的对象不在编译过程中决定,而是延迟到运行时有解
释器确定,这样对类中的变量和方法进行更新时就不至于影响现存的代码。解
释执行字节码时,这种符号信息的查找和转换过程进在一个新的名字出现时才
进行一次,随后代码便可以全速执行。在运行时确定引用的好处是可以使用已
被更新的类,而不必担心会影响原有的代码。
Java平台简介
1998年12月,Sun发布了Java2平台—JDK 1.2,这时Java发展是上的里程碑。1999年6月,Sun公司重新组织Java平台的集成方法,并将Java企业
级应用平台作为发展方向。2004年,Sun发布JDK1.5更名为JDK5.0.2006年底,Sun再度推出JDK1.6(JDK6.0)。如今,Java家族也已经有四个主要成员:
J2SE(Java 2 Standard Edition)用于工作站、PC机的Java标准平台,现改
名为JavaSE;J2EE(Java 2 Enterprise Edition)可扩展的企业级应用平台,
现改名为JavaEE;J2ME(Java 2 Micro Edition)嵌入式电子设备Java应用平台,现改名为JavaME;JavaFX是一种声明式的静态类型编程语言,专为喜欢在可视化编程中的Web脚本人员和应用程序开发人员量身定做,是Java新成员
Java程序的运行机制和Java虚拟机(JVM)
Java语言比较特殊,由Java语言编写的程序需要经过编译步骤,但是这个编译步骤并不会生成特定平台的机器码,而是生成一种与平台无关的字节码文件(也就是.class文件)。当然,这种字节码文件不是可执行的,必须使用Java 解释器来解释执行。因此,我们可以认为:Java语言既是编译型语言,也是解释型语言。或者说,Java语言既不是纯粹的编译型语言,也不是纯粹的解释型语言。Java程序的执行过程必须经过先编译,后解释两个步骤,
Java语言里负责解释执行字节码文件的是Java虚拟机,即JVM(Java Virtual Machine)。JVM是可运行JAVA字节码文件的虚拟计算机。所有平台的JVM向编译器提供相同的编译接口,而编译器只需要面向虚拟机,生成虚拟机能理解的代码,然后由虚拟机来解释执行。在一些虚拟机的实现中,还会将虚拟机代码转换成特定系统的机器码执行,从而提高执行效率。
JVM是一个抽象的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域。它负责执行指令,还要管理数据、内存和寄存器
Java开发环境搭建
首先进行JDK的安装,下载JDK安装包解压后进行环境变量的配置,配置步骤如下:
右击桌面上“我的电脑”图标,出现右键菜单;单击“属性”菜单项,出现“系统属性”或“高级系统设置”对话框;单击该对话框的“高级”选项,出现如图2所示的对话框。
单击“环境变量”按钮,将看到如图3所示的“环境变量”的对话框,通过该对话框可以修改或添加环境变量。
图2 图3
第一章系统开发环境
1.1开发环境
Sun Microsystems公司在推出Java语句的同时,推出了一套开发工具JDK。Sun提供的基于字符模式的Java开发工具包JDK:Java开发工具(JDK)是许多Java专家最初使用的开发环境。Java是平台无关的语言是指用Java写的应用程序不用修改就可以在不同的软硬件平台上运行。
Java源程序编写可以借助于记事本,Editplus,UltraEdit等第三方编辑工具。
所有的Java文件编辑、编译、调试、解释运行都是通过使用字符命令来执行操作。JDK由一个标准库和一组建立、测试及建立文档的Java实用程序组成。其核心Java API是一些预定义的类库,开发人员需要使用这些类来访问Java语言的功能。JDK是整个Java的核心,包括了Java运行环境,一堆Java 工具和Java基础的类库。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。
JDK里面是Java类库和Java的语言规范,它提供的是无论是用何种开
发软件写java程序都必须用到类库和java语言规范,没有JDK,你的java程
序根本就不能用。
最主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和
组织都开发了自己的JDK,例如IBM公司开发的JDK,BEA公司的Jrocket,还
有GNU组织开发的JDK等待,其中IBM的JDK包含的JVM运行效率要比Sun的JDK包含的JVM高出许多。而专门运行在X86平台的Jrocket在服务端运行效
率也要比Sun的JDK好很多。但是不管怎么说,还是需要把Sun的JDK掌握好。
但是在这里我借助的是一个编程软件MyEclipse来完成程序的编写与调
试的
1.2应用环境
操作系统:Windows 7
应用环境:JDK 1.6
应用软件:Myeclipse
第二章系统需求分析
2.1需求分析
游戏简介:游戏中玩家通过鼠标来移动自己的飞机,打掉飞机或蜜蜂会
获得分数和奖励,打掉一架飞机获得5分,打掉一只蜜蜂获得随机奖励:一条
命或者40次双倍火力,如果撞上敌机或蜜蜂,则会失去生命,同时双倍火力清零。每撞到一次就生命值减1,当生命值为0时,游戏结束
shoots要满足以下几点要求:
1.鼠标点击界面游戏开始
2.鼠标移出界面游戏暂停再次移入继续开始
3.飞机跟随鼠标指针移动
4.打掉飞机就分值增加,打掉蜜蜂就奖励生命值或者双倍火力
2.2可行性分析
Shoots游戏是一种简单的大众游戏,在实现游戏的过程中你需要对子弹
与敌机或蜜蜂的碰撞做出判断,判断的处理可以由坐标的范围来完成;如果碰
撞就要做删除处理,通过记录碰撞的对象(对象是存放在数组中的)的下标可
以对它进行删除操作;以及在它们越界(超出画板范围的那些敌机和蜜蜂)后
对它们要删除;因为敌机和蜜蜂是不断生成的,会越来越多,而存放它们的是
一个数组,这个数组不是固定的长度,会随着敌机和蜜蜂的数量的增加而进行
扩容,所以如果不对越界的敌机和蜜蜂进行处理,数组会越来越大,从而占有
更多的存储空间,而游戏运行也越来越慢;另外实现子弹、敌机和蜜蜂的自动
移动,需要对存放它们的数组遍历然后对每一个存放的对象的坐标属性进行加减操作;而用鼠标来操作飞机就需要用到与鼠标移动相关的触发事件,在鼠标的点击,滑动,移出面板,移入面板同样都有与之相关的鼠标事件,通过这些事件来实现暂停,运行。
选择使用Java语言,一方面是接触的多,另一方面是Java是一种跨平台的,适合于分布式计算机环境的面向对象编程语言,用Java写的应用程序不用修改就可在不同的软硬件平台上运行。
第三章系统概要设计
3.1设计目标
可以利用鼠标移动战机,鼠标移出游戏面板游戏暂停,鼠标再次移入游戏面板游戏开始,还要随机的产生敌机和蜜蜂,生命值为零结束游戏。
3.2系统功能模块
1.类与类之间的关系
包括一个源文件,五个类和两个接口
2.java源文件及其功能
模型,英雄机、敌机、蜜蜂以及子弹都是矩形区域,如下图所示:
以英雄机为例标示出数据x、y、width以及height所表示的位置。敌机、蜜蜂、子弹以及英雄机的这四个属性类似的
第四章系统详细设计
4.1程序设计
1.主类ShootGame
(1)成员变量
(1).主类的main为程序入口,定义了游戏窗口的的大小、居中,点击右上角“x”关闭窗口以及设置窗口的可见性
还调用了启动游戏的方法action()
3.抽象父类FlyingObject
由图3.1可以分析出英雄机、敌机、子弹以及蜜蜂都有x、y、width以及
height属性,因此,将这些属性抽象到父类FlyingObject中。另外,它们在
界面上都是以图片的形式显示,因此在父类FlyingObject中,添加image属性,表示它们的贴图;由于蜜蜂和敌机都可以被子弹击中,因此在FlyingObject类
中添加shootBy方法,该方法的参数为子弹类型。下图是以蜜蜂为例,说明子弹被击中的算法。代码如下:
/**敌人被子弹打,this:敌人;bullet:子弹*/
publicboolean shootBy(Bullet bullet){
//找出敌机的四个角的坐标
int x1 = this.x;
int x2 = this.x+this.width;
int y1 = this.y;
int y2 = this.y+this.height;
//找出子弹坐标
int x = bullet.x;
int y = bullet.y;
return x>x1 && x } 4.接口Enemy 实现该接口的类为敌人,如果子弹击中敌机,英雄机获取分数,因此该接口提 供获取分数的方法,代码如下: package shoots; publicinterface Enemy { publicint getScore(); } 5.接口Award 实现该接口的类表示奖励,如果子弹击中了蜜蜂,英雄机可以获取奖励,奖励 分两种,可以是双倍活力或生命值,因此提供获取奖励类型的方法,代码如下:package shoots; publicinterface Award { publicint DOUBLE_FIRE = 0;//火力值 publicint LIFE = 1;//命 /* 获取奖励类型(0为火力;1为命)*/ publicint getType(); } 6.类Airplane,表示敌机 敌机属于飞行物,因此继承FlyingObject类,重写了父类的step方法,实现Enemy接口,敌机可以向下移动,因此有移动的速度作为属性,实现了敌 机越界的判断方法,代码如下: package shoots; publicclass Airplane extends FlyingObject implements Enemy{ privateint speed = 2; public Airplane(){ image = ShootGame.airplane; width = image.getWidth(); height = image.getHeight(); x = (int)(Math.random()*(ShootGame.WIDTH- this.width)); y =-this.height; } publicint getScore(){ return 5; } publicvoid step(){ y +=speed; } publicboolean outOfBounds(){ return y>ShootGame.HEIGHT; } } 7.类Bee,表示蜜蜂 继承FlyingObject,重写了Step方法,实现Award接口,蜜蜂可以左右和向下移动,故含有移动速度的属性和越界的判断,代码如下: package shoots; import java.util.Random; publicclass Bee extends FlyingObject implements Award{ privateint xSpeed = 1; privateint ySpeed = 2; privateint awardType; public Bee(){ image = ShootGame.bee; width = image.getWidth(); height = image.getHeight(); Random rand = new Random(); x = rand.nextInt(ShootGame.WIDTH-this.width); y =-this.height; awardType=rand.nextInt(2); } publicint getType(){ return awardType; } publicvoid step(){ x += xSpeed; y += ySpeed; if(x>=ShootGame.WIDTH-this.width){ xSpeed = -1; } if(x<=0){ xSpeed = 1; } } publicboolean outOfBounds(){ return y>ShootGame.HEIGHT; } } 8.类Bullet,表示子弹 继承FlyingObject,重写了step方法,定义了越界的判断方法,代码如下: package shoots; publicclass Bullet extends FlyingObject { privateint speed = 3; public Bullet(int x, int y){ image = ShootGame.bullet; width = image.getWidth(); height = image.getHeight(); this.x = x; this.y = y; } publicvoid step(){ y -= speed; } publicboolean outOfBounds(){ return y<-this.height; } } 9.类Hero,表示英雄机 继承FlyingObject类,重写step方法,实现动态的飞行;由于会发射子弹击中蜜蜂,所以可以获取双倍火力或生命值,因此该类含有双倍子弹的具体数量,生命值的数量;另外该类代表的对象会和其他对象相碰撞,所以该类中定义了一个判断撞击的方法hit()来实现对撞击范围的判断;还对越界的判断返回值固定为false,是一个boolean的值,表示永不越界;在该类中含有一个构造方法用于初始化数据;moveTo方法用于处理鼠标位置:英雄机的中心点;关键代码是实现飞机动态效果和撞击的判断: 图示:撞击的判断 /** 重写step() */ publicvoid step(){ //10毫秒走一次 image = images[index++/10%images.length]; //10*10=100毫秒 } /** 英雄机与敌人碰撞检查 this:英雄机 other:敌人 */ publicboolean hit(FlyingObject other){ int x1=other.x-this.width/2; //x1:蜜蜂的x-1/2英雄机的宽 int x2=other.x+other.width+this.width/2; //x2:蜜蜂的x+蜜蜂的宽+1/2英雄机的宽 int y1=other.y-this.height/2; //y1:蜜蜂的y-1/2英 雄机的高 int y2=other.y+other.height+this.height/2;//y2:蜜蜂的y+蜜蜂的高+1/2英雄机的高 int hx=this.x+this.width/2; //hx:英雄机的x+1/2英 雄机的宽 int hy=this.y+this.height/2;//hy:英雄机的y+1/2英 雄机的高 return hx>x1 && hx && hy>y1 && hy 和y2之间,即为撞上了 } } 在Hero中添加shoot方法,实现发射子弹,英雄机发射子弹位置的计算如下图: public Bullet[] shoot(){ int xstep = this.width/4; int ystep = 20; if(doubleFire>0){//双倍火力 Bullet[] bullets = new Bullet[2]; bullets[0] = new Bullet(this.x+xstep,this.y-ystep); bullets[1] = new Bullet(this.x+3*xstep,this.y-ystep); doubleFire -= 2;//火力减2 return bullets; }else{ //单倍火力 Bullet[] bullets = new Bullet[1]; bullets[0] = new Bullet(this.x+2*xstep,this.y-ystep); return bullets; } } 10.主类ShootGame 由于主类要实现画板的功能,所以继承了JPanel,在该类中,使用静态常量定义面板的宽和高,并使用ImageIO的read方法加载图片;界面绘制过程如下: (1).在该类中添加FlyingObject[]类型的属性flyings,用于存储射击游戏 的所有敌机和蜜蜂; (2).添加Bullet[]类型的属性bullet,用于存储射击游戏中的所有子弹; (3).添加Hero类型的属性hero,表示英雄机; (4).添加paintHero方法、paintBullets方法、paintFlyingObject方法,分别用于实现在面板上画英雄机、子弹、敌机、蜜蜂;并重写paint方法,在该方法中调用上述三个方法; (5).添加构造初始化属性flyings、bullets以及hero; (6).重构Airplane类Bee类,设置固定的x、y坐标位置,以便显示查看。 另外在该类中定义了许多的方法,关键方法的详细功能及实现如下: 1).shootAction()方法,实现每次调用20次该方法发射一次子弹,并将发射的子弹存储到bullets数组中 2).bangAction方法和bang方法,这两个方法实现了子弹与飞行物(蜜蜂或敌机)的碰撞检测,详细过程如下: (1).循环遍历存储所有子弹的数组bullets; (2).在上述循环中,再次使用循环,遍历存储所有飞行物的数组flyings,在该循环中判断当前子弹是否击中某个飞行物,如果击中则退出循环,记录被击中的飞行物在flyings数组中的索引index; (3).在flyings数据中找到该飞行物,并将其移除; (4).判断该飞行物的类型是Emeny还是Award,如果是Enemy类型,则获取加分;如果是Award类型,则获取奖励 (5).获取奖励的类型,如果是奖励的类型为DOUBLE_FIRE,则获得40次双倍活力;如果奖励类型是LIFE,则奖励生命值, 3).outOfBoundsAction方法,该方法用于删除越界飞行物以及子弹,详细实现过程如下: (1).创建FlyingObject类型的数组flyingLives,用于存储所有活着的飞行物(蜜蜂和敌机),即没有越界的飞行物; (2).循环遍历存储所有飞行物的数组flyings,并判断每一个飞行物是否越界,将没有越界的飞行物放入flyingLives数组中存储,并记录不越界飞行物的个数index; (3).将flyingLives数组中的元素,复制到flyings数组中,并重新指定flyings数组的长度index; (4).删除子弹与删除飞行物的过程类似。 4).isGameOver方法,该方法用于判断游戏是否结束,方法实现的详细过程如下: (1).循环遍历存储所有飞行物(蜜蜂和敌机)的数组flyings (2).在循环中,判断英雄机是否与飞行物发生碰撞,如果发生碰撞,则减生命值、双倍火力清零,记录被撞飞行物在flyings数组中的索引index,该索引默认是-1,即没有发生碰撞; (3).判断index是否为-1,如果不为-1,将该索引位置的元素从flyings数组中清除; (4).判断生命值是否小于等于0,并返回比较结果 4.2各功能界面截图 1.Shoots游戏的基本运行界面 (1)初始界面