设计原因
上学期学了Java后,懵懵懂懂,这次设计主要是为了巩固Java知识,并进一步加深到Java的认识,本来一开始想写个五子棋,但贪吃蛇相对于五子棋来说,更容易实现一些,因此先完成贪吃蛇,再完成五子棋的设计.
设计功能
1.有好看的UI设计(墙,网格线,蛇,食物).
2.能播放音乐切歌功能.
3.增加玩家模式,AI模式选项功能.
4.能调游戏难度,或者随时间增加难度逐渐增大.
5.界面有长度,时间,歌曲,刷新频率,游戏说明显示
设计思路
首先从基础入手,先做一个界面出来,JFrame,JPanel,JLabel简单嵌套,使用简单无布局模式,用setBounds()确定标签位置即可,然后是整体坐标的确定,这里我设置的是7<=x<=491,12<=y<=474,由于画图每一点占用20px,空隙2px,因此点与点之间间隔22px,用类SnakeNode表示蛇节点,食物位置用随机数刷新,只要不与蛇身重叠就行,用线程Thread间隔300ms执行蛇身运动和组件的repaint,用线程Time间隔1000ms来计算游戏时间,用线程来播放音乐。蛇运动与撞墙判定条件简单,重点是如何设计一个AI版的贪吃蛇,因此我参考了网上的一些方法.
if(能吃到食物)
派虚拟蛇去吃,
if(吃完能跟着蛇尾走) 真蛇去吃
if(吃完不能跟着蛇尾) 真蛇跟着蛇尾走
else
真蛇跟着蛇尾
if(不能吃食物也不能跟着蛇尾)随便逛逛,
这里我的问题是如何派虚拟蛇去吃,最近几天一直在研究,由于其他原因,先更新博客,然后再下一次的改动把AI版阐述清楚.
设计说明
一些具体的参数未列出来,但大体差不多.部分采用伪代码形式
/* 变量说明*/
int SnakeLength; //蛇长.
int Hour,Minute,Second; //当前游戏时间.
final int MaxSnakeLength = 100; //蛇最大长度
String []SongName; //歌曲名字
JLabel []label; //UI显示组件
Thread run ; //游戏运行线程类.
SnakeNode head; //蛇头
SnakeNode []body; //蛇身
/*SnakeNode类说明*/
public class SnakeNode {
public int x,y; //蛇节点坐标.
public SnakeNode(int x1,int y1){
this.x = x1;
this.y = y1;
}
public SnakeNode(){
x = 0;
y = 0;
}
}
//initialData()函数名
/* 函数功能,初始化各参数*/
SnakeLength = 3 ; //蛇长初始化.
Current_direction = "R" ; //蛇行走方向.
Hour = 0 , Minute = 0 , Second = 0 ; //游戏时间初始化.
pause = false ; //游戏默认不暂停.
head = new SnakeNode(227,100); //蛇头初始化.
body[] = new SnakeNode(0,0); //各蛇身节点初始化.
/* 函数功能,产生食物随机坐标*/
随机生成食物坐标X,Y
while(1){
if (食物坐标与蛇身坐标或蛇头坐标冲突){
重新随机生成食物坐标X,Y
}else{
退出循环
}
}
/* 函数功能,吃食物*/
if (蛇头坐标与食物坐标重合){
能吃,返回true;
}else{
不能吃,返回false;
}
/* 函数功能,撞墙*/
if (蛇头坐标符合撞墙条件){
if (用户选择重新开始){
调用初始化initialData();函数
重新开始
}else{
结束游戏
}
}else{
什么事也不做
}
/* 函数功能,撞自己*/
if (蛇头坐标与身体坐标重合){
//游戏结束,死亡
if (用户选择重新开始){
调用初始化initialData();函数
重新开始
}else{
结束游戏
}
}else{
什么事也不做
}
/*函数功能,用户按键*/
if (用户按下UP键){
if (当前方向不是向下){
当前方向向上
}
}
if (用户按下DOWN键){
if (当前方向不是向上){
当前方向向下
}
}
if (用户按下LEFT键){
if (当前方向不是向右){
当前方向向左
}
}
if (用户按下RIGHT键){
if (当前方向不是向右){
当前方向向右
}
}
if (用户按下ENTER键){
切换当前歌曲
}
if (用户按下ESC键){
游戏重新开始.
}
/* 蛇身移动*/
用户按下方向键后,蛇头向前移动,紧跟蛇头的下一节点的坐标就是蛇头坐标,以此类推,能实现
蛇身移动.
if (蛇能吃到食物){
蛇变长,原来食物位置变为蛇头位置,然后按蛇身移动处理,只是需要把之前蛇尾坐标加上,因为长度加一
}
/* 画图函数,swing组件方法*/
Graphics g1;
Graphics2D g = (Graphics2D)g1;
g.setColor(); //设置颜色
g.fillRoundReat(); //设置圆角矩形
g.setPaint(new GradientPaint()); //设置渐变颜色
g.fillOval(); //设置填充矩形.
g.setStroke(); //定义画笔属性,粗细等.
g.setBackground(); //设置背景颜色
g.drawRect(); //画矩形
g.drawLine(); //画一条直线.
一些线程类由于太过基础,这里未列出来.
运行截图.
后期改进
1.能增加选项功能,主要用来切换背景.
2.增加障碍墙功能
3.增加游戏通关(下一关)模式
4.增加虚拟路径指导功能(动态规划路线)
5.增加更多的AI模式(无脑,普通AI,高级AI功能)
6.修改游戏难度
7.能引入对抗模式
实验总结
在完成了该贪吃蛇项目后,进一步加深对java的理解,虽然我对面向对象不是太过于熟练,下次争取改进,然后学会了基础的Thread,swing,音乐播放等等功能,虽然功能有些欠缺,但下一次争取做得更好.下一次博客更新是完成一个AI版的井字棋,然后进一步是AI版的五子棋,下下次是oj的搭建,暂时先这样吧。
源码上传至
https://github.com/Githubforusc2018/AI_Snake/tree/master