连连看大家应该都玩过,不多说直接上一个做好的界面截图吧,所有的功能都在上面的,要做的就只是如何去实现它们了。

差不多就是这个样子。先说一下大致的思路吧。首先编写基本的界面:把什么按钮啊,表格啊什么的都画上去。然后就是编写事件处理类,因为操作使用鼠标,所以加上鼠标监听。然后获取点击的坐标,根据坐标得出图片在数组中的位置。接着创建一个类,实现连连看消除的算法。这样就基本上可以开始游戏了。然后实现排行榜按钮和存档按钮的基本功能。最后加上一个线程类,用于处理倒计时。下面的介绍也基于这个顺序。

界面实现:这个其实没什么好说的,把JFrame的知识用上就好了。考虑到图片的闪烁问题,在界面类中重写paint方法,加上双缓冲(双缓冲不懂的,可以自行百度或者看看我写的Java版本2048)。所以就直接贴代码了。

packagecom.cbs.look;public interfaceLookConfig {int x=50;//初始x坐标,原来是10

int y=100;//初始y坐标,原来是50

int space=10;//图片间的间隔

int arc=50;//圆角矩形的弧度

int size=60;//图片的大小

int num=9;//图片类型

}

View Code

1 packagecom.cbs.look;2

3 importjava.awt.Color;4 importjava.awt.Font;5 importjava.awt.Graphics;6 importjava.awt.Graphics2D;7 importjava.awt.Image;8 importjava.awt.RenderingHints;9

10 importjavax.swing.ImageIcon;11 importjavax.swing.JButton;12 importjavax.swing.JFrame;13 importjavax.swing.JLabel;14 importjavax.swing.JOptionPane;15

16 /**

17 * 连连看的主界面类18 *19 *@authorCBS20 *21 */

22 @SuppressWarnings("serial")23 public class GameLook extends JFrame implementsLookConfig {24

25 private int[][] array = new int[8][8];//数组用于保存界面的信息

26

27 JLabel timeJl;//用于显示剩余时间

28

29 public static void main(String[] args) throwsInterruptedException {30 GameLook g = newGameLook();31 g.showUI();32

33 }34

35 /**

36 * 初始化界面37 *38 *@throwsInterruptedException39 */

40 public void showUI() throwsInterruptedException {41 setTitle("连连看");42 setSize(700, 800);43 setDefaultCloseOperation(3);44 setLocationRelativeTo(null);45 setResizable(true);46 setLayout(null);47

48 //添加新游戏按钮49 //ImageIcon start = new ImageIcon("res/start.png");

50 JButton startJB = new JButton("新游戏");51 startJB.setBounds(30, 700, 100, 40);52 //startJB.setBorderPainted(false);//设置边框为空

53 startJB.setFocusable(false);54 //startJB.setContentAreaFilled(false);//设置内容空

55 this.add(startJB);56 //添加排行榜按钮

57 JButton save = new JButton("排行榜");58 save.setFocusable(false);59 save.setBounds(190, 700, 100, 40);60 this.add(save);61

62 //添加存档按钮

63 JButton saveGame = new JButton("存档");64 saveGame.setFocusable(false);65 saveGame.setBounds(320, 700, 100, 40);66 this.add(saveGame);67

68

69 //添加剩余时间

70 JLabel jl = new JLabel("Time:");71 jl.setFont(new Font("", Font.BOLD, 20));72 jl.setBounds(440, 700, 80, 50);73 this.add(jl);74

75 //显示剩余时间

76 timeJl = new JLabel("90");77 timeJl.setFont(new Font("", Font.BOLD, 20));78 timeJl.setBounds(520, 700, 80, 50);79 this.add(timeJl);80

81 setVisible(true);82

83 GameListener gl = newGameListener();84 gl.setFrame(this);85 gl.setTimeJl(timeJl);86 gl.setArray(array);87 saveGame.addActionListener(gl);88 startJB.addActionListener(gl);89 save.addActionListener(gl);90

91 int i=JOptionPane.showConfirmDialog(this, "是否读取上次的存档", "读档",92 JOptionPane.YES_NO_OPTION);93 if(i==1){94 JOptionPane.showMessageDialog(this, "请按新游戏开始游戏吧!");95 }else{96 GameSave2 gs2=newGameSave2();97 CunD c=gs2.opean();98 if(c!=null){99 array=c.getArray();100 gl.setArray(array);101 this.addMouseListener(gl);102 this.repaint();103 TimeOut tt =new TimeOut(timeJl, this, gl);104 gl.setTt(tt);105 tt.setSeconds(c.getTime());106 tt.start();107 }else{108 JOptionPane.showMessageDialog(this, "读取失败!");109 }110 }111

112

113 }114

115 @Override116 public voidpaint(Graphics g) {117 super.paint(g);118 buffPaint(g);119 }120

121 /**

122 * 使用双缓冲技术解决闪屏问题123 *124 *@paramg传入的画笔对象125 */

126 public voidbuffPaint(Graphics g) {127 Image i = createImage(space + (size + space) * array[0].length, space128 + (size + space) *array.length);129 Graphics2D g2d =(Graphics2D) i.getGraphics();130 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,131 RenderingHints.VALUE_ANTIALIAS_ON);132 //绘制背景矩形

133 g2d.setColor(new Color(210, 180, 140));134 g2d.fillRoundRect(0, 0, space + (size + space) * array[0].length, space135 + (size + space) *array.length, arc, arc);136 //绘制背景方格

137 g2d.setColor(new Color(245, 245, 220));138 for (int r = 0; r < array.length; r++) {139 for (int c = 0; c < array[r].length; c++) {140 g2d.fillRect(space + (size + space) * c, space + (size +space)141 *r, size, size);142 }143 }144 //绘制图片

145 g2d.setColor(Color.BLUE);146 g2d.setFont(new Font("宋体", Font.BOLD, 30));147 for (int r = 0; r < array.length; r++) {148 for (int c = 0; c < array[r].length; c++) {149 if (array[r][c] != 0) {150 ImageIcon icon = new ImageIcon("res/" +array[r][c]151 + ".jpg");152 Image image =icon.getImage();153 g2d.drawImage(image, space + (size + space) *c, space154 + (size + space) * r, size, size, null);155 }156 }157 }158 g.drawImage(i, x, y, this);159 }160 }

