主界面

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.Random; import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel; /**
* 悲剧 长宽没有控制好 忘了给添加按钮留空间了
* @author Administrator
*
*/
public class MyFrame extends JFrame implements MouseListener { public static final int COL = 4; //图像列数
public static final int ROW = 4; //图像行数
public static final int ONE = 80; //每幅图像的宽度与高度
public static final int STANCE = 30;
private static final int WIDTH = COL*ONE; //界面的宽度
private static final int HEIGHT = ROW*ONE + STANCE; //界面的长度
public static final int number = COL*ROW/2; //图像数目
private JPanel functionJPanel = null; //最上方 用来保存功能键的panel
private JPanel imagesJPanel = null; // 中间用来保存图像的panel
private JPanel chooseJPanel = null; //下面用来选择重新开始和结束的panel
private JButton restartJButton = null; //重新开始的按钮
private JButton closeJButton = null; //关闭按钮
private JLabel functionJLabel = null;
private MyImages myImages ;
private int point1_x = -1; //第一下点击的x坐标
private int point1_y = -1; // 第一下点击的y坐标
private int point2_x = -1; //第二下点击的x坐标
private int point2_y = -1; //第二下点击的y坐标
private static Random random = new Random();
private CanGet canGet;
//用来存放图像的button 暂时不考虑用这种做法
// private JButton[][] myImageJButtons = new JButton[ROW][COL]; //用来保存地图的数组 素组下标表示位置 此位置上的值表示图像编号 0表示无图像
private int[][] myMap = new int[ROW][COL]; public int[][] getMyMap(){
return myMap;
} // 将一对一对的数随机到数组中 (1-8)随机生成地图
private void setMap(){ for(int i=0;i<number;i++){ for(int j=0 ;j<2;j++){
int x = random.nextInt(COL);
int y = random.nextInt(ROW);
while(myMap[x][y]!=0){
x = random.nextInt(COL);
y = random.nextInt(ROW);
}
myMap[x][y] = (i+1)/2+1; //在这里将每个位置上的图片编号设定好
}
} } private void init(){
setMap(); //将地图生成
//读图
myImages = new MyImages(this);
canGet = new CanGet(this);
//初始化JPanel
// functionJPanel = new JPanel();
// imagesJPanel = new JPanel();
// chooseJPanel = new JPanel(); //将JPanel放到适当的位置
// Container container = this.getContentPane();
// container.setLayout(new BorderLayout());
// container.add(imagesJPanel, "Center");
// container.add(functionJPanel, "North");
// container.add(chooseJPanel, "South"); //初始化JPanel上各个组件
// functionJLabel = new JLabel("00000000000");
// functionJPanel.add(functionJLabel);
// restartJButton = new JButton("重新开始");
// closeJButton = new JButton("退出游戏");
// chooseJPanel.add(restartJButton);
// chooseJPanel.add(closeJButton); //初始化frame的位置大小
Toolkit toolkit = Toolkit.getDefaultToolkit();
int width = toolkit.getScreenSize().width;
int height = toolkit.getScreenSize().height;
this.setLocation((width-WIDTH)/2, (height-HEIGHT)/2);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(WIDTH, HEIGHT);
this.addMouseListener(this);
this.setBackground(Color.WHITE);
this.setResizable(false);
this.setVisible(true);
} @Override
public void paint(Graphics g) { BufferedImage backScreen = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_3BYTE_BGR); Graphics g2 = backScreen.getGraphics();
Color c = g2.getColor();
g2.setColor(Color.WHITE);//設置背景顏色
g2.fillRect(0, 0, WIDTH, HEIGHT);
g2.setColor(c);
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++){
if(0 != myMap[i][j]){
// System.out.println(myMap[i][j]);
myImages.drawAnImage(g2, i, j, myMap[i][j]);
}
}
}
c = g2.getColor();
g2.setColor(Color.BLACK);
if(point1_x != -1){
g2.drawRect( point1_y*ONE,point1_x*ONE, ONE, ONE);
}
if(point2_x != -1){
g2.drawRect( point2_y*ONE,point2_x*ONE, ONE, ONE);
}
g2.setColor(c);
g.drawImage(backScreen, 0, 30, null);
} public MyFrame(){
init();
} /**
* @param args
*/
public static void main(String[] args) {
new MyFrame();
} @Override
public void mouseClicked(MouseEvent e) {
int col = e.getX()/ONE;
int row = (e.getY()-STANCE)/ONE; if(-1 == point1_x || -1 == point1_y){
//System.out.println("sssssssssssssssss");
point1_x = row;
point1_y = col;
System.out.println("flag111111111");
}else if (-1 == point2_x || -1 == point2_y) {
point2_x = row;
point2_y = col;
canGet = new CanGet(this);
System.out.println("flag22222222222");
if(myMap[point1_x][point1_y] == myMap[point2_x][point2_y]
&&(point1_x != point2_x || point1_y != point2_y)
&&canGet.isConnect(point1_x,point1_y, point2_x,point2_y)){
//在此处检测是否联通
System.out.println("flag333333333");
//如果联通 则将两个位置的图片消去(变成0)
setMapPointNull(point1_x, point1_y);
setMapPointNull(point2_x, point2_y);
//重置第两个选中的点
resetPoint1();
resetPoint2();
//重画界面
}else{
System.out.println("flag44444444444444");
point1_x = point2_x;
point1_y = point2_y;
resetPoint2();
}
}else{
System.out.println("flag55555555555");
resetPoint1();
resetPoint2();
}
// System.out.println("point1 ("+point1_x + "," +point1_y+")");
// System.out.println("point2 ("+point2_x + "," +point2_y+")");
// System.out.println(row + "," +col);
repaint();
} //将一个点重置为0
private void setMapPointNull(int row,int col){
myMap[row][col] = 0;
} //重置所有的点 生成新的地图
private void resetMapAllPoints(){
setMap();
} //重置两个鼠标选择的点 为未选中状态
private void resetPoint1(){
point1_x = -1;
point1_y = -1;
} private void resetPoint2(){
point2_x = -1;
point2_y = -1;
} @Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub } }

判断连通的类

import java.util.Stack;

public class CanGet {
private Stack<Node> mySteps = new Stack<>();
private Stack<Node> myRecord = new Stack<>();
private int[][] myMap;
private int current_row;
private int current_col;
private int rowNumber;
private int colNumber;
public CanGet(MyFrame myFrame){
this(myFrame.getMyMap());
}
public CanGet(int[][] map){
this.myMap = map;
this.rowNumber = this.myMap.length;
this.colNumber = this.myMap[0].length;
} private void setCurrent(int row ,int col){
current_col = col;
current_row = row;
} public boolean isConnect(int start_row,int start_col,int end_row,int end_col){
boolean flag = false;
setCurrent(start_row, start_col);
keepRecord();
while(!flag){
if(nextIsTarget(end_row, end_col)){
flag = true;
break;
}else {
if(mySteps.isEmpty()){
flag = false;
return flag;
}else if(goLeft() || goUp() || goRigth() || goDown()){
keepRecord();
}else {
Node node = mySteps.pop();
setCurrent(node.getRow(), node.getCol());
} }
}
return flag;
} private void keepRecord(){
Node node = new Node(current_row, current_col);
mySteps.push(node);
myRecord.push(node);
} private boolean goLeft(){
if(current_col-1 >= 0 &&
!myRecord.contains(new Node(current_row, current_col-1))
&& myMap[current_row][current_col-1] == 0){ current_col -= 1;
return true;
}
return false;
}
private boolean goUp(){
if(current_row-1 >= 0
&& !myRecord.contains(new Node(current_row-1, current_col))
&& myMap[current_row-1][current_col] == 0){ current_row -= 1;
return true;
}
return false;
}
private boolean goRigth(){
if(current_col+1 < this.colNumber
&& !myRecord.contains(new Node(current_row, current_col+1))
&& myMap[current_row][current_col+1] == 0){ current_col += 1;
return true;
}
return false;
}
//探测向下
private boolean goDown(){
if(current_row+1 < this.rowNumber
&& !myRecord.contains(new Node(current_row+1, current_col))
&& myMap[current_row+1][current_col] == 0){ current_row += 1;
return true;
}
return false;
} //用来判断当前点的周围是否是目标点
private boolean nextIsTarget(int target_row,int target_col){
int row = current_row;
int col = current_col;
boolean flag = false;
Node[] nodes = getNear(current_row,current_col);
for(int i=0;i<nodes.length;i++){
if(nodes[i] != null
&& (nodes[i].getRow() == target_row && nodes[i].getCol() == target_col)){
flag = true;
break;
}
}
return flag;
} private Node[] getNear(int row,int col){
Node[] nodes = new Node[4]; // 四个方向的临近点
if(row-1 >= 0){
nodes[0] = new Node(row-1, col);
}
if(col-1 >= 0){
nodes[1] = new Node(row, col-1);
}
if(row+1 < this.rowNumber){
nodes[2] = new Node(row+1, col);
}
if(col+1 < this.colNumber){
nodes[3] = new Node(row, col+1);
}
return nodes;
} private boolean isSmoothTo(int row,int col,Dir dir){
boolean isSmooth = false;
boolean flag = false;
int next_row = -1;
int next_col = -1;
switch(dir){
case L:
next_col = col - 1;
next_row = row ;
//当数组下表不越界 标识为真
if(next_col>=0){
flag = true;
}
break;
case U:
next_row = row - 1;
next_col = col;
//当数组下表不越界 标识为真
if(next_row>=0 ){
flag = true;
}
break;
case R:
next_col = col + 1;
next_row = row;
//当数组下表不越界 标识为真
if(next_col < this.colNumber){
flag = true;
}
break;
case D:
next_row = row + 1;
next_col = col;
//当数组下表不越界 标识为真
if(next_row < this.rowNumber){
flag = true;
}
break;
}
//当标识与 地图在这个位置没有障碍物 为0表示没有障碍物 且当前路线没有走过
if(flag && 0 == myMap[next_row][next_col]){
isSmooth = true;
}
return isSmooth;
} private boolean goToNextPoint(Dir dir){
boolean flag = false;
System.out.println("go to next point");
if (isSmoothTo(current_row, current_col, dir)) {
flag = true;
switch (dir) {
case R:
current_col += 1;
break;
case D:
current_row += 1;
break;
case L:
current_col -= 1;
break;
case U:
current_row -= 1;
break;
}
}
return flag;
} private class Node{
private int row;
private int col;
public Node(int row, int col){
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
@Override
public boolean equals(Object o) {
Node node = (Node)o;
return (node.getCol() == this.col && node.getRow() == this.row)? true:false;
} }
}

方向枚举

public enum Dir {
L,U,R,D
}

缓存绘制图像

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; import javax.imageio.ImageIO; public class MyImages {
private static final int IMAGENUM = MyFrame.COL*MyFrame.ROW/2;
private BufferedImage[] images = new BufferedImage[IMAGENUM];
private MyFrame myFrame;
public MyImages(MyFrame myFrame){
this.myFrame = myFrame;
//将八幅图像读进来 每幅图像的编号与其名字相同 是下标加1
for(int i=0;i<IMAGENUM;i++){
try {
images[i] = ImageIO.read(new File((i+1)+".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
//第一个参数是画笔 第二个参数是图像所在行数 第三个参数为列数 第四个参数是图像编号 为 1-8;
public void drawAnImage(Graphics g,int row,int col,int imageNum){
//根据行和列算出图像所在位置 画出图像
// System.out.println("image 编号:"+(imageNum));
g.drawImage(images[imageNum-1] , col*MyFrame.ONE,row*MyFrame.ONE, null);
}
}

放上去几张图片 点击这里下载

连连看java版的更多相关文章

  1. ArcGIS Server 10 Java 版的Rest服务手动配置方法

    Java版的Manager中发布的服务默认只发布了该服务的SOAP接口,而REST接口需要用户在信息服务器,如Tomcat. Apache.WebLogic等中手工配置.由于在Java版的Server ...

  2. PetaPojo —— JAVA版的PetaPoco

    背景 由于工作的一些原因,需要从C#转成JAVA.之前PetaPoco用得真是非常舒服,在学习JAVA的过程中熟悉了一下JAVA的数据组件: MyBatis 非常流行,代码生成也很成熟,性能也很好.但 ...

  3. 【转载】java版打字练习软件

    网上找到一个java版的打字的游戏 import java.applet.Applet; import java.applet.AudioClip; import java.awt.Dimension ...

  4. 微博地址url(id)与mid的相互转换 Java版

    原理: 新浪微博的URL都是如:http://weibo.com/2480531040/z8ElgBLeQ这样三部分. 第一部分(绿色部分)为新浪微博的域名,第二部分(红色部分)为博主Uid,第三部分 ...

  5. JCEF3——谷歌浏览器内核Java版实现(一):使用jawt获取窗体句柄

    前言 最近一段时间研究谷歌浏览器内核.谷歌浏览器内核一直开源,并维护更新,它的开源项目中内核更新速度和Chrome浏览器版本更新进度一样!而且它不同于WebKit(值得一题的是谷歌浏览器已不使用Web ...

  6. Selenium关键字驱动测试框架Demo(Java版)

    Selenium关键字驱动测试框架Demo(Java版)http://www.docin.com/p-803493675.html

  7. 第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容

    第一部分:微信JS-SDK介绍 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统 ...

  8. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  9. 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...

随机推荐

  1. 【转帖】解决远程连接MariaDB(mysql)很慢的方法

    在CentOS7上安装完成MariaDB之后,发现无论命令行还是程序中连接MariaDB的时候都很慢,大约要一二十秒,于是网上搜索了一番,发现下面的文章内容: 在进行 ping和route后发现网络通 ...

  2. Error - SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM

    I find using the following works quite well for SQL min/max dates after many DB related errors: Date ...

  3. QT 窗口拖拽移动实现

    我们知道,要实现窗口移动可以直接鼠标点住窗口的标题栏实现拖拽移动,这是窗口默认的行为,在QT中的事件响应函数为moveEvent. 但是现实中经常需要鼠标点住窗口客户区域实现窗口的拖拽移动,代码实现如 ...

  4. ubuntu 创建swap分区

    通常,Linux系统中swap分区可以通过两种方式指定,分别为:一.在磁盘分区的时候格式化一个swap分区:二.在文件系统中创建一个swap文件作为swap分区.此文主要介绍第二种方式.步骤如下: 1 ...

  5. [IR] Arithmetic Coding

    Statistical methods的除了huffman外的另一种常见压缩方式. Huffman coding的非连续数值特性成为了无法达到香农极限的先天无法弥补的缺陷,但Arithmetic co ...

  6. oracle 学习笔记(2)创建表空间及用户授权

    原文:http://www.cnblogs.com/smartvessel/archive/2009/07/06/1517690.html Oracle安装完后,其中有一个缺省的数据库,除了这个缺省的 ...

  7. Use a load-balancer as a first row of defense against DDOS

    We’ve seen recently more and more DOS and DDOS attacks. Some of them were very big, requiring thousa ...

  8. pythonCharm 破解

    操作步骤和IDEA是一样的 只是jar 包不一样 //激活拷贝-javaagent:E:\PythonCharm\PyCharm Community Edition 2017.3.4\bin\Jetb ...

  9. 使用Anaconda3配置多版本Python虚拟开发环境

    有时候,为了使用比较干净的开发环境,或者为了测试一些版本的扩展库,我们可能需要创建虚拟开发环境,在不同的虚拟开发环境中,只安装需要的扩展库,这样可以最大程度上减少不同扩展库之间的兼容性带来的冲突或其他 ...

  10. Spark RDD 默认分区数量 - repartitions和coalesce异同

    RDD.getNumPartitions()方法可以获得一个RDD分区数量, 1.默认由文件读取的话,本地文件会进行shuffle,hdfs文件默认会按照dfs分片来设定. 2.计算生成后,默认会按照 ...