FeedingFrenzy大鱼吃小鱼

该文章描述了一款使用Java开发的大鱼吃小鱼游戏的详细实现过程,包括界面设置、双缓存技术用于绘制界面、游戏模式设定、关卡难度调整、碰撞检测算法以及登陆界面的逻辑实现。作者在开发过程中面临了碰撞检测、UI设计和登录验证的挑战,并分享了课程设计的感想,展望了未来学习数据库和JavaWeb开发的需求。
摘要由CSDN通过智能技术生成

个人负责任务

搭建主框架:进行界面设置,添加动作事件

绘制界面图片:双缓存技术先储存图片组件,最后将所有组件图片添加到窗口中

设置游戏模式:调整关卡难度,控制鱼的移动和方向、碰撞

设置登陆界面逻辑实现部分

发布小程序:打包为jar文件,生成exe程序

目录

一、功能架构图

二、具体实现

1.面向对象设计

2.GameUtils类

1.声明创建对象:

2.绘制界面

3.*双缓存技术

4.设置关卡难度

5.生成鱼

6.定义移动方向与碰撞检测

7.重新开始

8.创建主函数

3.登陆界面逻辑实现

  4.发布小程序​

三、课程设计感想

四、展望



一、功能架构图

  1. 二、具体实现

1.面向对象设计

  • 包名:fish

    类名:

  • 2.GameUtils类

1.声明创建对象:

  1. 定义游戏状态,设置宽高,设置时间计时器,创建背景图,声明创建鱼类

  2. //游戏状态:0游戏未开始 1游戏中 2通关失败 3游戏成功 4暂停
    	//游戏默认状态
    	static int state=0;
    	
    	Image offScreenImage;
    	//设置宽高
    	int width=1440;
    	int height=900;
    	
    	
    	double random;
    	//计数器
    	int time=0;
    	
    	//背景
    	Bg bg=new Bg();
    	
    	//敌方鱼类
    	Enamy enamy;
    	
    	//boss类
    	Enamy boss;
    	//是否生成boss
    	boolean isboss=false;
    	
    	
    	//我方鱼类
    	Myfish myFish=new Myfish();

2.绘制界面