View Code

事件处理类:鼠标的事件处理主要负责的是记录两次点击的坐标,然后判断是否能够把两个图片消除,如果可以消除图片把对应的数组位置的数置为0,然后重绘画板,如果不行同样重绘画板消除选框及连线。动作的事件处理主要负责实现不同的按钮的功能。

packagecom.cbs.look;importjava.awt.BasicStroke;importjava.awt.Color;importjava.awt.FlowLayout;importjava.awt.Font;importjava.awt.Graphics2D;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjava.util.List;importjava.util.Random;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JOptionPane;importjavax.swing.plaf.FontUIResource;/*** 事件处理类

*@authorCBS*/

public class GameListener extends MouseAdapter implementsLookConfig,

ActionListener {//用于控制坐标的获取

private boolean flag = true;private int r1, c1, r2, c2;//对应数组的下标位置

private int x1, y1, x2, y2;//鼠标点击的坐标

private int array[][];//保存数组

private JFrame frame;//用于获取窗体对象,调用Repaint方法

private Graphics2D g;//画笔对象

JLabel timeJl;//用于显示剩余时间

TimeOut tt ;//倒计时线程类

private int x;//保存画框的顶点x坐标

private int y;//保存画框的顶点y坐标

publicTimeOut getTt() {returntt;

}public voidsetTt(TimeOut tt) {this.tt =tt;

}public voidsetTimeJl(JLabel timeJl) {this.timeJl =timeJl;

}public voidsetFrame(JFrame frame) {this.frame =frame;

g=(Graphics2D) frame.getGraphics();

}public void setArray(int[][] array) {this.array =array;

}

@Overridepublic voidmousePressed(MouseEvent e) {//获取坐标

if(flag) {

x1= e.getX() - 40;

y1= e.getY() - 50;

flag= false;if (y1 / (size + space) - 1 >=array.length)

r1= array.length - 1;else if (y1 / (size + space) - 1 < 0)

r1= 0;elser1= y1 / (size + space) - 1;if (x1 / (size + space) >= array[0].length)

c1= array[0].length - 1;elsec1= x1 / (size +space);

g.setColor(Color.RED);

g.setStroke(new BasicStroke(5));

x= space + space + c1 * (size + space) + 40;

y= size + r1 * (size + space) + 50;

g.drawRect(x, y, size, size);

}else{

x2= e.getX() - 40;

y2= e.getY() - 50;

flag= true;if (y2 / (size + space) - 1 >=array.length)

r2= array.length - 1;else if (y1 / (size + space) - 1 < 0)

r1= 0;elser2= y2 / (size + space) - 1;if (x2 / (size + space) >= array[0].length)

c2= array[0].length - 1;elsec2= x2 / (size +space);

g.setColor(Color.RED);

g.setStroke(new BasicStroke(4));

x= space + space + c2 * (size + space) + 40;

y= size + r2 * (size + space) + 50;

g.drawRect(x, y, size, size);

}

GameUtil gu= new GameUtil(this.frame);if (array[r1][c1] == array[r2][c2] && flag && !(r1 == r2 && c2 ==c1)&& (array[r1][c1] != 0 || array[r2][c2] != 0)) {if(gu.wuZhe(r1, c1, r2, c2, array)) {

array[r1][c1]= 0;

array[r2][c2]= 0;

g.setColor(Color.PINK);

g.drawLine(2 * space + size / 2 + c2 * (size + space) + 40,

size+ size / 2 + r2 * (size + space) + 50, 2 *space+ size / 2 + c1 * (size + space) + 40, size+ size / 2 + r1 * (size + space) + 50);

}else if(gu.yiZhe(r1, c1, r2, c2, array)) {

array[r1][c1]= 0;

array[r2][c2]= 0;

g.setColor(Color.PINK);

g.drawLine(2 * space + size / 2 + gu.getPath().get(0).y* (size + space) + 40, size + size / 2

+ gu.getPath().get(0).x * (size + space) + 50, 2

* space + size / 2 + c1 * (size + space) + 40, size+ size / 2 + r1 * (size + space) + 50);

g.drawLine(2 * space + size / 2 + gu.getPath().get(0).y* (size + space) + 40, size + size / 2

+ gu.getPath().get(0).x * (size + space) + 50, 2

* space + size / 2 + c2 * (size + space) + 40, size+ size / 2 + r2 * (size + space) + 50);

}else if(gu.erZhe(r1, c1, r2, c2, array)) {

array[r1][c1]= 0;

array[r2][c2]= 0;

g.setColor(Color.PINK);

g.drawLine(2 * space + size / 2 + gu.getPath().get(1).y* (size + space) + 40, size + size / 2

+ gu.getPath().get(1).x * (size + space) + 50, 2

* space + size / 2 + c1 * (size + space) + 40, size+ size / 2 + r1 * (size + space) + 50);//path的下标为一的位置要减一,因为数组扩大了

g.drawLine(2 * space + size / 2 + (gu.getPath().get(0).y - 1)* (size + space) + 40, size + size / 2

+ (gu.getPath().get(0).x - 1) * (size + space) + 50, 2

* space + size / 2 + gu.getPath().get(1).y* (size + space) + 40, size + size / 2

+ gu.getPath().get(1).x * (size + space) + 50);

g.drawLine(2 * space + size / 2 + (gu.getPath().get(0).y - 1)* (size + space) + 40, size + size / 2

+ (gu.getPath().get(0).x - 1) * (size + space) + 50, 2

* space + size / 2 + c2 * (size + space) + 40, size+ size / 2 + r2 * (size + space) + 50);

}//实现消除控制重绘的刷新时间

Thread t=newThread();try{

t.sleep(100);

frame.repaint();

}catch(InterruptedException e1) {//TODO Auto-generated catch block

e1.printStackTrace();

}if(isWin(array)) {

tt.setFlag(false);

frame.removeMouseListener(this);

JOptionPane.showMessageDialog(frame,"恭喜你,"

+ "你赢了!!请点击新游戏开始新一局");int i = JOptionPane.showConfirmDialog(frame, "是否记录将你的信息记入排行榜","排行榜", JOptionPane.YES_NO_OPTION);if (i == 0) {

String str= JOptionPane.showInputDialog(frame, "请输入你的名字","排行榜", JOptionPane.YES_NO_OPTION);int time=90-tt.getSeconds();

User u= newUser(str, time);

GameSave gs= newGameSave();

gs.save(u);

}

}

}//未实现消除,重绘去掉线条

if(flag) {

Thread t=newThread();try{

t.sleep(100);

frame.repaint();

}catch(InterruptedException e1) {//TODO Auto-generated catch block

e1.printStackTrace();

}

}

}//按钮动作监听

public voidactionPerformed(ActionEvent e) {

String str=e.getActionCommand();if ("新游戏".equals(str)) {for (int r = 0; r < array.length; r++)for (int c = 0; c < array[r].length; c++)if (array[r][c] != 0) {

array[r][c]= 0;

}if(tt!=null){if(tt.isFlag()){

frame.removeMouseListener(this);

tt.setFlag(false);

}

}

randomData();

frame.repaint();

frame.addMouseListener(this);//启动线程

tt = new TimeOut(timeJl, frame, this);if(!tt.isFlag())

tt.setFlag(false);

tt.start();

}if ("排行榜".equals(str)) {

GameSave gs= newGameSave();

List list =gs.opean();for (int i = 0; i < list.size(); i++) {int flag =i;for (int j = i + 1; j < list.size(); j++) {if (list.get(i).getTime() >list.get(j).getTime())

flag=j;

}if (flag !=i) {

User u1=list.get(i);

User u2=list.get(flag);

list.set(i, u2);

list.set(flag, u1);

}

}

JFrame jf= newJFrame();

jf.setTitle("排行榜");

jf.setDefaultCloseOperation(2);

jf.setSize(300, 500);

FlowLayout fl= newFlowLayout(FlowLayout.LEFT);

jf.setLayout(fl);

jf.setLocationRelativeTo(null);for (int i = 0; i < list.size(); i++) {

JLabel jl= newJLabel(list.get(i).toString());

jl.setFont(new FontUIResource("楷体", Font.BOLD, 20));

jf.add(jl);

}

jf.setVisible(true);

}if("存档".equals(str)){

System.out.println(23333);

GameSave2 gs2=newGameSave2();int time=tt.getSeconds();

CunD c=newCunD(array, time);boolean is=gs2.save(c);if(is)

JOptionPane.showMessageDialog(frame,"存档成功!");elseJOptionPane.showMessageDialog(frame,"存档失败!");

}

}/*** 生成随机数字*/

public voidrandomData() {

Random random= newRandom();intr1, r2, c1, c2;for (int i = 0; i < array.length * array[0].length / 2; i++) {do{

r1=random.nextInt(array.length);

c1=random.nextInt(array[r1].length);

}while (array[r1][c1] != 0);

array[r1][c1]= random.nextInt(num) + 1;do{

r2=random.nextInt(array.length);

c2=random.nextInt(array[r2].length);

}while (array[r2][c2] != 0);

array[r2][c2]=array[r1][c1];

}

}//遍历数组,判断输赢

public boolean isWin(int[][] array) {for (int r = 0; r < array.length; r++)for (int c = 0; c < array[r].length; c++)if (array[r][c] != 0)return false;return true;

}

}

