连连看-JAVA课程设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计
2013 ~ 2014学年第二学期
设计题目连连看游戏程序
院(系)
专业软件工程
班级学号
学生姓名
设计时间 2014年6月24日~2014年6月27日
指导教师
提交日期 2014年6月27日
目录
目录 (2)
1.课程设计的目的与要求 (3)
1.1课程设计目的与要求 (3)
1.2课程设计内容 (3)
1.3课程设计的实验环境 (3)
1.4课程设计的预备知识 (3)
2.系统模块结构图 (4)
2.1 模块设计 (4)
2.1.1 菜单控制模块 (4)
2.1.2 算法模块 (5)
2.1.3 界面显示模块 (7)
3.详细设计 (9)
3.1总体算法思路 (9)
3.2代码实现 (9)
4.小结 (9)
1.课程设计的目的与要求
1.1课程设计目的与要求
1.掌握JA V A语言中面向对象的概念,并能在程序中熟练运用。
2.了解面向对象程序设计(JA V A)的基本概念以及运用面向对象技术进行程序设计的基本思
想。
3.能正确编写和调试JA V A程序。
4.了解在JA V A环境下进行程序设计的基本思想和方法。
1.2课程设计内容
1.设计一个连连看的游戏程序。
2.在JA V A环境下,将上述程序使用GUI、数据结构等内容完成
3.设计思路:
(1)界面设计
1)初始测试界面可以考虑使用简单的按钮来代表连连看游戏中的图标。
2)布局可以考虑使用GRID方式。
3)设计菜单选择连连看难度等内容,具体可参照QQ连连看,也可自定义。
4)考虑完善界面,例如动画等。
(2)代码设计
1)本设计的核心为练练看算法的设计,可以考虑数据结构中的图的遍历章
节,合理设计算法,将界面中各按钮的分布映射入数学矩阵进行路径规划。
(可以上网搜索相关算法)。
2)完成连连看游戏的图形、算法等代码的设计。
4.实验步骤(包括操作方法、数据处理)
(1)界面设计
(2)算法设计
(3)代码设计
1.3课程设计的实验环境
硬件要求能运行Windows xp/7操作系统的微机系统。
JAVA程序设计语言及相应的集成开发环境, ECLIPSE开发工具。
1.4课程设计的预备知识
熟悉JAVA语言及ECLIPSE开发工具。
2.系统模块结构图
根据对“连连看”游戏的分析,该游戏可分为三个模块:算法模块、界面显示模块、控制模块。
如下图3-1所示:
2.1 模块设计
2.1.1控制模块
(1). 开始游戏
(2). 游戏结束后重新开始
(3). 提示
(4). 不能操作后自动洗牌
如下图3-5所示
2.1.2 算法模块
在检验两个方块能否消掉的时候,我们要让两个方块同时满足两个条件才行,就是两者配对并且连线成功。
如图4-3所示
分 3 种情况:从下面的这三种情况,我们可以知道,需要三个检测,这三个检测分别检测一条直路经。
这样就会有三条路经。
若这三条路经上都是空按钮,那么就刚好是三种直线(两个转弯点)把两个按钮连接起来了。
(1)、相邻
(2)、两个按钮分别横向延伸,如果有一条纵向线能将延伸区相连则可消除
(3)、若(2)失败两个按钮分别纵向延伸,如果有一条横向线能将延伸区相连则可消除
若以上三步都失败,说明这两个按钮不可以消去。
具体判断流程见下图
(4)、图片成对加载并打乱
将图片成对的显示在场景中,并打乱主要用的是Map类。
在该类中,用了一个数组以数字标记的形式来记录加载的图片是哪种图片,在每次加载图片的时候是一张图片连续加载四次,以保证加载图片成两对。
然后用数组的随机方法将数组打乱。
(5)、判断两图是否能够相连
两图能相连的所有情况:
(1)(2)(3)
2.1.3 界面显示模块
1、提示
2、统计分数
3、提示是否进行下一局或者退出
3.详细设计
3.1总体算法思路
由两个确定的按钮。
若这两个按钮的数字相等,就开始找它们相连的路经。
这个找路经
* 分3种情况:(从下面的这三种情况,我们可以知道,需要三个检测,这三个检测分别检测一条直路经。
这样就会有
* 三条路经。
若这三条路经上都是空按钮,那么就刚好是三种直线(两个转弯点)把两个按钮连接起来了)
* 1.相邻
*
* 2. 若不相邻的先在第一个按钮的同行找一个空按钮。
1).找到后看第二个按钮横向到这个空按钮
* 所在的列是否有按钮。
2).没有的话再看第一个按钮到与它同行的那个空按钮之间是否有按钮。
3).没有的话,再从
* 与第一个按钮同行的那个空按钮竖向到与第二个按钮的同行看是否有按钮。
没有的话路经就通了,可以消了.
*
* 3.若2失败后,再在第一个按钮的同列找一个空按钮。
1).找到后看第二个按钮竖向到这个空按钮所在的行是否有按钮。
* 2).没有的话,再看第一个按钮到与它同列的那个空按钮之间是否有按钮。
3).没有的话,再从与第一个按钮同列的
* 那个空按钮横向到与第二个按钮同列看是否有按钮。
没有的话路经就通了,可以消了。
*
* 若以上三步都失败,说明这两个按钮不可以消去。
*
3.2代码实现
1、MainFrame.java
jbPrompt.addActionListener(new ActionListener(){//提示按钮增加行为监听
@Override
public void actionPerformed(ActionEvent arg0) {
point sp = new point();
point ep = new point();
game.Tip(sp, ep);
jlb[sp.x-1][sp.y-1].setBorder(BorderFactory.createLineBorder(Color.black));
jlb[ep.x-1][ep.y-1].setBorder(BorderFactory.createLineBorder(Color.black));
//每提示一次减10分
game.deleteScore(10);
}
});
class event implements ActionListener{
//消除两个相同的图片,若相同,则分数加20分;若不同,不作反应
@Override
public void actionPerformed(ActionEvent arg0) {
//重写接口方法
//获取点击位置
myJButton jlbNext = (myJButton) arg0.getSource();
//输出坐标
System.out.println("["+jlbNext.xPoint+","+jlbNext.yPoint+"]");
if(flag)
{
if(game.linkOK(jlbFront.xPoint+1,jlbFront.yPoint+1,jlbNext.xPoint+1,jlbNext.yPoint+1)) {
if(game.needRandom())
{
game.random();
//通过needRandom()调用,实现抖动,并且重置界面
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
if(game.getMyMap()[i+1][j+1]!=0)
jlb[i][j].setIcon(imageIcon[game.getMyMap()[i+1][j+1]-1]);
}
}
}
}
if(game.isWin())
{
//赢的时候,提示按钮功能被屏蔽
jbPrompt.setEnabled(false);
int n =JOptionPane.showConfirmDialog(null, "你的分数是"+game.getScore()+"是否想再来一局?","提示",JOptionPane.YES_NO_OPTION);
//再来一局
if(n == JOptionPane.YES_OPTION){
MainFrame f = new MainFrame();
f.setTitle("~~连连看~~");
f.setVisible(true);
f.setSize(800, 850);
}
}
}
}
class myJButton extends JButton{//实现按钮和图片的比例吻合的功能
/**
*
*/
private static final long serialVersionUID = 1L;
public int xPoint;
public int yPoint;
public myJButton(ScaleIcon imageIcon)
{
super(imageIcon);
}
public void setPoint(int x,int y)
{
xPoint = x;
yPoint = y;
}
}
class ScaleIcon implements Icon{//初始化图标的大小
//private BufferedImage i = null;
private Icon icon = null;
public ScaleIcon(Icon icon) {
this.icon = icon;
}
@Override
public int getIconHeight() {
return icon.getIconHeight();
}
@Override
public int getIconWidth() {
return icon.getIconWidth();
}
public void paintIcon(Component c, Graphics g, int x, int y) { float wid = c.getWidth();
float hei = c.getHeight();
int iconWid = icon.getIconWidth();
int iconHei = icon.getIconHeight();
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.V ALUE_INTERPOLATION_BILINEAR);
g2d.scale(wid / iconWid, hei / iconHei);
icon.paintIcon(c, g2d, 0, 0);
}
}
2、Game.java
public boolean startGame(){
for(i=0;i<sizeX*sizeY;i++)
{
int x = (int) (Math.random()*100);
int a = save[i];
save[i] = save[x];
save[x] = a;
}//产生100张图片
for(i=0;i<sizeX*sizeY;i++)
{
map[i] = save[i];
}//把图片的坐标信息放入map里
for(i=1;i<=sizeX;i++)
{
for(j=1;j<=sizeY;j++)
{
myMap[i][j]=map[(i-1)*sizeY+(j-1)];
}
}//把图片的坐标信息放入map里
return true;
}
public boolean canLink(int startX,int startY,int endX,int endY,int step,int di)
{//判断能否消除
int ss;
for(int i=0;i<4;i++)
{
//横向搜索
int x = startX + dir[0][i];
//纵向搜索
int y = startY + dir[1][i];
//若没搜索到,则跳出
if(x<0||x>sizeX+1||y<0||y>sizeY+1)
{
continue;
}
ss = step;
if(i!=di)
{
ss = step +1;
}
if(ss >=3)
{
continue;
}
if(x==endX&&y==endY)
{
return true;
}
else
{
if(myMap[x][y] == 0 && used[x][y] != true)
{
used[x][y] = true;
if(canLink(x,y,endX,endY,ss,i))
{
return true;
}
used[x][y] = false;
}
else
{
continue;
}
}
}
return false;
}
public boolean linkOK(int startX,int startY,int endX,int endY) {//是否能消掉图片
for(int i=0;i<used.length;i++){
for(int j=0;j<used[i].length;j++)
{
used[i][j]=false;
}
}//初始时,定义所有图片都没用过
used[startX][startY] = true;
if(myMap[startX][startY]!=myMap[endX][endY])
{
return false;
}
if(canLink(startX,startY,endX,endY,-1,-1))
{
myMap[startX][startY] = 0;
myMap[endX][endY] = 0;
GameScore += 20;
return true;
}
else
{
return false;
}
}
public boolean Tip(point sp,point ep)
{//实现提示功能
for(sp.x=1;sp.x<sizeX;sp.x++)
{
for(sp.y=1;sp.y<=sizeY;sp.y++)
{
for(ep.x=1;ep.x<=sizeX;ep.x++)
{
for(ep.y=1;ep.y<=sizeY;ep.y++)
{
for(int i=0;i<used.length;i++){
for(int j=0;j<used[i].length;j++)
{
used[i][j]=false;
}
}//初始时,定义所有图片都没用过
used[sp.x][sp.y] = true;//改变图片的used属性,说明此图片已经消除掉了
if(myMap[sp.x][sp.y]==0||myMap[ep.x][ep.y]==0||
(sp.x==ep.x&&sp.y==ep.y)||myMap[sp.x][sp.y]!=myMap[ep.x][ep.y])
{
continue;
}//若地图里myMap[sp.x][sp.y]或者myMap[sp.x][sp.y]没有图片,则跳出当前循环
if(canLink(sp.x,sp.y,ep.x,ep.y,-1,-1))
{
return true;
}//如果能消除,则返回true
}
}
}
}
return false;
}
public void random()
//实现抖动重置功能
for(int i=1;i<=sizeX;i++)
{
for(int j=1;j<sizeY;j++)
{
if (myMap[i][j]!=0)
{
myMap[i][j] = save[--k];
}
}
}
}
public boolean needRandom()
{//判断是否需要抖动重置,如果无法通过提示功能消除图片,则就需要抖动重置//point startPoint = null;
//point endPoint = null;
if(Tip(new point(),new point()))
{
return false;
}
return true;
}
3、Point.java
package game;
public class point {
public int x,y;
}
4.小结
以上介绍了连连看游戏的设计代码及代码实现,游戏任务不设定限定实际。
所有的图标均采用数组的形式组织。
由于时间有限,这个程序还有需要改进的地方,比如:添加声音,图案比较单一,并且还可以增加一些功能,例如:设定限定时间,暂停,重来一局,等。
这次实训让我学到了许多东西,不仅在理论上对JA V A有了全新的认识,在实践方面也有了一定的提高。
理论与实践相结合,真正做到学以致用,这次实训对我以后学习,找工作有重大意义。
相信这些宝贵经验会成为我以后的重要基石。
这次实训让我明白了团队合作的重要性,保证了效率和准确性。