最近用Java.swing做了一个初级的连连看,其实在没动手之前觉得很难,因为学习了这段时间,以前没有自己动手做过一个完整的东西出来,但是现在写着的时候却发现都是学过的东西,只是平时缺乏思路去把它们合理的整合在一起。以下是整个完整的发开思路和过程。
*(本文代码皆为截取代码,有一定的不完整性)
在Java.swing中开发连连看,主要在于实现以下几个功能。
1.创建一个界面放置连连看的所有图片。
在这个过程中要注意的几点是:
a、为了以后方便计算连连看的图片摆放的位置最好用一个二维数组表示。
b、连连看里面的所有图片都要保证能够消除,即连连看的图片要成对出现。
public static final int X0=30;//起始位置 public static final int Y0=30; public static final int ROWS=8;//连连看的行和列 public static final int LINES=14; public static final int SIZE=30;//连连看图片的宽度(正方形) public static ImageIcon[][] ICON=new ImageIcon[ROWS][LINES];//放置图片的数组。 public static void initPicdata(){ ArrayList<ImageIcon> iconlist=new ArrayList<ImageIcon>(); //先将图片成对的装入这个集合。 Random rd=new Random();//获取随机数 for(int i=0;i<ROWS*LINES/2;i++){ int num=rd.nextInt(3); String url="imgs/"+num+".gif"; ImageIcon img=new ImageIcon(url); iconlist.add(img); iconlist.add(img);//同一张图片加载两次,保证出现次数为偶数。 } for(int i=0;i<ROWS;i++){ for(int j=0;j<LINES;j++){ int num=rd.nextInt(iconlist.size()); //把iconlist中的图片一张张随机加载到ICON中去。 ICON[i][j]=iconlist.remove(num); } } } @Override//重写paint方法,把图片加载到面板中画出来。 public void paint(Graphics g) { super.paint(g); for(int i=0;i<ROWS;i++){ for(int j=0;j<LINES;j++){ if(ICON[i][j]!=null){ ImageIcon img=ICON[i][j]; g.drawImage(img.getImage(), X0+SIZE*j, Y0+SIZE*i,SIZE,SIZE,null); } } } }
2.当点击两个图片的时候,判断是否可以消除。
这里的设定是点击第一次和第二次能消除,第三次和第四次消除,但是点击的第二次和第三次不消除。判断两张图片能消除要分为以下三种情况。
a、两张图片在同一行或者同一列。满足条件:两张图片连通而且即中间没有其它图片。
b、两张图片通过一个转折点连接。满足条件:这个转折点连通这两张图片。
c、两张图片通过两个转折点连接。满足条件:两个转折点之间能连通,而且两个转折点分别和两张图片能连通。
<第二部分代码和第三部分代码在一起。>
3.两张可以消除的图片之间中一条线连接起来。
这基本上就是给玩家一个视觉效果,提示两个被消掉的图片。
a、建立一个集合,在判断的时候把点添加进去,当判断能消除的时候,用线画出两连通点之间的提示线。
b、在执行下一次判断之前把集合中的点全部清空。
public static ArrayList<Point> pplist=new ArrayList<Point>();//提示线的保存点。 @Override//在加载的图片面板中添加一个鼠标监听器,判断是否消除。 public void mousePressed(MouseEvent e) { JPanel panel=(JPanel)e.getSource(); int x=e.getX(); int y=e.getY(); if(comm==0){ comm++; icon1=init(x,y); j1=(x-X0)/SIZE; i1=(y-Y0)/SIZE; }else{ pplist.clear(); comm--; icon2=init(x,y); j2=(x-X0)/SIZE; i2=(y-Y0)/SIZE; if(icon1!=null&&icon2!=null&&(i1!=i2||j1!=j2) &&icon1.toString().equals(icon2.toString())){ if(SuanFaDemo.checkRow(i1, i2, j1, j2)|| SuanFaDemo.checkCol(i1, i2, j1, j2)|| SuanFaDemo.twoPoint(i1, i2, j1, j2)|| SuanFaDemo.threePointH(i1, i2, j1, j2)){ for(int i=0;i<pplist.size();i+=2){ Point p1=pplist.get(i); Point p2=pplist.get(i+1); int p1X=X0+p1.y*SIZE+SIZE/2; int p1Y=Y0+p1.x*SIZE+SIZE/2; int p2X=X0+p2.y*SIZE+SIZE/2; int p2Y=Y0+p2.x*SIZE+SIZE/2; g.setColor(Color.red); g.drawLine(p1X, p1Y, p2X, p2Y); } try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } ICON[i1][j1]=null; ICON[i2][j2]=null; panel.repaint(); } } } } //这是算法部分 //判断同行的两张图片是否能消除 public static boolean checkRow(int x1,int x2,int y1,int y2){ if(x1==x2){ int min=Math.min(y1, y2); int max=Math.max(y1, y2); for(int i=min+1;i<max;i++){ if(ICON[x1][i]!=null){ return false; } } pplist.add(new Point(x1, y1)); pplist.add(new Point(x2, y2)); return true; } return false; } public static boolean checkCol(int x1,int x2,int y1,int y2){ if(y1==y2){ int min=Math.min(x1, x2); int max=Math.max(x1, x2); for(int i=min+1;i<max;i++){ if(ICON[i][y1]!=null){ return false; } } pplist.add(new Point(x1, y1)); pplist.add(new Point(x2, y2)); return true; } return false; } public static boolean twoPoint(int x1,int x2,int y1,int y2){ if(ICON[x1][y2]==null){ if(checkRow(x1,x1,y1,y2)&&checkCol(x2,x1,y2,y2)){ return true; } } if(ICON[x2][y1]==null){ if(checkCol(x1,x2,y1,y1)&&checkRow(x2,x2,y2,y1)){ return true; } } pplist.clear(); return false; } public static boolean threePointH(int x1,int x2,int y1,int y2){ for(int i=0;i<LINES;i++){ if(ICON[x1][i]==null&&ICON[x2][i]==null){ if(checkRow(x1,x1,i,y1)&&checkRow(x2,x2,i,y2)&& checkCol(x1,x2,i,i)){ return true; } } } for(int j=0;j<ROWS;j++){ if(ICON[j][y1]==null&&ICON[j][y2]==null){ if(checkRow(j,j,y1,y2)&&checkCol(j,x1,y1,y1)&& checkCol(j,x2,y2,y2)){ return true; } } } pplist.clear(); return false; } }
4、至于其它关卡设置、开始游戏、结束游戏的button和功能还没有实现。
除了这种算法思路消除连连看之外,还有在网上搜索到一种更精简的思路:
即点击的第一张图片的时候:
1、保存所有这张图片它上下左右连通点,加入到S集合中。
2、遍历S集合中所有的连通点,保存所有这张图片它上下左右连通点,加入到T集合中。
3、遍历T集合中所有的连通点,保存所有这张图片它上下左右连通点,加入到S集合中,并且将T集合中的所有点添加到S集合中。
4、点击第二张图片的时候,判断此时这张图片的位置在不在S集合中,如果在就消除。
<这个方法自己还没有实现,不过觉得思路真的一级棒。>