View Code

这里的图片我使用的是直接绘制图片,而不是通过按钮,所以坐标的判断有些麻烦。数组的下标取得是通过鼠标坐标整除方格的边长加间隔,然后由数组下标取得屏幕坐标则相反。初始数据是由randomData方法生成,不同的数字对应不同的图片。

连连看的算法:这里我使用的算法是比较容易理解和实现的分类算法,据说还有一种比较厉害的算法叫广度优先搜索,那个我不会,所以就只能用这种了。先说说连连看的规则吧,就是用不超过两次拐弯的直线能够相连就能够消除。这样分类算法就很好理解了,按照消除要拐弯的次数分为无折相连,一折相连和二折相连。首先是无折相连这个很好理解,要么他们左右相邻或者是上下相邻,要么就是同一行,两个方快中间没有阻隔或者是同一列中间没有阻隔。

就像上面的图,左边是不相邻的,右边是相邻的,这两种都属于无折的相连。然后是一折的相连。一折的相连就是拐一个弯,先看看示意图把:

其实无论是哪种情况,能够实现一折相连的方块都是在矩形的两个对顶角,所以只要判断矩形的另外两个对顶角是否能够实现无折相连就行了。最后是二折相连,同样是先看示意图:

二折的情况看似复杂,其实只要在水平方向上和垂直方向上分别进行遍历,如果是空格就判断这个空格是否能够和另一个格子一折相连就行了。其实整个算法有点像是递归,一折调用无折,二折调用一折。算法的思路大概就是这样。然后就上代码吧:

packagecom.cbs.look;importjava.awt.Point;importjava.util.ArrayList;importjava.util.List;importjavax.swing.JFrame;/*** 核心算法

* 判断两个方块是否联通

*@authorCBS

**/

public class GameUtil implementsLookConfig {//path主要是记录下相连的数组的位置,为了方便实现连线的功能

private List path=new ArrayList();public ListgetPath() {returnpath;

}publicGameUtil(JFrame frame) {

}/*** 无折算法,无折的情况,要么同行,判断列是否连通;要么同列判断行是否连通

*

*@paramr1第一个方块行下标

*@paramc1第一个方块列下标

*@paramr2第二个方块行下标

*@paramc2第二个方块列下标

*@paramarray用于保存数组的信息

*@return如果能够连通返回TRUE,or返回FALSE*/

public boolean wuZhe(int r1, int c1, int r2, int c2, int[][] array) {if (r1 != r2 && c1 !=c2)return false;//如果两点的x坐标相等,则在水平方向上扫描

if (r1 ==r2) {if (c1 == c2 - 1 || c2 == c1 - 1)//列相邻

return true;for (int i = Math.min(c1, c2) + 1; i < Math.max(c2, c1); i++)if (array[r1][i] != 0)return false;

}//如果两点的y坐标相等,则在竖直方向上扫描

else if (c1 ==c2) {if (r1 == r2 - 1 || r2 == r1 - 1)//行相邻

return true;for (int i = Math.min(r1, r2) + 1; i < Math.max(r2, r1); i++)if (array[i][c1] != 0)return false;

}return true;

}/*** 一折算法,无论是哪种情况下,都只需要判断对角的r1,c2和r2,c1和两点是否连通

*

*@paramr1第一个方块行下标

*@paramc1第一个方块列下标

*@paramr2第二个方块行下标

*@paramc2第二个方块列下标

*@paramarray 用于保存数组的信息

*@return如果能够连通返回TRUE,or返回FALSE*/

public boolean yiZhe(int r1, int c1, int r2, int c2, int[][] array) {//如果属于0折的情况,直接返回FALSE

if (r1 == r2 || c1 ==c2)return false;//测试对角点1

if (array[r1][c2] == 0) {boolean test1 =wuZhe(r1, c1, r1, c2, array);boolean test2 = test1 ?wuZhe(r1, c2, r2, c2, array) : test1;if (test1 &&test2){

path.add(newPoint(r1,c2));return true;

}

}//测试对角点2

if (array[r2][c1] == 0) {boolean test1 =wuZhe(r1, c1, r2, c1, array);boolean test2 = test1 ?wuZhe(r2, c1, r2, c2, array) : test1;if (test1 &&test2){

path.add(newPoint(r2,c1));return true;

}

}return false;

}/*** 二折算法

*

*@paramr1第一个方块行下标

*@paramc1第一个方块列下标

*@paramr2第二个方块行下标

*@paramc2第二个方块列下标

*@paramarray用于保存数组的信息

*@return如果能够连通返回TRUE,or返回FALSE*/

public boolean erZhe(int r1, int c1, int r2, int c2, int[][] array) {//在原来数组的基础上扩大一圈,用于判断边界的方格

int[][] newArray = new int[array.length + 2][array[0].length + 2];for (int r = 0; r < array.length; r++) {for (int c = 0; c < array[r].length; c++) {

newArray[r+ 1][c + 1] =array[r][c];

}

}//判断是否二折连接//向下垂直遍历

for (int i = r1 + 2; i < newArray.length; i++) {if (newArray[i][c1+1] == 0) {if(yiZhe(r2+1, c2+1, i, c1+1, newArray)){

path.add(new Point(i-1, c1));return true;

}

}else

break;

}//向上垂直遍历

for (int i = r1 ; i > -1; i--) {if (newArray[i][c1+1] == 0){if(yiZhe(i, c1+1, r2+1, c2+1, newArray)){

path.add(new Point(i-1, c1));return true;

}

}else

break;

}//向右水平遍历

for (int i = c1 + 2; i < newArray[0].length; i++) {if (newArray[r1+1][i] == 0){if( yiZhe(r2+1, c2+1, r1+1, i, newArray)){

path.add(new Point(r1,i-1));return true;

}

}else

break;

}//向左水平遍历

for (int i = c1 ; i > -1; i--) {if (newArray[r1+1][i] == 0) {if(yiZhe(r1+1, i, r2+1, c2+1, newArray)){

path.add(new Point(r1,i-1));return true;

}

}else

break;

}return false;

}

}

