JAVA大作业贪吃蛇--终于有人把游戏的原理讲清了--【课程设计】

关于毕业设计这个总目录
一定要看,因为JAVA工具,tomcat,MAVEN , idea 下载都在这篇文件当中
JAVA项目环境必知必会–【大作业及毕设项目】
部分截图如下:(持续增加中)
在这里插入图片描述

在这里插入图片描述

JAVA的有代码一般都叫【课程设计】
SSM或JAVAWEB(JSP)的【唐诗300首】
springBoot 的叫【JSB项目实战】
PHP的项目叫【白嫖项目】
其它的有可能叫【课程设计】或【毕业设计】


《贪食蛇》介绍:

《贪食蛇》(也叫贪吃蛇)是1976年推出的一款街机游戏游戏。
《贪食蛇》中玩家控制一条不断移动的蛇,在屏幕上吃掉出现的食物。每吃掉一个食物,蛇的身体就会变长。游戏的目标是尽可能长时间地生存下去,同时避免蛇头撞到自己的身体或屏幕边缘。游戏最初是像素风格,后来发展出了3D版本和多人对战模式。玩家需要灵活操作,利用策略在有限的空间内避免碰撞,挑战高分。
在这里插入图片描述

环境及工具:

本系列环境

环境win11
工具idea 2017/idea 2018
jdk1.8
数据库无(文件读写方式)
maven
项目导入方式打开目录
数据库前端工具

项目说明

这个游戏工作量比较小,也比较粗糙。当做学习还是相当的不错的。当毕业设计就有点拿不出手了。
关于游戏的理解也可以参照:
https://blog.youkuaiyun.com/dearmite/article/details/132296106

帧频

什么是游戏里的一帧?这就要理解游戏帧数:
游戏帧数是指游戏运行时每秒所运行的帧数(简称FPS,Frames Per Second)和视频一样,FPS越大,在屏幕上的视频就越来越平滑,直到一个临界点(大约是100FPS),超过这个临界点,再高的FPS都只是一个令人惊奇的数值,400FPS和100FPS在人的视觉中几乎没有差别。
不过,做游戏的时候,这个帧频,还是与打游戏看到的这个有一定的差别。
做游戏的宗师那就必须要说说flash 小游戏这个东西了。他有一个重要的概念流传至今:帧频
flash onEnterframe
‌onEnterFrame事件‌是Flash中一个非常重要的函数,主要用于在每个帧更新时触发一个事件。这意味着无论影片剪辑是否在播放或暂停状态,只要它存在于舞台上,onEnterFrame事件就会持续触发。
onEnterFrame与帧循环的关系
onEnterFrame事件常用于实现帧循环,因为它会以帧频持续调用。例如,可以使用onEnterFrame来实现一个简单的动画循环:
比如这里为了看的清楚,设定了2秒一动(帧)
这个意思就是第一个2秒。
这个画面是左边的样子。
到了2秒之后,成了右图,(3个连着的小块–表示蛇)蛇向上移动了一格
在这里插入图片描述
这就是构成了游戏的基本元素,用时间来推动画面。

游戏的内容逻辑

控制

当在前面的2秒之内,如果按下了向右。则改变了蛇下一个2秒的走向
按左则向左转
按上则不反应,因为蛇原本就是向上走
按下则不反应,因为蛇不能退着走
在这里插入图片描述

游戏的输赢判定

游戏嘛,自然有终止。
贪吃蛇比较简单,就是人来不及下一秒撞墙前拐弯,导致蛇撞墙。
赢,一般言是满足人的心理,比如吃到了更长,超过前一次记录。(但不会终止)

整体设计一下

这个是大般的大一学生的弱项。其实也很容易理解,只学会了hello world 要做一个游戏,脑子都大了好几圈。怎么会静下心来一点点的思考?
在这里插入图片描述
界面,不用说,
学的好一些的人都知道了。
做一个大饼,往上面撒芝麻嘛

JFrame frame = new JFrame("贪食蛇");
		frame.getContentPane().add(oSnakeGame);

