复制代码
public class GameJFrame extends JFrame implements KeyListener {
//创建一个二维数组
int[][] data = new int[4][4];
//记录空白方块在二维数组中的位置
int x=0;
int y=0;
//把地址路径改为变量
String path="..\\Day03\\out\\image\\animal\\";
//定义变量用来统计步数
int step=0;
//JFrame 界面,窗体
//跟游戏相关的都写在这个界面
public GameJFrame() {
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化数据(打乱)
initdata();
//初始化图片(根据打乱之后的数据来加载图片)
initImage();
//这里是开启和关闭图形化界面的
this.setVisible(true);
}
//定义一个二维数组,存储正确的数据
int[][] win={
{1,2,3,4},
{6,7,8,9},
{11,12,13,10},
{14,15,0,5}
};
//初始化数据(打乱)
private void initdata() {
//需求:
//把一个一维数组的数据:0~15打乱顺序
//然后再按照4个一组的方式添加到二维数组当中
//定义一个一维数组
int[] tempArr = {0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
//2.打乱数组中数据的顺序
//遍历数组.得到每一个元素,拿着每一个元素跟随机索引上的数据进行交换
Random r = new Random();
for (int i = 0; i < tempArr.length; i++) {
//获取到随机索引
int index = r.nextInt(tempArr.length);
//拿着遍历到的每一个数据,跟随机索引上的数据进行交换
int temp = tempArr[i];
tempArr[i] = tempArr[index];
tempArr[index] = temp;
}
//遍历数组
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] == 0){
x=i/4;
y=i%4;
}else{
data[i/4][y%4]=tempArr[i];
}
}
//给二维数组添加数据
//遍历二维数组,给里面每一个数据赋值
int index = 0;
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[0].length; j++) {
data[i][j] = tempArr[index];
index++;
}
}
}
//初始化图片
private void initImage() {
//清空原本已经出现的图片
this.getContentPane().removeAll();
if (victory()) {
//显示的胜利的图标
JLabel winlabel = new JLabel(new ImageIcon("C:\\Users\\Administrator\\IdeaProjects\\Day03\\out\\image\\animal1\\victory.png"));
winlabel.setBounds(203,253,250,200);
this.getContentPane().add(winlabel);
}
JLabel stepCount=new JLabel("步数:"+step);
stepCount.setBounds(50,30,100,20);
this.getContentPane().add(stepCount);
// 细节:先加载的图片在上边,后加载的图片在下边
for (int i = 0; i < 4; i++) {
for (int j= 0; j < 4; j++) {
int num=data[i][j];
//创建一个JLable的对象(管理容器)
JLabel label=new JLabel(new ImageIcon(path+num+".png"));
//指定图片的位置
label.setBounds(50*j+200,50*i+200 ,50,50);
//给图片添加边框
//0:表示让图片凸起来
//1:表示让图片凹下去
label.setBorder(new BevelBorder(BevelBorder.LOWERED));
//把管理容器放到界面当中
this.getContentPane().add(label);
}
}
//添加背景图片
JLabel background = new JLabel(new ImageIcon("..\\Day03\\out\\image\\animal1\\background.png"));
background.setBounds(40, 40 , 508,560);
//把背景图片添加到界面当中
this.getContentPane().add(background);
//刷新一下界面
this.getContentPane().repaint();
}
//初始化菜单
private void initJMenuBar() {
//初始化菜单
//创建整个菜单对象
JMenuBar menuBar = new JMenuBar();
//创建菜单上面的俩个选项的对象 (功能 关于我们)
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//创建选项下面的条目对象
JMenuItem replayItem= new JMenuItem("重新游戏");
JMenuItem reloginItem= new JMenuItem("重新登陆");
JMenuItem closeItem= new JMenuItem("关闭游戏");
JMenuItem accoutItem= new JMenuItem("公众号");
//将每一个选项的条目添加到选项当中
functionJMenu.add(replayItem);
functionJMenu.add(reloginItem);
functionJMenu.add(closeItem);
//然后再把选项添加到菜单里面
menuBar.add(functionJMenu);
aboutJMenu.add(accoutItem);
menuBar.add(aboutJMenu);
//给整个界面去设置菜单
this.setJMenuBar(menuBar);
}
// 初始化界面
private void initJFrame() {
//设置界面的长和宽
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置游戏的关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//取消默认的居中方式
this.setLayout(null);
//给整个界面添加键盘监听事件
this.addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
//按下不松时候,可以调用这个方法
public void keyPressed(KeyEvent e) {
int code=e.getKeyCode();
if(code==65){
//把界面中所有的图片删除
this.getContentPane().removeAll();
//加载第一张完整的图片
JLabel all=new JLabel(new ImageIcon(path+"all.png"));
all.setBounds(100,100,400,400);
this.getContentPane().add(all);
//加载背景图片
JLabel background = new JLabel(new ImageIcon("..\\Day03\\out\\image\\animal1\\background.png"));
background.setBounds(40, 40 , 508,560);
//把背景图片添加到界面当中
this.getContentPane().add(background);
this.getContentPane().repaint();
}
}
@Override
//松开按键的时候,可以调用这个方法
public void keyReleased(KeyEvent e) {
if (victory()) {
return;
}
//对上下左右进行判断
//左:37,上:38,右:39,下:40
int code=e.getKeyCode();
if(code==37){
if(y==3){
//表示空白方块已经在最下方了,他的下面没有图片能移动了
return;
}
System.out.println("向左移动");
data[x][y]=data[x][y+1];
data[x][y+1]=0;
y++;
//每移动一次,计数器就自增一次
step++;
initImage();
}else if(code==38){
System.out.println("向上移动");
if (x==3){
//表示空白方块已经在最下方了,他的下面没有图片能移动了
return;
}
//逻辑:把空白方块下方的的数字向上移动
//x,y表示空白方块
//x+1,y表示空白方块下方的数字
//把空白下方的数字赋值给空白方块
data[x][y]=data[x+1][y];
data[x+1][y]=0;
x++;
//每移动一次,计数器就自增一次
step++;
//调用方法
initImage();
}else if(code==39){
System.out.println("向右移动");
if(y==0){
//表示空白方块已经在最下方了,他的下面没有图片能移动了
return;
}
data[x][y]=data[x][y-1];
data[x][y-1]=0;
y--;
//每移动一次,计数器就自增一次
step++;
initImage();
}else if(code==40){
System.out.println("向下移动");
if(x==0){
//表示空白方块已经在最下方了,他的下面没有图片能移动了
return;
}
data[x][y]=data[x-1][y];
data[x-1 ][y]=0;
x--;
//每移动一次,计数器就自增一次
step++;
initImage();
} else if (code==65) {
initImage();
} else if (code==87) {
data=new int[][]{
{1,2,3,4},
{6,7,8,9},
{11,12,13,10},
{14,15,0,5}
};
initImage();
}
}
//判断data里面的数据看是否跟win数据相同
//如果相同就返回true,不相同就返回false
public boolean victory(){
for (int i = 0; i < data.length; i++) {
//i表示二维数组data里面的索引
//data[i]:依次表示每一个一维数组
for (int j = 0; j < data[i].length; j++) {
if(data[i][j]!=win[i][j]){
//只要有一个数据不一样,就返回false
return false;
}
}
}
//循环结束表示数组遍历比较完毕,全部一样返回true
return true;
}
}