View Code

还有一个要说一下就是上面第一张图的那种二折情况,如果这种二折情况处于数组的边界的话,在使用上面的二折算法判断就会因为数组的问题,永远不可能实现相连。解决的方法就是:把数组扩大,在整个的数组外边加上一层,也就是说原来4*4变成6*6。把所有除原来4*4之外的位置的值都设为0,这样就能够遍历到了。不过在判断的时候要注意使用的是新数组的坐标还是旧数组的坐标(把新数组的坐标行下标和列下标都减一就是旧数组的行下标和列下标)。能够消除就意味着你的连连看游戏已经可以玩了,剩下的就是一些优化的问题了。

排行榜和存档功能的实现:这两个功能放一起讲,因为都用到了Java的IO的一些知识。这里主要用到的是Java中的FileOutputStream和FileInputStream这两个类。FileOutputStream这个类是把内存中的数据输出到外部的存储设备,主要的方法就是write(向目标文件一次写入一个字节)和close(关闭输出流);FileInputStream则是把外部的数据输入到内存中供程序使用,主要的方法就是read(从目标文件一次读取一个字节)和close(关闭输入流)。存档的思路就是:把当前的数组情况和时间记录下来(使用一个类来保存这两个信息),保存到一个文件中,下次打开游戏的时候询问用户是否载入进度。排行榜的话是如果玩家获胜,就记录下玩家的姓名和通关用时(同样使用一个类),保存到文件中。下面是代码,把存档和排行榜的相关类都放进去了:

1 packagecom.cbs.look;2

3 /**

4 * 存档5 *6 *@authorCBS7 */

8

9 public classCunD {10 private intarray[][];11 private inttime;12

13 publicCunD() {14 }15

16 public CunD(int[][] array, inttime) {17 this.array =array;18 this.time =time;19 }20

21 public int[][] getArray() {22 returnarray;23 }24

25 public void setArray(int[][] array) {26 this.array =array;27 }28

29 public intgetTime() {30 returntime;31 }32

33 public void setTime(inttime) {34 this.time =time;35 }36

37 }38 packagecom.cbs.look;39

40 importjava.io.FileInputStream;41 importjava.io.FileNotFoundException;42 importjava.io.FileOutputStream;43 importjava.io.IOException;44 importjava.io.InputStream;45 importjava.io.OutputStream;46

47 /**

48 * 用于保存游戏存档的信息49 *50 *@authorCBS51 */

52 public classGameSave2 {53

54 public booleansave(CunD d) {55

56 String path = "src/com/cbs/look/info.txt";57

58 try{59

60 OutputStream os = newFileOutputStream(path);61 os.write(d.getTime());62 for (int r = 0; r < d.getArray().length; r++) {63 for (int c = 0; c < d.getArray()[0].length; c++) {64 os.write(d.getArray()[r][c]);65 }66 }67 os.close();68 return true;69 } catch(FileNotFoundException e) {70 e.printStackTrace();71 } catch(IOException e) {72 e.printStackTrace();73 }74

75 return false;76 }77

78 publicCunD opean() {79 String path = "src/com/cbs/look/info.txt";80 try{81 InputStream is = newFileInputStream(path);82 int time =is.read();83 int array[][]=new int[8][8];84

85 for (int i = 0; i < array.length; i++)86 for (int j = 0; j < array[0].length; j++)87 array[i][j] =is.read();88 CunD c=newCunD(array,time);89 is.close();90 returnc;91

92 } catch(FileNotFoundException e) {93 e.printStackTrace();94 } catch(IOException e) {95 e.printStackTrace();96 }97 return null;98 }99 }100 packagecom.cbs.look;101

102 /**

103 * 记录排行榜的用户信息的类104 *105 *@authorCBS106 *107 */