放芝麻

	oPnlLeft = new JPanel();
		oPnlControl = new JPanel();
		oPnlMsg = new JPanel();
		oPnlControl.setLayout(new GridLayout(3, 1, 10, 10));
		oPnlLeft.setLayout(null);
		oPnlMsg.setLayout(new GridLayout(4,1));
		oCon.add(oPnlLeft);
		oCon.add(oPnlControl);
		oCon.add(oPnlMsg);
		oPnlMsg.setBackground(new Color(160, 168, 194));
		oPnlLeft.setBackground(new Color(160, 168, 194));

		oPnlMsg.setBounds(205, 10, 85, 120);
		oPnlMsg.setBounds(205*2, 20*2, 85*2, 120*2);

		oPnlControl.setBounds(205, 190, 85, 100);
		oPnlControl.setBounds(205*2, 190*2, 85*2, 100*2);

		oPnlLeft.setBounds(10, 10, 176, 288);
		oPnlLeft.setBounds(10*2, 10*2, 176*2, 288*2);

然后呢?
东问同学,西问同学,都是调这个界面。

这个突破口就是,你先做一个帧的响应。
然后,让一个小块来移动。

if(timer == null){
					timer = new Timer(2000, new GameTimeEvent());
				}

为什么不能不停的new ??
那是因为一个游戏里只能有一个时间,
当初flash 就是可以有多个时间onTime 的,然后那游戏是越跑越卡。最后把I9的CPU吃满。
要是全局用一个时间轴呢?当然了,在time 的开销上没了。但是能不能在下一帧之前CPU(显卡)把所有的要动的生物移动到新的位置,这个就不一定了。
这也就是为什么LOL升级了之后,一般的显卡会丢帧。画面里的物品(动)还没计算完位置,下一帧的开始信号发出来了。于是CPU把这一帧的重置,接手下一帧的计算。有的时候,甚至会不停的这样,于是那个游戏画面“卡”死在了那里。
当然这其实是游戏厂家容易这么设置的,因为他完全可以在第一次计算超时之后,直接计算下二帧的内容。
或者有一些游戏直接就锁帧了。计算完了CPU,显卡就休息,不要抢活
在这里插入图片描述

再次回到了帧的响应

其实只要一条最关键。 那就是移动。只是在移动之前,要判断游戏是不是“输”

/*



				if(oLblSnakeLen.getText().length()>readfile().length)
				{
					writefile();
					oLblSnakeLen2.setText(Integer.toString(sNakes.iLen));
					JOptionPane.showMessageDialog(null, "You are the record breaker !\n     please leave you name\n                     ^_^");

				}
				else if(oLblSnakeLen.getText().compareTo(readfile())>0){
					writefile();
					oLblSnakeLen2.setText(Integer.toString(sNakes.iLen));
					JOptionPane.showMessageDialog(null, "You are the record breaker !\n     please leave you name\n                     ^_^");
				}
				else
					JOptionPane.showMessageDialog(null, "死翘翘喽~~~~继续加油哦^_^");

*/
				return;
			}
			else{
				sNakes.move();
			}

游戏是怎么判断的输

第一,分析蛇的移动。
其实分蛇头的移动。(往上一次用户按了上下左右的方向上移动一格)当然要合理。蛇只能左右摆头。
第二,蛇身的移动。
就是不停的占前一节的位置。
那么就简单了。
蛇头出界就是输了。

所以,蛇的移动就变成了蛇头的移动。
这样就又回到了一个小方块的移动了。
只要不死(撞墙就移动好了) 先不要考虑撞自已身体的问题

public void moveUp(){
		if(iRow>0)
			setPosition(--iRow,iCell);
		else
			setTouch();
	}
	public void moveDown(){
		if(iRow<iBoxH-1)
			setPosition(++iRow,iCell);
		else
			setTouch();
	}
	public void moveLeft(){
		if(iCell>0)
			setPosition(iRow,--iCell);
		else
			setTouch();
	}
	public void moveRight(){
		if(iCell<iBoxW-1)
			setPosition(iRow,++iCell);
		else
			setTouch();
	}

整体的合起来就成了

//		头部要自己跑
		switch(heading){
			case 37:
				aoSnakes[0].moveLeft();
				break;
			case 38:
				aoSnakes[0].moveUp();
				break;
			case 39:
				aoSnakes[0].moveRight();
				break;
			case 40:
				aoSnakes[0].moveDown();
				break;
			default:
				break;
		}
//		身子都是跟着跑。
		for(int j=0;j<iLen-1;j++){
			aoSnakes[j+1].setPosition(tempSnakes[j].getRow(),tempSnakes[j].getCell());
			tempSnakes[j].hide();
		}

