设计原因

上学期学了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();	//画一条直线.

一些线程类由于太过基础,这里未列出来.

运行截图.

java制作贪吃蛇游戏有关的ppt java贪吃蛇设计报告_贪吃蛇

后期改进

1.能增加选项功能,主要用来切换背景.
2.增加障碍墙功能
3.增加游戏通关(下一关)模式
4.增加虚拟路径指导功能(动态规划路线)
5.增加更多的AI模式(无脑,普通AI,高级AI功能)
6.修改游戏难度
7.能引入对抗模式

实验总结

在完成了该贪吃蛇项目后,进一步加深对java的理解,虽然我对面向对象不是太过于熟练,下次争取改进,然后学会了基础的Thread,swing,音乐播放等等功能,虽然功能有些欠缺,但下一次争取做得更好.下一次博客更新是完成一个AI版的井字棋,然后进一步是AI版的五子棋,下下次是oj的搭建,暂时先这样吧。

源码上传至
https://github.com/Githubforusc2018/AI_Snake/tree/master