Java期末项目 大鱼吃小鱼(改进版-期末95分以上)

2023-11-22 19:50

本文主要是介绍Java期末项目 大鱼吃小鱼(改进版-期末95分以上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目名称:大鱼吃小鱼

目录

        1 基本信息

1.1 系统名称

1.2 开发运行环境

1.3 使用的核心类

2.系统需求分析

2.1系统可行性分析

2.2系统需求分析

3.系统功能设计

3.1系统总体设计

3.2系统模块详细设计

3.3 其他分析

4.系统整体及功能模块展示与实现

5.总结体会


1 基本信息

1.1 系统名称

大鱼吃小鱼

1.2 开发运行环境

JDK1.8、Eclipse、photoshop、Windows操作系统

1.3 使用的核心类

1.GWindow类:窗口的绘制,继承JFrame类,其主要设置的内容有:

窗口的相关信息:宽度、高度、窗体是否可见、窗体居中,添加组件等等。

相关事件:鼠标事件、键盘事件

相关方法:logic()方法用来实现鱼类的不断创建,reGame()方法用来实现游戏的重新开始,paint()方法用来实现图像的绘制,使用线程sleep()方法调用repaint()方法。

游戏状态:5种,0—未开始 1—游戏中 2—通关失败 3—通关成功 4—暂停,通过switch语句定义状态。

2.GUtils类:工具类,存放的内容有:

游戏的相关信息:游戏背景图,关卡等级,鱼类图片等。

方法:drawWord()方法用来绘制窗体中文字的大小、颜色、位置等。

3.Bg类:背景图的实体类,用来绘制不同游戏状态下的背景,在状态0(未开始)下背景上出现开始,状态1(游戏中)下会出现积分、难度、等级,状态2(通关失败)下会出现积分、难度、等级、失败,状态3(通关成功)下会出现积分、难度、等级、成功,状态4(暂停)下会出现积分、难度、等级、游戏暂停。

4.EnamyFish类:敌方鱼类,存放的内容有:

定义相关信息:物体坐标、体型大小、移动速度、移动方向、分值等。

方法:paintSelf()实现绘制自身的方法,getrRec()是获取自身矩形的方法,用于碰撞检测。

5.MyFish类:我方 鱼类,存放的内容有:

定义相关信息:物体坐标、体型大小、移动速度、等级等等。

方法:paintSelf()实现绘制自身的方法,getrRec()是获取自身矩形的方法,用于碰撞检测,logic()是返回我方鱼类的方法,添加对键盘的控制。

6.Music类:实现播放背景音乐的类,主要内容有:

run()方法中调用play()方法,play()方法用于实现字节流的读入,并通过玩家播放音乐。

2.系统需求分析

2.1系统可行性分析

1.项目概况

《大鱼吃小鱼》是一款休闲类游戏,于2011年发行。该游戏把玩家带进一个神秘的海底世界,游戏中每一关卡都有玩法提示和海洋鱼类知识学习。在看似风平浪静的大海里,却隐藏着与人类世界相同的危机,海底生物在弱肉强食的竞争下,不但得觅食以填饱肚子,更重要的是学会保护自己。

2.项目当前发展情况

此类游戏在现在的手机上基本都可安装此游戏。虽然版本有所不同,但是游戏玩法和以前没什么区别,值得一提的是操作的设计越来越人性化。

3.项目实现所需条件

《大鱼吃小鱼》的核心算法是实现移动和捕食,我们需要实现《大鱼吃小鱼》的基本功能的方向移动以及捕食后体积增长。

4.项目实施总结

本次项目设计主要运用Java语言来完成。Java语言是一种跨平台,适应于分布式计算环境的面向对象编程语言,用Java编写的应用程序可以不经过大幅度修改就可在不同的软硬件平台上运行,更加简便高效。

2.2系统需求分析

本次项目设计主要是完成游戏的基本操作,需要满足以下几点要求:

1.对游戏中所需类进行设计。

2.写出源程序文件,对游戏进行调试和分析,使程序能够成功运行。

3.系统功能设计

3.1系统总体设计

见文档

3.2系统模块详细设计

部分内容如下:

3.2.1启动封面功能模块

启动封面模块时,首先需要了解一件事,就是游戏的五种游戏状态:

//游戏状态  0—未开始 1—游戏中 2—通关失败 3—通关成功 4—暂停

static int  state=0;//游戏默认状态  

//在paint()方法中利用switch语句定义游戏状态

public void paint(Graphics g) {g.drawImage(offScreenImage, 0, 0, null);switch (state) {case 0:g.drawImage(GUtils.image, 0, 0, null);// 启动页面背景图break;case 1:break;case 2:break;case 3:break;case 4:break;default:}}

3.2.2 启动页面的点击事件功能模块

启动页面是在游戏最开始的时候显示,此时游戏的状态为0。当鼠标左键点击启动窗口后,用if判断鼠标可否点击,游戏进入运行状态,游戏状态为1,启动页面文字消失,在launch()方法中,为页面添加鼠标事件。

// 鼠标事件this.addMouseListener(new MouseAdapter() {// 使用MouseAdapter()可直接重写某个需要的方法@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);// 用if判断鼠标可否点击,并进入游戏运行状态if (e.getButton() == 1 && state == 0) {// 鼠标点击了左键时,e.getButton()==1,进入游戏中修改state=1state = 1;// repaint()可再次调用paint方法,将改变后的窗口绘制出来repaint();}}});

3.2.3 游戏开始的背景添加功能模块

首先新建一个背景图的实体类Bg。过程如下:

1.编写绘制背景的方法,定义所需参数。

//绘制背景的方法paintSelf()

public void paintSelf(Graphics g,int fishgrade) {//定义所需参数g.drawImage(GUtils.image, 0, 0, null);}

2.在窗体类中获取背景类的对象。

//获取背景类Bg的对象Bg bg=new Bg();

3.将背景绘制自身的方法,放到游戏状态为1的语句下。

public void paint(Graphics g) {g.drawImage(offScreenImage, 0, 0, null);switch (state) {case 0:g.drawImage(GUtils.image, 0, 0, null);// 启动页面背景图g.setColor(Color.pink);//将画笔颜色改为粉色g.setFont(new Font("仿宋",Font.BOLD,60));//设置字体样式g.drawString("开始", 700, 500);//为启动页面添加文字break;case 1:bg.paintSelf(g);break;case 2:break;case 3:break;case 4:break;default:}}

4.在launch()方法中添加一个while循环,每间隔40毫秒调用一次repaint方法。

while (true) {repaint();try {Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}

3.2.4 双缓存解决闪屏问题功能模块

在游戏开始的背景添加功能模块中,在launch()方法中添加一个while循环后,会发现启动页的文字有闪动现象,使用缓存的方式解决闪动问题。思路为:重新创建一个空的图片,把所有的组件先绘制到空的图片上,然后把绘制好的图片一次性绘制到主窗口中。过程如下:

1.在主窗口中定义一个成员变量

Image offScreenImage;

2.在paint()方法中懒加载模式初始化对象

public void paint(Graphics g) {offScreenImage = createImage(width, height);Graphics gImage = offScreenImage.getGraphics();// 获取图片对应的画笔对象,把组件绘制到新的图片中g.drawImage(offScreenImage, 0, 0, null);switch (state) {case 0: // 已在Bg类中定义gImage.drawImage(GUtils.image, 0, 0, null);//启动页面背景图gImage.setColor(Color.pink);//将画笔颜色改为粉色gImage.setFont(new Font("仿宋",Font.BOLD,60));//设置字体样式gImage.drawString("开始", 700, 500);//为启动页面添加文字break;case 1:bg.paintSelf(gImage);break;case 2:break;case 3:break;case 4:break;default:}}

3.把内存当中绘制好的新图片一次性绘制到主窗口中。

g.drawImage(offScreenImage, 0, 0, null);

3.2.5敌方鱼的随机生成功能模块

1.在工具类(GUtils)中,创建一个所有敌方鱼物体的集合。

//敌方鱼类集合

public static List<EnamyFish> EnamyList=new ArrayList<>();

2.创建敌方鱼类(EnamyFish),添加敌方鱼类,编写敌方鱼的父类,定义变量。实现右鱼继承左鱼,左鱼继承敌方鱼父类。

Image img; //定义图片int x; int y; //定义物体坐标int width; int height;int speed; //定义移动速度int dir=1; //定义方向:敌方鱼的移动方向,从左向右—1,从右向左— -1int type; //定义敌方鱼的类型int count; //定义分值public void paintSelf(Graphics g){g.drawImage(img, x, y, width, height, null);} //绘制自身的方法//获取自身矩形的方法,用于碰撞检测public Rectangle getrRec(){return new Rectangle(x,y,width,height);}

3.在窗口类创建一个方法,用于批量添加敌方鱼类,将敌方小鱼添加到敌方鱼的集合中。

//敌方鱼EnamyFish enamy;public void logic(){enamy=new Enamy_1_L();GUtils.EnamyList.add(enamy);}

4.因为鱼的生成速度过快,因此要在所创造的方法中,控制敌方鱼的生成,定义一个变量,记录游戏的重绘次数 即paint调用次数,在while中进行自增。

int time=0;while (true) {repaint();time++;try {Thread.sleep(40);//调用sleep()方法} catch (InterruptedException e) {e.printStackTrace();}}

5.在敌方鱼的代码中添加判断语句,定义一个随机数double random,每调用20次paint方法生成一条鱼,在paint方法游戏状态为1的代码块中,循环遍历敌方鱼的生成。

if(time%20 ==0){if(random>0.5){ enamy =new Enamy_1_L();//将小鱼添加到集合中}GUtils.EnamyList.add(enamy);}// 循环遍历敌方鱼的生成, 绘制敌方鱼for (EnamyFish enamy : GUtils.EnamyList) {enamy.paintSelf(gImage);}

6.在所创造的方法中用for each循环定义地方鱼移动方向。

//foreach循环定义鱼类移动方向for(EnamyFish enamy : GUtils.EnamyList){enamy.x += enamy.dir*enamy.speed;}

3.2.6键盘控制我方鱼的移动功能模块

添加我方鱼类并实现键盘控制。过程如下:

1.首先在工具类中添加我方鱼图。

//我方鱼类public static  Image myfish_l=new ImageIcon("images/myfish/myfish_left.gif").getImage();public static  Image myfish_r=new ImageIcon("images/myfish/myfish_right.gif").getImage();

2.创建我方鱼类(MyFish),定义物体变量。过程同敌方鱼类(EnamyFish)。

3.在工具类中添加方向判定,用于控制我方鱼移动的方向。

4.在MyFish类中定义logic()方法,并在paintSelf()中画出对键盘的控

3.2.7鱼的碰撞检测功能模块

  1.通过获取鱼类自身矩形的方法,用于检测不同矩形之间是否相交了来判断鱼类碰撞。为每个鱼类生成一个可以返回Rectangle类的对象的方法。之后再通过Java中的intersects()方法去比较两个返回的Rectangle对象是否相交就可以判断出鱼类间是否碰撞了。

2.我方鱼的体积增加时,碰撞检测时的体积也应该增加。

public  Rectangle getRec(){return new Rectangle(x,y,width+GUtils.count,height+GUtils.count);}

3.2.8 游戏积分的实现功能模块

1.工具类中定义分数

//定义分值public static int count=0;

2.我方鱼和敌方鱼碰撞检测完成后积分加1,在窗口类中实现我方鱼吃掉敌方鱼的所得积分。

if(myFish.getRec().intersects(enamy.getrRec())){System.out.println("碰撞了");enamy.x=-200;enamy.y=-200;//碰撞了,积分加碰撞的敌方鱼数GUtils.count=GUtils.count+enamy.count; }

3.在窗口类paint方法,游戏状态为1的代码块中,打印所得积分。

gImage.setColor(Color.pink);//将画笔颜色改为粉色gImage.setFont(new Font("仿宋",Font.BOLD,60));//设置字体样式gImage.drawString("积分", 200, 120);//为启动页面添加文字

3.2.9关卡的设置功能模块

根据积分实现关卡的设置,如果达到目标积分则过关,并增加等级。

1.在工具类中定义关卡等级grade。并在窗口类logic()方法中设置关卡难度,在paint()方法中state=3的情况下实现。

static int grade=0;//关卡难度if(GUtils.count<10){.grade=0; MyFish.grade=1;}else if(GUtils.count<=50){ GUtils.grade=1; }else if(GUtils.count<=100){ GUtils.grade=2; MyFish.grade=2;}else if(GUtils.count<=150){ GUtils.grade=3; MyFish.grade=3; }else if(GUtils.count<=200){ GUtils.grade=4; MyFish.grade=3; }else if(GUtils.count>200){ state=3; }//在paint()方法中state=3的情况下实现case 3:myFish.paintSelf(gImage);gImage.setColor(Color.pink);//将画笔颜色改为粉色gImage.setFont(new Font("仿宋",Font.BOLD,60));//设置字体样式gImage.drawString("积分", 200, 120);//为启动页面添加文字gImage.drawString("胜利", 400, 500);//为启动页面添加文字break;

3.2.10 boss鱼的出现功能模块

3.2.11 暂停和重新开始功能模块

3.2.12 背景音乐功能模块

为了增加游戏的功能,创建一个Music类继承Thread类,为游戏添加背景音乐。

需要重写run方法。并将音乐读入,在主类中创建Music对象。

 public void play() throws FileNotFoundException, JavaLayerException { //通过字符缓冲流读入FileInputStream fis=new FileInputStream(music);BufferedInputStream buffer = new BufferedInputStream(fis);player = new Player(buffer);player.play();}//重写Thread类中的run方法public void run() {try {play();//调用play方法,并抛出异常} catch (FileNotFoundException  |JavaLayerException e) {// TODO Auto-generated catch blocke.printStackTrace();}}new Music("Relax.mp3").start();

3.3 其他分析

我利用所学的专业知识应用到这个项目中,内容如下:

1.引入第三方jar包:若Java程序想要实现背景音乐功能,就需要下载一个jar包,即在本程序中引入第三方jar包。可以从网站下载我们所需要的jar包。导入jar包的步骤:

在java项目中新建一个文件夹,并将需要导入的jar包复制到新建文件夹中→→选中新建文件夹中的jar包,右键依次点击【Build Path】→【Add to Build Path】即可。

2. Photoshop技术

通过Photoshop我设计出游戏中鱼类的图片,主要实现的是:

a.设置动态鱼类,格式为gif。

b.用Photoshop将gif图片背景变透明。

步骤为:打开一张gif图→→点击窗口的时间轴→→选中第一张图片,让其图层为可见,选择魔棒工具,点击图片背景,点击Delete键将背景删除→依次选中后面图层,并将其背景删除→→时间轴处点击下面小箭头可以设置延迟时间,点击播放可以看动态效果→→完成后将图片存储为web所用格式→→选择格式为gif。

4.系统整体及功能模块展示与实现

5.总结体会

这篇关于Java期末项目 大鱼吃小鱼(改进版-期末95分以上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/412494

相关文章

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决Spring运行时报错:Consider defining a bean of type ‘xxx.xxx.xxx.Xxx‘ in your configuration

《解决Spring运行时报错:Considerdefiningabeanoftype‘xxx.xxx.xxx.Xxx‘inyourconfiguration》该文章主要讲述了在使用S... 目录问题分析解决方案总结问题Description:Parameter 0 of constructor in x

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在