连连看小游戏Java
- 格式:doc
- 大小:161.00 KB
- 文档页数:17
连连看思路算法及实现1. 任务概述连连看是一款益智类图标消除游戏,玩家需要通过消除相同的图标来获得分数。
该游戏的思路算法主要包括图标布局、路径查找和消除逻辑。
本文将详细介绍连连看游戏的思路算法及其实现。
2. 游戏规则在连连看游戏中,通常会给出一个NxM的矩阵,矩阵中填充了各种不同类型的图标。
玩家需要通过点击两个相同的图标,使它们之间的路径最多只有两个直角转弯,从而消除这两个图标。
被消除的图标将被移除,并且上方的图标将下落填充空缺。
玩家的目标是在限定时间内消除尽可能多的图标,获得尽可能高的分数。
3. 思路算法及实现3.1 图标布局图标布局是连连看游戏的一个重要部分。
在游戏开始前,需要生成一个随机的NxM矩阵,并在每个格子中填充一个随机的图标。
为了保证游戏的可玩性,生成的矩阵需要满足以下条件: - 每个图标在矩阵中至少出现两次,确保存在与之相匹配的图标。
- 任意两个相同图标之间的路径不超过两个直角转弯,确保图标可以被消除。
其实现思路如下: 1. 随机生成NxM矩阵,并初始化为空。
2. 随机选择一个图标,将其填充到矩阵中某个随机的空格子。
3. 将该图标在矩阵中的位置存储到一个列表中。
4. 重复2-3步骤,直到每个图标至少在矩阵中出现两次。
5. 遍历矩阵,对于每一个空格子,随机选择一个已填充的图标填充进去,确保每个图标的数量相等。
6. 返回生成的矩阵。
3.2 路径查找路径查找是连连看游戏的关键算法之一。
在玩家点击两个图标后,需要通过路径查找算法判断这两个图标之间是否存在符合条件的路径。
一种常用的路径查找算法是深度优先搜索(DFS)算法。
其实现思路如下: 1. 从起点图标开始,将其标记为已访问。
2. 对于当前图标的每个相邻图标,判断是否满足消除条件(路径最多只有两个直角转弯)。
3. 如果相邻图标满足消除条件且没有被访问过,则递归调用步骤2。
4. 如果找到了与目标图标相匹配的路径,则返回True,否则返回False。
摘要:近年来,Java作为一种新的编程语言,以其简单性、可移植性和平台无关性等优点,得到了广泛地应用,特别是Java与万维网的完美结合,使其成为网络编程和嵌入式编程领域的首选编程语言。
Java语言的学习热潮并没有因为时间的推移而消退,相反,由于计算机技术的发展所带来的新应用的出现,Java越来越流行,这种情况是以往程序设计语言在其生存周期内所不多见的。
Java语言之所以这样长盛不衰,一是因为其众多的技术特点与现今的应用十分合拍,可以覆盖大部分的需求;二是因为SUN公司不断推出新的版本,完善Java自身的功能。
有了这两点,Java语言成为程序员首选的程序设计开发工具就在情理之中了.连连看来源于街机游戏《四川麻将》和《中国龙》,是给一堆图案中的相同图案进行配对的简单游戏,在2003年,一个叫做朱俊的网友将这种形式搬到了PC上,立刻成为办公一族的新宠,并迅速传遍了世界各地。
饱受工作压力的人们没有太多的时间进行复杂的游戏,而对于这种动动鼠标就能过关的游戏情有独钟。
之后村子的连连看风靡版,阿达的连连看奥运版,连连看反恐版,还有敏敏连连看,水晶连连看等遍地开花,造就了一个连连看的新世界。
连连看游戏有多种地图样式和道具系统、大大加强了游戏的可玩性,是一款老少皆宜的休闲佳品。
关键字:发展,java,连连看,程序设计;1.课程设计介绍课题设计的目的:1) 进一步加深对Java语言的理解和掌握;将所学的JAVA知识运用于实践中。
2) 课程设计将理论与实践相结合,提供了一个既动手又动脑,独立实践的机会,锻炼我们的分析解决;实际问题的能力,提高学生适应实际,实践编程的能力。
3)熟练掌握JAVA语言中图形用户界面程序的编写;4)大体了解怎样用JAVA来编写小游戏的,增强我们实践能力和创新精神的综合培养。
课程设计的要求:由于Java语言是当今流行的网络编程语言,它具有面向对象、跨平台、分布应用等特点。
面向对象的开发方法是当今世界最流行的开发方法,它不仅具有更贴近自然的语义,而且有利于软件的维护和继承学会java程序开发的环境搭建与配置,并在实际运用中学习和掌握Java程序开发的全过程。
连连看小游戏开发教程连连看是一款经典的益智游戏,玩家需要在规定时间内消除相同的图标。
本文将为你详细介绍如何开发一个连连看小游戏。
以下是游戏开发的步骤:1. 游戏规则设计连连看游戏的基本规则是玩家需要通过点击两个相同的图标来消除它们,但这两个图标之间的连线不能超过三个直线。
可以通过第三个图标或直线来连接这两个图标。
在你开始编码之前,需要明确你的游戏规则,并考虑游戏难度、时间限制和游戏界面设计等因素。
2. 确定游戏素材接下来,你需要准备游戏所需的素材。
包括不同种类的图标、游戏背景以及其他界面元素。
你可以通过自己绘制或者使用现成的资源来获得所需的图标和背景。
确保素材的大小和样式一致,以保持游戏整体的美观度。
3. 游戏界面搭建在游戏开始之前,你需要创建一个游戏窗口和菜单。
游戏窗口应该包含游戏背景、图标网格和计时器等元素。
为了增加游戏体验,你可以添加背景音乐和声效。
4. 图标布局生成在游戏开始之前,你需要生成一个包含各种图标的图标布局。
可以采用二维数组来表示图标的排列。
确保图标之间没有直接相连的路径,避免玩家无法消除。
你可以使用随机算法来生成不同的图标布局。
5. 图标点击事件处理当玩家点击某个图标时,需要对点击事件进行处理。
首先,你需要判断点击的图标是否可以被消除。
通过遍历图标布局,找到与点击的图标相同的图标,再判断这两个图标之间是否有可用的路径。
如果存在可用路径,将这两个图标从布局中移除,否则,显示错误信息。
6. 连线绘制在点击两个可消除的图标后,你需要绘制一条连接这两个图标的路径。
可以使用线段或曲线来表示路径。
为了增加视觉效果,你可以在路径上添加动画效果。
7. 游戏结束判断当图标布局中没有可消除的图标时,游戏结束。
你可以在游戏结束后显示玩家的得分和时间,并提供重新开始游戏的选项。
8. 添加额外功能除了基本的连连看功能外,你还可以添加一些额外的功能来提升游戏体验。
比如,添加道具系统、计分系统、关卡设计和多人对战模式等。
连连看游戏分析设计与实现1.连连看(picture matching)游戏简介连连看游戏界面上均匀分布2N个尺寸相同的图片,每张图片在游戏中都会出现偶数次,游戏玩家需要依次找到两张相同的图片,而且这两张图片之间只用横线、竖线相连(连线上不能有其他图片),并且连线的条数不超过3条,那么游戏会消除这两个图片。
连连看是一款广受欢迎的小游戏,它具有玩法简单、耗时少等特征,尤其适合广大白领女性在办公室里休闲、放松.2。
分析连连看连连看是一个小的、简单的游戏程序,所以不需要大量的分析.首先,我们列出用例。
用例不多。
有:用户开始游戏,用户进行配对图片。
图1。
连连看用例图下一步就是为每个用例和相关场景写一个文本描述。
连连看相当简单,只有一个参与者,就是游戏玩家。
在使用这个程序的过程中也不会碰到出错的情况,所以场景也很短。
开始游戏的场景:玩家打开应用程序,点击“开始”按钮,会生成三种不同的图片排列方式(矩阵、竖向、横向排列).配对图片的场景:玩家对图片进行配对,配好后会消除这对图片。
当在规定的时间内配对完所有图片时,弹出胜利对话框,否则弹出失败对话框。
尽管只有2个简单用例,但它们确实揭示了我们所需完成的任务的重要方面。
大的应用程序会有更多的用例,有些更为复杂,有些一样简单。
用例导致了场景。
场景通常要比这个例子中的复杂,反映了在某项特征或功能上,用户和开发者之间的更为细节化的合约。
每个场景所需的细节程序取决于许多方面,但将场景写下来有助于确保每个人理解系统应该完成什么任务。
我们在连连看的用例和场景的呈现上不是太正规。
有时,这种非正规的方式和几张纸或白板就足够了。
更为正规的面向对象方法学在确定用例及相应场景方面有更正规的做法,也提供了特定的软件来创建和跟踪用例和场景。
3.(分析阶段)发现对象、属性和操作通过阅读问题描述以及实际情况,我们得到以下名词清单:图片,游戏视图,图片的排列方式,服务组件.包图通过对问题的声明的名词进行分析,我们得到游戏的包图:图2,连连看包图其中util包负责与图片加载有关的处理,view包负责呈现界面,Object包是整个游戏的配置参数,impl是图片的排列方式,board包含了整个游戏的面板类。
连连看游戏编程教程连连看游戏是一款经典的益智类游戏,其独特的游戏规则让玩家们在娱乐的同时提高了思维能力和反应速度。
本篇文章将为大家介绍如何使用Python语言编写一个简单的连连看游戏。
一、游戏规则的设计在开始编写代码之前,我们需要先设计游戏规则。
连连看游戏的目标是通过消除相同图标的配对来清空游戏界面上的所有方块。
具体的游戏规则如下:1. 游戏界面是一个矩阵,每个方块上都有一个图标。
2. 玩家需要通过连接相同图标的路径来消除方块。
路径只能在水平和垂直方向上进行连接,不能有其他方块阻挡。
3. 每次消除相同图标的方块会得到一定的分数,随着游戏的进行,剩余方块的数量会减少。
4. 游戏会根据玩家的分数和剩余方块数量进行评分和排名。
二、游戏界面的设计在编写代码之前,我们需要使用Python中的图形库创建游戏界面。
这里我们推荐使用Pygame库,它是一款功能强大且易于上手的游戏开发库。
首先,我们需要创建一个窗口以及游戏界面的矩阵。
可以使用Pygame库提供的Surface对象来创建窗口,并使用二维列表来表示游戏界面的矩阵。
接下来,我们需要在窗口中绘制游戏界面的方块和图标。
可以使用Pygame库提供的绘制函数来实现,通过循环遍历游戏界面的矩阵,根据方块的状态来选择绘制的图标。
可以使用不同的颜色或者图片来表示不同的图标。
三、游戏逻辑的设计游戏逻辑是编写连连看游戏的核心部分。
主要包括方块的生成、方块的选择和判断是否可以连接的函数。
首先,在游戏开始时,需要生成随机的方块,并将其放置在游戏界面的矩阵中。
然后,需要实现方块的选择函数,玩家可以通过鼠标点击方块来选择两个需要连接的方块。
可以使用Pygame库提供的事件监听函数来实现。
接下来,需要实现判断两个方块是否可以连接的函数。
主要通过判断两个方块之间是否有可连通的路径来判断它们是否可以连接。
可以使用BFS或DFS等搜索算法来实现。
最后,在两个方块成功连接后,需要将它们从游戏界面的矩阵中移除,并计算玩家得分。
java实现2048⼩游戏(含注释)本⽂实例为⼤家分享了java实现2048⼩游戏的具体代码,供⼤家参考,具体内容如下实现⽂件APP.javaimport javax.swing.*;public class APP {public static void main(String[] args) {new MyFrame();}}类⽂件import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Random;//定义⾃⼰的类(主类)去继承JFrame类并实现KeyListener接⼝和ActionListener接⼝public class MyFrame extends JFrame implements KeyListener, ActionListener {//⽤于存放游戏各位置上的数据int[][] data = new int[4][4];//⽤于判断是否失败int loseFlag = 1;//⽤于累计分数int score = 0;//⽤于切换主题String theme = "A";//设置三个菜单项⽬JMenuItem item1 = new JMenuItem("经典");JMenuItem item2 = new JMenuItem("霓虹");JMenuItem item3 = new JMenuItem("糖果");//核⼼⽅法public MyFrame(){//初始化窗⼝initFrame();//初始化菜单initMenu();//初始化数据initData();//绘制界⾯paintView();//为窗体提供键盘监听,该类本⾝就是实现对象this.addKeyListener(this);//设置窗体可见setVisible(true);}//窗体初始化public void initFrame(){//设置尺⼨setSize(514,538);//设置居中setLocationRelativeTo(null);//设置总在最上⾯setAlwaysOnTop(true);setLayout(null);}//初始化菜单public void initMenu() {//菜单栏⽬JMenuBar menuBar = new JMenuBar();JMenu menu1 = new JMenu("换肤");JMenu menu2 = new JMenu("关于我们");//添加上menuBarmenuBar.add(menu1);menuBar.add(menu2);//添加上menumenu1.add(item1);menu1.add(item2);menu1.add(item3);//注册监听item1.addActionListener(this);item2.addActionListener(this);item3.addActionListener(this);//添加进窗体super.setJMenuBar(menuBar);}//初始化数据,在随机位置⽣成两个2public void initData(){generatorNum();generatorNum();}//重新绘制界⾯的⽅法public void paintView(){//调⽤⽗类中的⽅法清空界⾯getContentPane().removeAll();//判断是否失败if(loseFlag==2){//绘制失败界⾯JLabel loseLable = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-lose.png"));//设置位置和⾼宽loseLable.setBounds(90,100,334,228);//将该元素添加到窗体中getContentPane().add(loseLable);}//根据现有数据绘制界⾯for(int i=0;i<4;i++) {//根据位置循环绘制for (int j = 0; j < 4; j++) {JLabel image = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-"+data[i][j]+".png"));//提前计算好位置image.setBounds(50 + 100 * j, 50+100*i, 100, 100);//将该元素添加进窗体getContentPane().add(image);}}//绘制背景图⽚JLabel background = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-Background.jpg")); //设置位置和⾼宽background.setBounds(40,40,420,420);//将该元素添加进窗体getContentPane().add(background);//得分模板设置JLabel scoreLable = new JLabel("得分:"+score);//设置位置和⾼宽scoreLable.setBounds(50,20,100,20);getContentPane().repaint();}//⽤不到的但是必须重写的⽅法,⽆需关注@Overridepublic void keyTyped(KeyEvent e) {}//键盘被按下所触发的⽅法,在此⽅法中加⼊区分上下左右的按键@Overridepublic void keyPressed(KeyEvent e) {//keyCode接收按键信息int keyCode = e.getKeyCode();//左移动if(keyCode == 37){moveToLeft(1);generatorNum();}//上移动else if(keyCode==38){moveToTop(1);generatorNum();}//右移动else if(keyCode==39){moveToRight(1);generatorNum();}//下移动else if(keyCode==40){moveToBottom(1);generatorNum();}//忽视其他按键else {return;}//检查是否能够继续移动check();//重新根据数据绘制界⾯paintView();}//左移动的⽅法,通过flag判断,传⼊1是正常移动,传⼊2是测试移动 public void moveToLeft(int flag) {for(int i=0;i<data.length;i++){//定义⼀维数组接收⼀⾏的数据int[] newArr = new int[4];//定义下标⽅便操作int index=0;for(int x=0;x<data[i].length;x++){//将有数据的位置前移if(data[i][x]!=0){newArr[index]=data[i][x];index++;}}//赋值到原数组data[i]=newArr;//判断相邻数据是否相邻,相同则相加,不相同则略过for(int x=0;x<3;x++){if(data[i][x]==data[i][x+1]){data[i][x]*=2;//如果是正常移动则加分if(flag==1){score+=data[i][x];}//将合并后的数据都前移,实现数据覆盖for(int j=x+1;j<3;j++){data[i][j]=data[i][j+1];}//末尾补0data[i][3]=0;}//右移动的⽅法,通过flag判断,传⼊1是正常移动,传⼊2是测试移动 public void moveToRight(int flag) {//翻转⼆维数组reverse2Array();//对旋转后的数据左移动moveToLeft(flag);//再次翻转reverse2Array();}//上移动的⽅法,通过flag判断,传⼊1是正常移动,传⼊2是测试移动 public void moveToTop(int flag) {//逆时针旋转数据anticlockwise();//对旋转后的数据左移动moveToLeft(flag);//顺时针还原数据clockwise();}//下移动的⽅法,通过flag判断,传⼊1是正常移动,传⼊2是测试移动 public void moveToBottom(int flag) {//顺时针旋转数据clockwise();//对旋转后的数据左移动moveToLeft(flag);//逆时针旋转还原数据anticlockwise();}//检查能否左移动public boolean checkLeft(){//开辟新⼆维数组⽤于暂存数据和⽐较数据int[][] newArr = new int[4][4];//复制数组copyArr(data,newArr);//测试移动moveToLeft(2);boolean flag = false;//设置break跳出的for循环标记lo:for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {//如果有数据不相同,则证明能够左移动,则返回trueif(data[i][j]!=newArr[i][j]){flag=true;break lo;}}}//将原本的数据还原copyArr(newArr,data);return flag;}//检查能否右移动,与checkLeft()⽅法原理相似public boolean checkRight(){int[][] newArr = new int[4][4];copyArr(data,newArr);moveToRight(2);boolean flag = false;lo:for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if(data[i][j]!=newArr[i][j]){flag=true;break lo;}}}copyArr(newArr,data);//检查能否上移动,与checkLeft()⽅法原理相似public boolean checkTop(){int[][] newArr = new int[4][4];copyArr(data,newArr);moveToTop(2);boolean flag = false;lo:for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if(data[i][j]!=newArr[i][j]){flag=true;break lo;}}}copyArr(newArr,data);return flag;}//检查能否下移动,与checkLeft()⽅法原理相似public boolean checkBottom(){int[][] newArr = new int[4][4];copyArr(data,newArr);moveToBottom(2);boolean flag = false;lo:for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if(data[i][j]!=newArr[i][j]){flag=true;break lo;}}}copyArr(newArr,data);return flag;}//检查是否失败public void check(){//上下左右均不能移动,则游戏失败if(checkLeft()==false&&checkRight()==false&&checkTop()==false&&checkBottom()==false){ loseFlag = 2;}}//复制⼆维数组的⽅法,传⼊原数组和新数组public void copyArr(int[][] src,int[][] dest){for (int i = 0; i < src.length; i++) {for (int j = 0; j < src[i].length; j++) {//遍历复制dest[i][j]=src[i][j];}}}//键盘被松开@Overridepublic void keyReleased(KeyEvent e) {}//翻转⼀维数组public void reverseArray(int[] arr){for(int start=0,end=arr.length-1;start<end;start++,end--){int temp = arr[start];arr[start] = arr[end];arr[end] = temp;}}//翻转⼆维数组public void reverse2Array(){for (int i = 0; i < data.length; i++) {reverseArray(data[i]);//顺时针旋转public void clockwise(){int[][] newArr = new int[4][4];for(int i=0;i<4;i++){for(int j=0;j<4;j++){//找规律啦~newArr[j][3-i] = data[i][j];}}data = newArr;}//逆时针旋转public void anticlockwise(){int[][] newArr = new int[4][4];for(int i=0;i<4;i++){for(int j=0;j<4;j++){//规律newArr[3-j][i] = data[i][j];}}data = newArr;}//空位置随机⽣成2public void generatorNum(){int[] arrarI = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; int[] arrarJ = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; int w=0;for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if(data[i][j]==0){//找到并存放空位置arrarI[w]=i;arrarJ[w]=j;w++;}}}if(w!=0){//随机数找到随机位置Random r= new Random();int index = r.nextInt(w);int x = arrarI[index];int y = arrarJ[index];//空位置随机⽣成2data[x][y]=2;}}//换肤操作@Overridepublic void actionPerformed(ActionEvent e) {//接收动作监听,if(e.getSource()==item1){theme = "A";}else if(e.getSource()==item2){theme = "B";}else if(e.getSource()==item3){theme = "C";}//换肤后重新绘制paintView();}}//测试失败效果的数据/*int[][] data = {{2,4,8,4},{16,32,64,8},{128,2,256,2},{512,8,1024,2048}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
一、实验目的1. 熟悉并掌握使用Java语言进行图形界面编程的基本方法。
2. 理解并运用面向对象编程思想,提高编程能力。
3. 掌握连连看游戏的基本原理和实现方法。
4. 培养团队合作能力和创新意识。
二、实验内容1. 熟悉Java语言的基本语法和面向对象编程思想。
2. 使用Java Swing库开发图形界面。
3. 实现连连看游戏的基本功能,包括游戏界面、数据结构、逻辑算法等。
三、实验环境1. 操作系统:Windows 102. 开发工具:Eclipse3. 编程语言:Java四、实验步骤1. 创建Java项目,命名为“连连看游戏”。
2. 设计游戏界面,包括游戏区域、时间显示、分数显示等。
3. 定义数据结构,用于存储游戏中的图片和匹配关系。
4. 编写游戏逻辑算法,包括初始化游戏、随机生成图片、匹配图片等。
5. 实现游戏控制,包括鼠标点击事件、图片移动、匹配判断等。
6. 编写游戏结束判断和结果显示。
五、实验结果与分析1. 实验结果通过以上步骤,成功开发了一个连连看游戏。
游戏界面美观,功能完善,可以满足用户的基本需求。
2. 实验分析(1)游戏界面设计:采用Java Swing库中的JPanel、JLabel等组件,实现了游戏界面的布局。
通过设置背景图片、颜色等属性,使游戏界面更具吸引力。
(2)数据结构:使用二维数组存储游戏中的图片,每行每列代表一个位置。
通过遍历数组,判断相邻图片是否可以匹配。
(3)逻辑算法:在游戏开始时,随机生成图片并存储到数组中。
当用户点击一个图片时,判断其相邻图片是否可以匹配。
如果可以匹配,则将这两个图片移动到一起,并更新分数和时间。
(4)游戏控制:通过监听鼠标点击事件,实现图片的移动和匹配判断。
当图片移动到一起时,判断是否匹配,并更新游戏状态。
六、实验总结1. 通过本次实验,掌握了Java语言的基本语法和面向对象编程思想,提高了编程能力。
2. 熟悉了Java Swing库在图形界面编程中的应用,为以后开发类似项目奠定了基础。
连连看思路算法及实现连连看是一款经典的益智游戏,其玩法简单,规则清晰,深受广大玩家喜爱。
在这个游戏中,我们需要通过消除相同的图案来获得高分。
而要想在游戏中取得好成绩,则需要掌握一定的思路算法和实现方法。
一、思路算法1.寻找相同图案在连连看游戏中,最基本的操作就是寻找相同的图案。
因此,在进行游戏时,我们需要将所有可消除的图案都找出来,并建立起它们之间的关联关系。
2.建立关联关系建立图案之间的关联关系是为了方便后续操作。
我们可以使用二维数组或者链表等数据结构来存储每个图案以及它们之间的连接情况。
对于每一个图案,我们可以将其坐标作为数组下标,并将其与周围相邻的图案进行连接。
3.寻找可消除路径在建立好每个图案之间的连接关系后,我们就可以开始寻找可消除路径了。
通常情况下,可消除路径有两种:直线型和弯曲型。
对于直线型路径,我们只需要判断两个图案之间是否存在直线连接即可;而对于弯曲型路径,则需要考虑路径中是否存在转折点。
4.消除图案当我们找到了可消除路径后,就可以进行图案的消除操作了。
在消除时,我们需要将所有经过的图案都从数据结构中删除,并将得分累加到总分中。
此外,在进行消除操作时,我们还需要考虑一些特殊情况,如图案之间存在障碍物等。
5.判断游戏结束当所有的图案都被消除或者无法再进行消除操作时,游戏就结束了。
在判断游戏是否结束时,我们可以检查当前数据结构中是否还有未被消除的图案。
如果存在未被消除的图案,则说明游戏还未结束;否则,游戏就已经结束了。
二、实现方法1.数据结构在实现连连看游戏时,我们通常使用二维数组或链表等数据结构来存储每个图案以及它们之间的连接关系。
对于二维数组来说,其优点是存储简单、操作方便;而链表则更加灵活,可以动态地添加和删除元素。
2.算法实现在实现连连看游戏时,我们需要编写一些算法来完成相应的功能。
例如,在寻找可消除路径时,我们可以使用广度优先搜索算法(BFS)或深度优先搜索算法(DFS)来遍历所有可能的路径,并找到其中符合要求的路径。
连连看游戏(C#)自己动手做一个简单的连连看游戏。
(很多可扩展的空能,留给各位自行扩展)游戏规则就不说了,大家应该都知道吧。
运行画面:图标区域就是连连看的操作区域,这部分的表示是程序随机生成的。
1,通过先后点击2个图标,程序会判断这2个图标是否可连接,如果可以连接就将这2个图标从图中消失(截图中,空白的2个图标,就是连接后,消失的)。
2,左下是计时区域。
目前可以计时,但时间倒数为0时,程序不会自动终止(各位可以自行实现这个功能)。
3,右上是设定区域。
当第一局游戏结束后,可以通过点击按钮“再开始”以开始新的游戏。
游戏模式可以自行设定。
例如“15*12----6”代表15行、12列、每种图标数量为6个(可以计算出需要15*12/6=30 个不同的图标)。
4,右下是帮助区域。
当找不到可以连接的图标时,可以点下“Help”寻求程序帮助(现状当程序无解的时候,不会自动提醒玩家,各位可自行实现)。
想要重排画面上的图标时(有时候很长时间都找不到怎么连接),可以点击“画面Data调整”按钮(各位可以自行实现)。
CheckBox“连接线表示”是在玩家点击了2个图标后,程序自动描画一个连接2个图标的线。
CheckBox“空格子表示”是为了给消失了的格子画线,不勾上的时候,消失的格子将不会有虚线框表示。
程序结构:1,Group文件夹内是44个系统图片,用来表示相同的格子。
代码中随机生成的是2维int数组,但是表示的时候,将相同的int数字用图片代替。
每一局游戏的图片都是随机从这44个图片中产生的。
2,Form1。
就是我们所看到的的主画面。
3,PnlCanvas。
左上操作区域的画布控件。
程序主要代码:各位可以自行尝试,或发邮件至********************索取源代码1,Form1.cs:using System;using System.Collections.Generic;using System.Drawing;using System.Windows.Forms;namespace GameLianliankan{public partial class Form1 : Form{///<summary>空位置坐标</summary>private static Point NullPoint = new Point(-1, -1);///<summary>空值</summary>private static int NullNum = -1;///<summary>横向起点基准坐标</summary>private static int basePX = 30;///<summary>纵向起点基准坐标</summary>private static int basePY = 30;///<summary>前一次选中格子的颜色</summary>private Color preClickBorderColor = Color.DeepPink;///<summary>前一次选中格子的位置</summary>private Point preClickPoint = NullPoint;///<summary>ヘルプ点1</summary>private Point ptHelp1 = NullPoint;///<summary>ヘルプ点2</summary>private Point ptHelp2 = NullPoint;private Color helpBorderColor = Color.DeepSkyBlue;private int totalTime = 600;private int curTime = 0;///<summary>每一个格子横向宽度</summary>private int lengthX = 50;///<summary>每一个格子纵向高度</summary>private int lengthY = 50;///<summary>格子值二维数组</summary>private int[,] aryPic;///<summary>连连看游戏图标</summary>private List<Icon> lstIcons = new List<Icon>();///<summary>格子值与图标Index之间的关系</summary>private Dictionary<int, int> dicValueToIndex = new Dictionary<int, int>();public Form1(){InitializeComponent();}///<summary>///画面Load場合、データ作成///</summary>///<param name="sender"></param>///<param name="e"></param>private void Form1_Load(object sender, EventArgs e){this.cmbKind.SelectedIndex = 0;for (int i = 1; i < 100; i++){object ob =Properties.Resources.ResourceManager.GetObject(string.Format("_{0}", i.ToString("00")));if (ob is Icon){Icon icon = ob as Icon;if (icon.Width == 32 && icon.Height == 32){lstIcons.Add(icon);}else{icon.Dispose();icon = null;}}}btnRestart_Click(null, null);}///<summary>///画面データ再作成///</summary>///<param name="sender"></param>///<param name="e"></param>private void btnRestart_Click(object sender, EventArgs e){this.ptHelp1 = NullPoint;this.ptHelp2 = NullPoint;timer.Stop();pgbTime.Value = 100;curTime = 0;int perCount = GetSetRowColCount();dicValueToIndex.Clear();//例:「列、行」aryPic = new int[(pnlShow.Width - 2 * basePX) / lengthX, (pnlShow.Height - 2 * basePY) / lengthY];Random random = new Random(Environment.TickCount);List<int> lstIndex = new List<int>();for (int i = 0; i < lstIcons.Count; i++){lstIndex.Add(i);}List<int> lstRandom = new List<int>(aryPic.GetLength(0) *aryPic.GetLength(1));for (int i = 0; i * perCount < lstRandom.Capacity; i++){for (int j = 0; j < perCount; j++){lstRandom.Add(i + 1);}int index = random.Next(0, lstIndex.Count - 1);dicValueToIndex.Add(i + 1, lstIndex[index]);lstIndex.RemoveAt(index);}//行for (int i = 0; i < aryPic.GetLength(1); i++){//列for (int j = 0; j < aryPic.GetLength(0); j++){int index = random.Next(0, lstRandom.Count - 1);aryPic[j, i] = lstRandom[index];lstRandom.RemoveAt(index);}}this.pnlShow.Refresh();timer.Start();}///<summary>///データを表示///</summary>///<param name="sender"></param>///<param name="e"></param>private void pnlShow_Paint(object sender, PaintEventArgs e) {#region基本格子的描画//行for (int i = 0; i < aryPic.GetLength(1); i++){//列for (int j = 0; j < aryPic.GetLength(0); j++){Rectangle rect = new Rectangle(new Point(j * lengthX + basePX, i * lengthY + basePY), new Size(lengthX, lengthY));if (aryPic[j, i] == NullNum){if (chkIsNullShow.Checked){using (Pen pen = new Pen(Color.Red)){pen.DashStyle =System.Drawing.Drawing2D.DashStyle.Dot;e.Graphics.DrawRectangle(pen, rect);}}continue;}using (Pen pen = new Pen(Color.LightSteelBlue)){e.Graphics.DrawRectangle(pen, rect);}#regionアイコン描画int index = dicValueToIndex[aryPic[j, i]];rect.X += (rect.Width - lstIcons[index].Width) / 2;rect.Y += (rect.Height - lstIcons[index].Height) / 2;e.Graphics.DrawIconUnstretched(lstIcons[index], rect);#endregion//TextRenderer.DrawText(e.Graphics, aryPic[j, i].ToString(), this.Font, rect, Color.Black);}}#endregion#region选中格子的描画if (preClickPoint != NullPoint){Rectangle rect = new Rectangle(new Point(preClickPoint.X * lengthX + basePX, preClickPoint.Y * lengthY + basePY), new Size(lengthX, lengthY));using (Pen pen = new Pen(preClickBorderColor)){pen.Width = 2;e.Graphics.DrawRectangle(pen, rect);}using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, preClickBorderColor))){e.Graphics.FillRectangle(brush, rect);}}#endregion#region帮助格子的描画if (ptHelp1 != NullPoint && ptHelp2 != NullPoint){Rectangle rect1 = new Rectangle(new Point(ptHelp1.X * lengthX + basePX, ptHelp1.Y * lengthY + basePY), new Size(lengthX, lengthY));Rectangle rect2 = new Rectangle(new Point(ptHelp2.X * lengthX + basePX, ptHelp2.Y * lengthY + basePY), new Size(lengthX, lengthY));using (Pen pen = new Pen(helpBorderColor)){pen.Width = 2;e.Graphics.DrawRectangle(pen, rect1);e.Graphics.DrawRectangle(pen, rect2);}using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, helpBorderColor))){e.Graphics.FillRectangle(brush, rect1);e.Graphics.FillRectangle(brush, rect2);}}#endregion}///<summary>///クリックエベント///</summary>///<param name="sender"></param>///<param name="e"></param>private void pnlShow_MouseClick(object sender, MouseEventArgs e) {if (e.X < basePX || e.Y < basePY){preClickPoint = NullPoint;pnlShow.Refresh();return;}//列int x = (e.X - basePX) / lengthX;//行int y = (e.Y - basePY) / lengthY;if (x >= aryPic.GetLength(0) || y >= aryPic.GetLength(1)){preClickPoint = NullPoint;pnlShow.Refresh();return;}if (aryPic[x, y] == NullNum){preClickPoint = NullPoint;}else{ptHelp1 = NullPoint;ptHelp2 = NullPoint;if (preClickPoint == NullPoint){preClickPoint.X = x;preClickPoint.Y = y;}else if (preClickPoint.X == x && preClickPoint.Y == y){return;}else{Point curClickPoint = new Point(x, y);bool isOK = TryToConnect(preClickPoint, curClickPoint);if (isOK){aryPic[preClickPoint.X, preClickPoint.Y] = NullNum; aryPic[curClickPoint.X, curClickPoint.Y] = NullNum; }else{}preClickPoint = NullPoint;}}pnlShow.Refresh();}///<summary>///帮助按钮按下后,由程序寻找可连接的两个格子///</summary>///<param name="sender"></param>///<param name="e"></param>private void btnHelp_Click(object sender, EventArgs e){bool existFlg = false;for (int i = 0; i < aryPic.GetLength(0); i++){for (int j = 0; j < aryPic.GetLength(1); j++){if (aryPic[i, j] == NullNum) continue;existFlg = true;for (int m = i; m < aryPic.GetLength(0); m++){for(int n = ((m == i) ? j + 1 : 0); n < aryPic.GetLength(1); n++) {if (aryPic[m, n] == NullNum) continue;if (aryPic[i, j] != aryPic[m, n]) continue;if (TryToConnect(new Point(i, j), new Point(m, n))){ptHelp1.X = i;ptHelp1.Y = j;ptHelp2.X = m;ptHelp2.Y = n;this.pnlShow.Refresh();return;}}}}}if (!existFlg){MessageBox.Show("所有格子都已连接完毕,请重新开始游戏!");}else{MessageBox.Show("已无可连接格子!\r\n请点击「画面データ調整」按钮以随机调整!");}}///<summary>///画面上剩余的格子数剧随机再调整///</summary>///<param name="sender"></param>///<param name="e"></param>private void btnResort_Click(object sender, EventArgs e){MessageBox.Show("...待实现...");}///<summary>///空格子表示///</summary>///<param name="sender"></param>///<param name="e"></param>private void chkIsNullShow_CheckedChanged(object sender, EventArgs e) {this.pnlShow.Refresh();}///<summary>///画面表示///</summary>///<param name="sender"></param>///<param name="e"></param>private void chkMode_CheckedChanged(object sender, EventArgs e){if (!chkMode.Checked){this.Width = 1011;chkMode.Text = "<";}else{this.Width = 685;chkMode.Text = ">";}}///<summary>///快捷键///</summary>///<param name="sender"></param>///<param name="e"></param>private void Form1_KeyDown(object sender, KeyEventArgs e){//ヘルプif (e.KeyCode == Keys.F1){this.btnHelp_Click(null, null);}//再開始else if (e.KeyCode == Keys.F5){if (MessageBox.Show("再開始?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes) {this.btnRestart_Click(null, null);}}}private void timer_Tick(object sender, EventArgs e){curTime++;int value = (totalTime - curTime) * 100 / totalTime;if (value < 0) value = 0;pgbTime.Value = value;this.lblTime.Text = string.Format("{0}:{1}", ((totalTime - curTime) / 60).ToString("00"), ((totalTime - curTime) % 60).ToString("00"));}#region主要方法///<summary>///連接計算///</summary>///<param name="preClickPoint"></param>///<param name="curClickPoint"></param>private bool TryToConnect(Point ptFrom, Point ptTo){if (ptFrom == NullPoint || ptTo == NullPoint){return false;}if (ptFrom.X < 0|| ptFrom.Y < 0|| ptFrom.X > aryPic.GetLength(0) - 1|| ptFrom.Y > aryPic.GetLength(1) - 1){return false;}if (ptTo.X < 0|| ptTo.Y < 0|| ptFrom.X > aryPic.GetLength(0) - 1|| ptFrom.Y > aryPic.GetLength(1) - 1){return false;}//值相等判断if (aryPic[ptFrom.X, ptFrom.Y] != aryPic[ptTo.X, ptTo.Y]){return false;}bool ret = false;#region横向联通判断for (int m = -1; m <= aryPic.GetLength(1); m++){bool isTry = true;//超过范围内的默认为联通if (m == -1 || m == aryPic.GetLength(1)){ }else{int start = ptFrom.X > ptTo.X ? ptTo.X : ptFrom.X;int end = ptFrom.X + ptTo.X - start;//判断是否联通for (int n = start; n <= end; n++){if ((ptFrom.X == n && ptFrom.Y == m) || (ptTo.X == n && ptTo.Y == m)){continue;}if (aryPic[n, m] != NullNum){isTry = false;break;}}}if (!isTry) continue;int from = ptFrom.Y > m ? m : ptFrom.Y;int to = ptFrom.Y + m - from;for (int t = from; t < to; t++){if (t == -1 || t == aryPic.GetLength(1)) continue;if (ptFrom.Y == t) continue;if (aryPic[ptFrom.X, t] != NullNum){isTry = false;break;}}if (!isTry) continue;from = ptTo.Y > m ? m : ptTo.Y;to = ptTo.Y + m - from;for (int t = from; t < to; t++){if (t == -1 || t == aryPic.GetLength(1)) continue;if (ptTo.Y == t) continue;if (aryPic[ptTo.X, t] != NullNum){isTry = false;break;}}if (isTry){ret = true;if (chkIsLineShow.Checked){DrawConnectLines(false, m, ptFrom, ptTo);}break;}}#endregionif (ret){return ret;}#region纵向联通判断for (int m = -1; m <= aryPic.GetLength(0); m++){bool isTry = true;if (m == -1 || m == aryPic.GetLength(0)){ }else{int start = ptFrom.Y > ptTo.Y ? ptTo.Y : ptFrom.Y;int end = ptFrom.Y + ptTo.Y - start;for (int n = start; n <= end; n++){if ((ptFrom.X == m && ptFrom.Y == n) || (ptTo.X == m && ptTo.Y == n)){continue;}if (aryPic[m, n] != NullNum){isTry = false;break;}}}if (!isTry) continue;int from = ptFrom.X > m ? m : ptFrom.X;int to = ptFrom.X + m - from;for (int t = from; t < to; t++){if (t == -1 || t == aryPic.GetLength(0)) continue;if (ptFrom.X == t) continue;if (aryPic[t, ptFrom.Y] != NullNum){isTry = false;break;}}if (!isTry) continue;from = ptTo.X > m ? m : ptTo.X;to = ptTo.X + m - from;for (int t = from; t < to; t++){if (t == -1 || t == aryPic.GetLength(0)) continue;if (ptTo.X == t) continue;if (aryPic[t, ptTo.Y] != NullNum){isTry = false;break;}}if (isTry){ret = true;if (chkIsLineShow.Checked){DrawConnectLines(true, m, ptFrom, ptTo);}break;}}#endregionreturn ret;}///<summary>///連接可、連接線を表示///</summary>///<param name="isVertical"></param>///<param name="posi"></param>///<param name="ptFrom"></param>///<param name="ptTo"></param>private void DrawConnectLines(bool isVertical, int posi, Point ptFrom, Point ptTo){List<Point> lstPoint = new List<Point>();lstPoint.Add(GetCenterPoint(ptFrom));if (!isVertical){if (posi == ptFrom.Y && posi == ptTo.Y){ }else if (posi == ptFrom.Y){lstPoint.Add(GetCenterPoint(ptTo.X, posi));}else if (posi == ptTo.Y){lstPoint.Add(GetCenterPoint(ptFrom.X, posi));}else{lstPoint.Add(GetCenterPoint(ptFrom.X, posi));lstPoint.Add(GetCenterPoint(ptTo.X, posi));}}else{if (posi == ptFrom.X && posi == ptTo.X){ }else if (posi == ptFrom.X){lstPoint.Add(GetCenterPoint(posi, ptTo.Y));}else if (posi == ptTo.X){lstPoint.Add(GetCenterPoint(posi, ptFrom.Y));}else{lstPoint.Add(GetCenterPoint(posi, ptFrom.Y));lstPoint.Add(GetCenterPoint(posi, ptTo.Y));}}lstPoint.Add(GetCenterPoint(ptTo));using (Pen pen = new Pen(Color.DarkRed)){this.pnlShow.CreateGraphics().DrawLines(pen, lstPoint.ToArray()); System.Threading.Thread.Sleep(400);}}#region内部方法///<summary>//////</summary>///<param name="pt"></param>///<returns></returns>private Point GetCenterPoint(Point pt){return GetCenterPoint(pt.X, pt.Y);}///<summary>//////</summary>///<param name="posiX"></param>///<param name="posiY"></param>///<returns></returns>private Point GetCenterPoint(int posiX, int posiY){return new Point(posiX * lengthX + basePX + lengthX / 2, posiY * lengthY + basePY + lengthY / 2);}#endregion#endregionprivate int GetSetRowColCount(){int ret = 6;switch (this.cmbKind.SelectedIndex){//12*12----8case 1:this.lengthX = 50;this.lengthY = 50;ret = 8;break;//12*12----12case 2:this.lengthX = 50;this.lengthY = 50;ret = 12;break;//15*12----6case 3:this.lengthX = 50;this.lengthY = 40;ret = 6;break;//15*12----10case 4:this.lengthX = 50;this.lengthY = 40;ret = 10;break;//15*12----12case 5:this.lengthX = 50;this.lengthY = 40;ret = 12;break;//12*12----6default:this.lengthX = 50;this.lengthY = 50;ret = 6;break;}return ret;}}}2,Form1.Designer.csnamespace GameLianliankan{partial class Form1{///<summary>///必要なデザイナ変数です。
Java程序课程设计任务书一、主要任务与目标1、了解图形用户界面的概念;2、了解AWT的基本体系结构,掌握窗口的基本原理;3、掌握几种布局管理器的使用方法;4、掌握java的事件处理机制;5、了解Swing的基本体系结构,掌握Swing组件的使用方法;6、掌握java小程序的工作原理和使用方法;7、该游戏还将设置退出,再来一局按钮,并实现相应的功能。
8、设计一个用户注册登录界面二、主要内容与基本要求游戏规则是模仿网络上普通的连连看游戏,主要是鼠标两次点击的图片能否消去的问题。
当前,前提是点击两张相同的图片,若点击的是同一张图片或者两张不同的图片,则不予处理。
在两张想同图片所能连通的所有路径中,如果存在一条转弯点不多于两个的路径,就可以消去;如果没有,则不予处理。
该游戏由30张不同的图片组成,游戏开始将会出现30张随机组合的图片,在规则下点击两张相同的图片后图片将会消失。
图片全部消完为游戏成功。
游戏还将设置退出,再来一局的按钮,和倒计时的功能,方便用户进行操作。
并且有一个用户登录注册界面,玩家必须登录以后才可以进行游戏。
三、计划进度12月28日~ 12月29日:课程设计选题,查找参考资料12月30日~ 12月31日:阅读参考书籍,收集资料,完成需求分析1月1日~ 1月3日:系统的代码设计及实现,数据库设计与实现1月4日~ 1月5日:系统的调试,修改,完善1月6日~ 1月7日:完成课程设计报告,准备答辩四、主要参考文献[1] 刘宝林.Java程序设计与案例习题解答与实验指导[M].[2] 王鹏何云峰.Swing图形界面开发与案例分析[M].[3](美)Karl Avedal , Danny Ayers, Timothy Briggs. JSP编程指南[M]. 电子工业出版社, 2004,47-125.[4](美)Mark Linsenbardt. JSP在数据库中的应用与开发[M]. 希望电子出版社,2005,210-236.[5] Dianne Phelan,Building a simple web database application[C].IEEE InternationalProfessional Communication Conference, 2004, 79-86.[6](美)Karl Avedal,Danny Ayers,Timothy Briggs.JSP编程指南[M].电子工业出版社,2006,47-125.[7] Dianne Phelan,Building a simple web database application[C].IEEE InternationalProfessional Communication Conference, 2005, 79-86.[8] Altendorf. Eric, Hohman. Moses, Zabicki. Roman. Using J2EE on a large,web-based project[J]. IEEE Software.2002,19(02):81-89.摘要当今社会,休闲型游戏越来越得到人们的喜爱,我所做的毕业设计实例“连连看游戏的设计与实现”是近几年来网络上非常流行的一种二维休闲游戏,它对电脑配置要求不高,娱乐性强,易于上手。