public void launch() {
		this.setSize(width, height);//设置窗口大小
		this.setLocationRelativeTo(null);//设置窗口在屏幕居中位置
		
		this.setTitle("Feeding Frenzy");
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);;
		this.setVisible(true);//设置窗口可见
		
		this.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				if(e.getButton()==1&&state==0) {
					state=1;
					repaint();//重新绘制窗口;
				}
				if(e.getButton()==1&&state==2||state==3) {
					reGame();
					state=1;
				}
			}
		});
	
	//键盘移动
		this.addKeyListener(new KeyAdapter() {
			//按下
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				
				if(e.getKeyCode()==38) {
					GameUtils.UP=true;
				}
				if(e.getKeyCode()==40) {
					GameUtils.DOWN=true;
				}
				if(e.getKeyCode()==37) {
					GameUtils.LEFT=true;
				}
				if(e.getKeyCode()==39) {
					GameUtils.RIGHT=true;
				}
				if(e.getKeyCode()==32) {
					switch(state) {
					case 1:
						state=4;
						GameUtils.drawWord(getGraphics(),"游戏暂停",Color.RED,50,20,400);
						break;
					case 4:
						state=1;
						break;
					}
				}
			}
			//松开
			public void keyReleased(KeyEvent e) {
				super.keyReleased(e);
				if(e.getKeyCode()==38) {
					GameUtils.UP=false;
				}
				if(e.getKeyCode()==40) {
					GameUtils.DOWN=false;
				}
				if(e.getKeyCode()==37) {
					GameUtils.LEFT=false;
				}
				if(e.getKeyCode()==39) {
					GameUtils.RIGHT=false;
				}
			}
		});
		
	//循环调用
	while(true) {
		repaint();
		time++;
		try {
			Thread.sleep(40);
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	}

3.*双缓存技术

  1. 懒加载模式初始化对象

4.设置关卡难度

  1. 根据积分变化改变关卡的难度等级和自身鱼的等级。

    if(GameUtils.count<5) {
    			GameUtils.level=0;
    			myFish.level=1;
    		}else if(GameUtils.count<=15) {
    			GameUtils.level=1;
    		}else if(GameUtils.count<=50) {
    			GameUtils.level=2;
    			myFish.level=2;
    		}else if(GameUtils.count<=150) {
    			GameUtils.level=3;
    			myFish.level=3;
    		}else if(GameUtils.count<=300) {
    			GameUtils.level=4;
    			myFish.level=3;
    		}else if(GameUtils.count>300) {
    			state=3;
    		}

5.生成鱼

random=Math.random();
		switch(GameUtils.level) {
		case 4:
			if(time%60==0) {
				if(random>0) {
					boss=new Enamy_Boss();
					isboss=true;
				} 
			}
			
		case 3:
			if(time%10==0) {
				if(random>0.5) {
					enamy=new EnamyLeft();
				}else {
				    enamy=new EnamyRight();
				}
				GameUtils.EnamyList.add(enamy);
			}
		case 2:
			if(time%30==0) {
				if(random>0.5) {
					enamy=new EnamyLeft3();
				}else {
				    enamy=new EnamyRight3();
				}
				GameUtils.EnamyList.add(enamy);
			}
		
		case 1:
			if(time%20==0) {
				if(random>0.5) {
					enamy=new EnamyLeft2();
				}else {
				    enamy=new EnamyRight2();
				}
				GameUtils.EnamyList.add(enamy);
			}
		case 0:
			if(time%10==0) {
				if(random>0.5) {
					enamy=new EnamyLeft();
				}else {
				    enamy=new EnamyRight();
				}
				GameUtils.EnamyList.add(enamy);
			}
			break;
			default:
		}

6.定义移动方向与碰撞检测

小鱼的位置由方向与速度决定,大boss碰到界面边界时boss消失,大boss碰到玩家鱼玩家失败,游戏结束。

鱼自身矩形发生重叠时判定等级与关卡难度,被吃掉的鱼消失。

for(Enamy enamy:GameUtils.EnamyList) {
			enamy.x=enamy.x+enamy.dir*enamy.speed;
		
			if(isboss) {
				if(boss.getRec().intersects(getBounds())) {
			       enamy.x=-200;
				   enamy.y=-200;
				  }
				if(boss.getRec().intersects(myFish.getRec())) {
					state=2;
				}
			}
		
			//我方鱼与敌方鱼碰撞检测
			if(myFish.getRec().intersects(enamy.getRec())) {
				if(myFish.level>=enamy.type) {
					System.out.println("碰撞了");
					enamy.x=-200;
				    enamy.y=-200;
				    GameUtils.count=GameUtils.count+enamy.count;
				}else {
					state=2;
				}
				
			}

7.重新开始

游戏结束时点击重新开始,并初始化对象

void reGame() {
		GameUtils.EnamyList.clear();
		time=0;
		myFish.level=1;
		GameUtils.count=0;
		myFish.x=700;
		myFish.y=500;
		myFish.width=50;
		myFish.height=50;
		boss=null;
		isboss=false;
		
		
	}

8.创建主函数

声明创建GameWin对象调用launch方法

public static void main(String args[]) {
		GameWin gameWin=new GameWin();
		gameWin.launch();
	}

3.登陆界面逻辑实现

    @Override
    public void mouseClicked(MouseEvent m) {
        if (m.getSource() == loginButton){
            System.out.println("用户点击登录按钮");
            String name = UserjTextField.getText();
            String paw  = passwordField.getText();
            //获取验证码
            String codeInput = code.getText();
            UserInfo  user = new UserInfo(name,paw);
            System.out.println("用户输入的用户名为:"+name);
            System.out.println("用户输入的密码为:"+paw);

            if (codeInput.length() == 0 && name.length() !=0 && paw.length() !=0){
                System.out.println("用户验证码为空!");
                showDialog("验证码不能为空!");
                String code = CodeUtil.Create(5);//创建一个5位长度的随机验证码
                rightCode.setText(code);
            }else if (name.length() ==0 || paw.length() == 0){
                System.out.println( "用户名或者密码为空");
                showDialog("用户名或者密码为空");
                String code = CodeUtil.Create(5);
                rightCode.setText(code);
                //判断输入的验证码与生成的验证码是否相同
            } else if (!codeInput.equalsIgnoreCase(rightCode.getText())) {
                showDialog("验证码输入错误");
                String code = CodeUtil.Create(5);
                rightCode.setText(code);
            }else if(contains(user)){
                System.out.println("用户输入账号正确,登录成功!");
                //关闭登陆界面
                this.setVisible(false);
                new Game();
            }else {
                System.out.println("用户名或密码错误");
                showDialog("用户名或密码错误");
                String code = CodeUtil.Create(5);
                rightCode.setText(code);
            }
        }
        //更换验证码
        if(m.getSource() == rightCode){
            System.out.println("更换验证码!");
            String code = CodeUtil.Create(5);
            rightCode.setText(code);
        }
       //进入注册页面
        if(m.getSource() == enrollButton){
            System.out.println("用户注册");
            this.dispose();
            new Register();
        }
    }
//鼠标长按
    @Override
    public void mousePressed(MouseEvent m) {
         if (m.getSource() == loginButton){
             loginButton.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\登录按下.png"));
         }else if (m.getSource() == enrollButton){
             enrollButton.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\注册按下.png"));
         } //显示查看密码
         else if (m.getSource() == seelabel){
             seelabel.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\显示密码按下.png"));
             passwordField.setEchoChar((char)0);
         }
    }
//松开按钮
    @Override
    public void mouseReleased(MouseEvent m) {
        if (m.getSource() == loginButton){
            loginButton.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\登录按钮.png"));
        }else if (m.getSource() == enrollButton){
            enrollButton.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\注册按钮.png"));
        }  else if (m.getSource() == seelabel){
            seelabel.setIcon(new ImageIcon("......\\FeedingFrenzy\\image\\login\\显示密码.png"));
            passwordField.setEchoChar('*');
        }
    }

  4.发布小程序

三、课程设计感想

在实现大鱼吃小鱼小游戏的过程中,我遇到了以下问题:

1. 对象碰撞检测的处理:在游戏中,需要判断鱼和鱼、鱼和道具之间是否有碰撞发生,这是游戏正常运行的重要部分。我在实现过程中,使用了 Rectangle 类实现碰撞检测,但是仍需考虑鱼的移动速度和碰撞检测的精度问题。

2. 游戏UI界面的设计:游戏界面的设计也是一个比较重要的问题,需要考虑到用户交互的易用性和视觉效果的表现。

3.登录注册界面实现:生成验证码连接储存的用户信息是一个难点。

感受:

1. 游戏开发难度较大:游戏的开发难度比较大,需要考虑到不同游戏元素之间的交互方式以及游戏逻辑、界面设计、音效等,相对于其他常规Java应用程序,所需考虑的问题更加复杂。

2. 编码风格及代码组织的重要性:在开发过程中,代码编写规范以及代码组织方式对于后续的维护和扩展是非常重要的,良好的编码风格和代码组织方式能够提高开发效率和代码质量。

3. 需要不断调试与优化:游戏开发过程中,需要不断进行调试与优化,才能使游戏质量更高、性能更好。在游戏发布之前必须进行透彻测试,以确保游戏的稳定性和流畅性。

总之,Java实现大鱼吃小鱼小游戏是一项非常有趣的任务,需要在编程技能、设计能力、创意思维和实际操作能力等方面综合考虑,具有一定的挑战性和技术含量。

四、展望

  1. 不足之处:未能实现更高精度的判定两鱼碰撞判定,单机游戏未能实现多人共同游玩,游戏角色单一,界面不够美观
  2. 未来想学习技能:学习数据库:当需要存储用户信息、分数和其他游戏数据,需要了解使用Java进行数据库开发的相关知识;学习Java Web开发:Java应用程序可以使用Java Web技术来创建Web应用程序,并利用Java Servlet和Java Server页面(JSP)等技术编写可响应网页请求的Java代码。这将提供所需的基础架构与支持,以便在Web浏览器中呈现和执行Java小游戏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值