108 public classUser {109

110 private String name;//用户名

111

112 private int time;//记录用户通过所用时间

113

114 publicUser() {115 }116

117 public User(String name, inttime) {118 this.name =name;119 this.time =time;120 }121

122 publicString getName() {123 returnname;124 }125

126 public voidsetName(String name) {127 this.name =name;128 }129

130 public intgetTime() {131 returntime;132 }133

134 public void setTime(inttime) {135 this.time =time;136 }137

138 @Override139 publicString toString() {140 String str=name+"用时为:"+time;141 returnstr;142 }143

144

145 }146 packagecom.cbs.look;147

148 importjava.io.DataInputStream;149 importjava.io.DataOutputStream;150 importjava.io.FileInputStream;151 importjava.io.FileNotFoundException;152 importjava.io.FileOutputStream;153 importjava.io.IOException;154 importjava.io.InputStream;155 importjava.io.OutputStream;156 importjava.util.ArrayList;157 importjava.util.List;158

159 /**

160 * 用于保存游戏排行榜信息161 *162 *@authorCBS163 */

164 public classGameSave {165

166 public booleansave(User user) {167

168 String path = "src/com/cbs/look/save3.txt";169

170 try{171 List array =opean();172 if(array!=null){173 array.add(user);174 for (int i=0;iarray.get(j).getTime())178 flag=j;179 }180 if(flag!=i){181 User u1=array.get(i);182 User u2=array.get(flag);183 array.set(i, u2);184 array.set(flag, u1);185 }186 }187 }else{188 array=new ArrayList();189 array.add(user);190 }191

192 OutputStream os = newFileOutputStream(path);193 DataOutputStream dos=newDataOutputStream(os);194 //先写入有几条信息

195 os.write(array.size());196 for (int i = 0; i < array.size(); i++) {197 User u =array.get(i);198 dos.writeByte(u.getName().getBytes().length);199 dos.write(u.getName().getBytes());200 dos.writeInt(u.getTime());201 }202 os.close();203 dos.close();204 return true;205 } catch(FileNotFoundException e) {206 e.printStackTrace();207 } catch(IOException e) {208 e.printStackTrace();209 }210

211 return false;212 }213