能吃代码写到这里或者分析到这里,你的贪吃蛇的主体就出来了。
然后就是吃一个子。
把蛇的list + 1 的问题了。蛇身变长
其实就是路过了吃子(食物)的时候,把蛇的list +1 再重新随机产生一个“吃子”

public void eat(){
		Snake tempSnakes[] = new Snake[iLen];
		for(int i=0;i<tempSnakes.length;i++){
			tempSnakes[i] = aoSnakes[i].clone();
			tempSnakes[i].hide();
		}
		aoSnakes = new Snake[++iLen];
		SnakeGame.oLblSnakeLen.setText(Integer.toString(iLen));
		aoSnakes[0] = new Snake();
		aoSnakes[0].setPosition(Food.getRow(),Food.getCell());
		for(int i=1;i<iLen;i++){
			aoSnakes[i] = tempSnakes[i-1].clone();
		}
		Food.hide(); // 这个食物被吃
		Food = createSnake(); //生成了新的食物
	}

好了,总体上就是两个类。一个是游戏类,一个是蛇。
只是为了方便,把蛇头与蛇身子(list )分开了。
在这里插入图片描述
怎么样?
是不是感觉很轻松呢?
根据一些学生的要求,也加入的数据库的版本:
https://blog.youkuaiyun.com/dearmite/article/details/144874304?spm=1001.2014.3001.5502
JAVA大作业贪吃蛇–加上mysql数据库–【课程设计】
文章所使用代码如下:
限制功能的代码:(免费)
https://download.youkuaiyun.com/download/dearmite/90199819?spm=1001.2014.3001.5503
全部代码:不白嫖
https://download.youkuaiyun.com/download/dearmite/90201612?spm=1001.2014.3001.5503

用来完成大作业的。文档内容: 1 Java技术体系 1.1 Java语言 1.2 Java平台 1.3 Java应用领域 2 Java语言的技术特点 2.1 1 2.2 2 2.3 3 3 Java语言与C++的异同分析总结。 4 选用C和java语言时编程算法程序有什么不同,有什么优势和劣势。 5 自己编程学习的级别和状态。以及自己以后的编程学习的计划和想法。 6 下面3道题目中选一道,给出算法分析和程序。 1)“黄金分割数”在我们的生活中很常见,但是在不同的应用领域,要求的精度也不一样。 例如:三位小数是0.618 现在我们需要你能求出保留100位小数的黄金分割数,采用的算法为“分层计算法”: 黄金数= 1 --------------- 1+ 1 ------------- 1+ 1 ----------- 1+ 1 --------- ..... 注意,计算出的结果,如果第100位为0也需要保留。 2)已知一个数列: 5,2,4,3,7,6 那么,在这个数列中存在这样一些“连续数”,例如:5,2,4,3这个子数列排序后是连续的。同样2,4,3也是连续的,为了方便表示 我们使用下标来标识,这样,这个数列中存在以下“连续数”: [1,1] [1,4] [1,6] [2,2] [2,4] [3,3] [3,4] [4,4] [5,5] [5,6] [6,6] 这样,他就存在11个“连续数”。现在需要你在用户找出一个数组中所有的“连续数”。 要求: 1、用户输入一个整数N,表示下面数组的个数 2、用户每输入一行作为一个数组 如: 用户输入: 1 5,2,4,3,7,6 程序输出: 11 3)有一种数我们称之为幸运数,它的特点是这样的,首先,由自然数按顺序排列: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 … 这样,1比较特殊, 1为第一个幸运数,那么,我们移除掉序号能被2整除的数(注意:是序号,而不是数本身,每次移除后都重新排序)就剩下: 1 3 5 7 9 11 13 15 17 19… 3为第二个幸运数,那么我们需要去掉序号能被3(下一次是除4,然后是5,每次加1)整除的数,5 11 17...剩下: 1 3 7 9 13 15 19… 那么7为第三个幸运数,后面的幸运数,依此类推,移除之后剩下的数字都是幸运数。 现在我们需要你求出给定的m和n之间的幸运数的个数: 例如:给定1 20,那么个数为:5(5个幸运数分别是1,3,7,13,19) 现在要求用户输入两个数m和n(m<n<=1000*1000),输出幸运数的个数。 例如: 用户输入: 1 20 程序输出: 5 格式:小四,1.5倍行距
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

项目张雪峰之巅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值