214 public Listopean() {215 String path = "src/com/cbs/look/save3.txt";216 try{217 InputStream is = newFileInputStream(path);218 DataInputStream dis = newDataInputStream(is);219

220 //读取有几条信息

221 int size=is.read();222 List list=new ArrayList();223

224 if(size!=-1){225 for(int i=0;i

238 } catch(FileNotFoundException e) {239 e.printStackTrace();240 } catch(IOException e) {241 e.printStackTrace();242 }243 return null;244 }245 }

View Code

倒计时的实现:倒计时其实很简单使用一个线程就好(如果线程不了解请自行百度或者学习,不用很了解,知道就行,只是为了做个倒计时罢了),每次线程休眠一秒就让时间减一,然后把时间在窗体中输出就行了。也没什么可说的,上代码咯:

packagecom.cbs.look;/*** 线程类,控制时间*/

importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JOptionPane;public class TimeOut extendsThread {private int seconds=90;//游戏时间

private JFrame frame;//主窗体对象

private JLabel jl;//倒计时标签

private boolean flag = true;//控制线程结束

private GameListener gl;//事件处理类//在别的类中控制线程的关闭

public void setFlag(booleanflag) {this.flag =flag;

}public booleanisFlag() {returnflag;

}public intgetSeconds() {returnseconds;

}public void setSeconds(intseconds) {this.seconds =seconds;

}publicTimeOut(JLabel jl, JFrame frame, GameListener gl) {this.jl =jl;this.frame =frame;this.gl =gl;

}

@Overridepublic voidrun() {//seconds = 90;

jl.setText(seconds + "");while (seconds-- > 0 &&flag) {

jl.setText(seconds+ "");if (seconds == 0) {

JOptionPane.showMessageDialog(frame,"不好意思,时间用光了,请开始新游戏");

frame.removeMouseListener(gl);

}try{

Thread.sleep(1000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

View Code

这样所有的东西也就都讲完了,剩下的就是如何把它们组织在一起形成你的东西了。

java连连看代码_Java版连连看相关推荐

  1. java连连看代码_java实现连连看游戏

    本文实例为大家分享了java实现连连看游戏的具体代码,供大家参考,具体内容如下 代码会实现共享的,这个是截图 代码: package com.lr.bean; import java.util.Sca ...

  2. java玫瑰花代码_Java版给爱人表白的玫瑰花程序代码

    1 书写表白语句的frame(渐入功能) package com.wanju.blessing; import java.awt.Color; import java.awt.Container; i ...

  3. java 定时器代码_Java定时器代码的编写

    Java定时器代码的编写 在某些时候, 我们需要实现这样的`功能,某一程序隔一段时间执行一次,而这一事情由系统本身来完成,并不是人为的触发,我们一般可称此为定时器任务.其实到Java中,实现起来是非常 ...

  4. java 编写代码_Java 7:如何编写非常快速的Java代码

    java 编写代码 当我第一次写此博客时,我的目的是向您介绍ThreadLocalRandom类,它是Java 7中新增的用于生成随机数的类. 我在一系列微基准测试中分析了ThreadLocalRan ...

  5. java游戏代码_Java与Kotlin系列文章之性能问题详解

    作者丨Jakub Anioła 译者丨姜雨生 策划丨田晓旭 随着对 Kotlin 越来越深入的了解,我发现市面上关于 Kotlin 方面,比较深入的资料几乎是 0,所以我决定,将 Kotlin 各个方 ...

  6. java四则运算代码_Java实现简单四则运算

    GitHub 项目地址 PSP PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 10 10 · Estima ...

  7. java 文件下载代码_java文件下载代码实例(单文件下载和多文件打包下载)

    这篇文章主要介绍了java文件下载代码实例(单文件下载和多文件打包下载),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最近项目有需要写文件下载相关 ...

  8. java简易版连连看_Java版连连看小游戏

    2.[代码][Java]代码 package com; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graph ...

  9. java微信机器人_Java版微信机器人代码

    Java版微信机器人代码 (2014-07-31 09:47:58) 标签: 软件测试 java 上海泽众软件 package com.eiyoung.wechat.web.controller; i ...

  10. java 云架构_java版Spring Cloud云架构代码结构构建

    本篇我们根据架构图进行代码的构建.根据微服务化设计思想,结合spring cloud一些优秀的项目,如服务发现.治理.配置化管理.路由负载.安全控制等优秀解决方案,使用Maven技术将框架进行模块化. ...

最新文章

  1. linux 下 select 函数的用法
  2. 【12】 全国外电音DJ 3000首 32G
  3. 将数组中的值按逆序重新存放
  4. Spring+jpaNo transactional EntityManager available
  5. Java 多线程(一)
  6. makefile工作笔记0003---Makefile的ifeq逻辑或,逻辑与的变通实现
  7. 用GitHub Copilot 生成的项目中,40%会引入漏洞
  8. sublime安装markdown
  9. ai/ml_本月有关AI / ML的令人印象深刻的中等文章
  10. JAVA中整型常量的长度_以下的 能正确表示Java语言中的一个整型常量。_学小易找答案...
  11. linux怎么重启samba服务器,Linux系统怎么重启Samba服务
  12. OverflowError: Python int too large to convert to C long
  13. Potplayer svp 播放60帧视频
  14. iTextSharp
  15. Ubuntu16.04安装NVIDIA Titan Xp显卡驱动
  16. ArcGIS教程:按掩膜提取 (空间分析)
  17. Sencha学习笔记4: Creating your First App - 官方创建您的第一个Sencha Touch应用指导
  18. 链接:https://pan.baidu.com/s/1joRvLQ7nbti0Wp4t2CkX5w 提取码:ZMTD
  19. Java面试题汇总大杂汇
  20. apicloud studio 怎么开启自动wifi同步?

热门文章

  1. 2017计算机夏令营汇总
  2. Metasploit [基础]
  3. elasticsearch-head离线安装
  4. Juniper SRX340防火墙配置
  5. 163邮箱登陆写信自动化脚本
  6. php 生成pdf 中文,用PHP创建PDF中文文档
  7. python黑魔法指南_python黑魔法
  8. 关于@Result注解的说明
  9. 企业必须面对云计算时代
  10. 库克开怼谷歌和Facebook:自己搞的烂摊子,要会自己收拾