【分享一个动漫拼图项目】

分享一个动漫拼图小游戏项目

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

利用Java中的JFrame等方法完成一个简单拼图游戏的实现


提示:以下是本篇文章正文内容,下面案例可供参考

一、此次将主要使用JFrame来完成此项目,JFrame是什么?

JFrame是指一个计算机语言-java的GUI程序的基本思路是以JFrame为基础,它是屏幕上window的对象,能够最大化、最小化、关闭。

二、使用步骤

1.项目代码

代码如下(示例):

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

/**
 * @Description @Author:ZhangShuai @CreateTime:2022/7/1 15:17
 */
// 动漫拼图游戏
//   
public class PictureFrame extends JFrame {
  // 定义一个二维数组,用来存储图片的编号,其中0号是用来挪动的位置,当前15张图片位置正确后,最后一张会自动显示出来
  //  使用private修饰,可以做到paintFrame()方法体内使用的datas局部变量数组受到保护,外部使用的是成员变量不受这个影响
  private int[][] datas = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 0}};
  // 定义一个移动成功时的数组
  private int[][] winDatas = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 0}};
  // 定义了成员变脸x0,y0用来表示空白图片对应的位置
  private int x0;
  private int y0;
  //  定义按钮为成员变量
  private JButton shang;
  private JButton xia;
  private JButton zuo;
  private JButton you;
  private JButton qiuzhu;
  private JButton chongzhi;
  // 为了实现重绘,把组件面板也定义为成员变量
  private JPanel imagePanel;

  public PictureFrame() {
    // 构造窗体
    initFrame();
    // 打乱图片,此步骤要放在打印方法之前
    randomData();
    // 打印窗体上组件
    paintFrame();
    // 给按钮添加事件
    addButtonEvent();
    // 实现窗体可见
    this.setVisible(true);
  }

  //  移动的图形重新绘制
  public void rePaintFrame() {
    // 移除组件面板上所有的内容
    imagePanel.removeAll();
    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].length; j++) {
        // 加载面板上的16张图片资源
        JLabel imageLabel =
            new JLabel(
                new ImageIcon(
                    "E:\\Program Files\\GameMadeByMyself\\images\\" + datas[i][j] + ".png"));
        imageLabel.setBounds(90 * j, 90 * i, 90, 90);
        imagePanel.add(imageLabel);
      }
    }
    //    把面板加载到窗体上
    // 提示:要先把组建创建好之后,最后创建背景图
    this.add(imagePanel);

    // 重绘所有的
    imagePanel.repaint();
  }
  // 判断是否移动成功,移动成功后自动生成16张图片规正后的样子,并且让移动按钮失效的方法
  //    在每个按钮点击后都要判断一下
  public boolean ifSuccess() {
    //      遍历二维数组,如果两个数组中对应的元素完全相同,就代表移动成功了,返回一个boolean值
    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].length; j++) {
        if (datas[i][j] != winDatas[i][j]) {
          return false;
        }
      }
    }
    // 如果两个循环不被中断,则代表两个数组中的元素都完全相同
    return true;
  }

  public void addButtonEvent() {
    //    使用addActionListener()方法给按钮添加事件
    shang.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            //            System.out.println("上");
            //              边界处理(当向上移动时,如果x0==3,空白图片已经到最底下了,不能再进行位置交换)
            if (x0 == 3) {
              return;
            }

            //              图片编号对应的元素交换
            datas[x0][y0] = datas[x0 + 1][y0];
            datas[x0 + 1][y0] = 0;
            //            交换成功后,x0加1
            x0 = x0 + 1;

            // 判断移动是否成功
            if (ifSuccess()) {
              success();
            }

            //            调用重绘的方法
            rePaintFrame();
          }
        });

    xia.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {

            //              System.out.println("下");
            if (x0 == 0) {
              return;
            }
            datas[x0][y0] = datas[x0 - 1][y0];
            datas[x0 - 1][y0] = 0;
            x0 = x0 - 1;

            // 判断移动是否成功
            if (ifSuccess()) {
              success();
            }

            rePaintFrame();
          }
        });

    zuo.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            //            System.out.println("左");
            if (y0 == 3) {
              return;
            }

            datas[x0][y0] = datas[x0][y0 + 1];
            datas[x0][y0 + 1] = 0;
            y0 = y0 + 1;

            // 判断移动是否成功
            if (ifSuccess()) {
              success();
            }
            rePaintFrame();
          }
        });

    you.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            //            System.out.println("右");
            if (y0 == 0) {
              return;
            }
            datas[x0][y0] = datas[x0][y0 - 1];
            datas[x0][y0 - 1] = 0;
            y0 = y0 - 1;

            // 判断移动是否成功
            if (ifSuccess()) {
              success();
            }

            rePaintFrame();
          }
        });

    qiuzhu.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {

            //              System.out.println("求助");
            // 调用success()方法实现图片归正
            success();
            rePaintFrame();
          }
        });

    chongzhi.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {

//            System.out.println("重置");
            //实现按钮可用
            shang.setEnabled(true);
            xia.setEnabled(true);
            zuo.setEnabled(true);
            you.setEnabled(true);

            //实现图片重新打乱

            datas=new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 0}};
            randomData();
            rePaintFrame();

          }
        });
  }

  // 求助功能实现成功的方法,要求:1、实现图片归正 2、移动按钮禁止使用
  public void success() {
    /*给成员数组datas赋值,然后调用repaintFrame()方法可以实现图片的归正,要是重新创建一个数组,在
    调用repaintFrame()方法时不会起作用*/
    datas = new int[][] {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
    //     调用setEnabled()方法,移动按钮禁止使用
    shang.setEnabled(false);
    xia.setEnabled(false);
    zuo.setEnabled(false);
    you.setEnabled(false);
  }

  public void randomData() {
    Random random = new Random();
    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].length; j++) {
        int x = random.nextInt(datas.length);
        int y = random.nextInt(datas[i].length);
        int temp = datas[x][y];
        datas[x][y] = datas[i][j];
        datas[i][j] = temp;
      }
    }
    // 采用二维数组遍历的方法找到0号图片对应的x0,y0
    // 给最外层循环命名,使用break直接跳出最外层循环
    wc:
    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].length; j++) {
        if (datas[i][j] == 0) {
          x0 = i;
          y0 = j;
          System.out.println(x0 + "," + y0);
          break wc;
        }
      }
    }
  }

  public void initFrame() {
    this.setLayout(null);
    this.setTitle("动漫拼图");
    this.setSize(960, 565);
    this.setDefaultCloseOperation(3);
    this.setAlwaysOnTop(true);
    this.setLocationRelativeTo(null);
  }

  public void paintFrame() {
    //        绘制标题图片
    JLabel title = new JLabel(new ImageIcon("E:\\Program Files\\Anime Jigsaw\\images\\title.png"));
    title.setBounds(354, 27, 232, 57);
    this.add(title);

    //        展示面板上的16张图片
    //    int[][] datas = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

    //        创建面板
    imagePanel = new JPanel();
    imagePanel.setBounds(150, 114, 360, 360);
    imagePanel.setBackground(Color.yellow);
    imagePanel.setLayout(null);

    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].length; j++) {
        // 加载面板上的16张图片资源
        JLabel imageLabel =
            new JLabel(
                new ImageIcon(
                    "E:\\Program Files\\GameMadeByMyself\\images\\" + datas[i][j] + ".png"));
        imageLabel.setBounds(90 * j, 90 * i, 90, 90);
        imagePanel.add(imageLabel);
      }
    }
    //    把面板加载到窗体上
    // 提示:要先把组建创建好之后,最后创建背景图
    this.add(imagePanel);

    // 参照图的绘制
    JLabel canzhaotu =
        new JLabel(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\canzhaotu.png"));
    canzhaotu.setBounds(574, 114, 122, 121);
    this.add(canzhaotu);

    // 上按钮
    shang = new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\shang.png"));
    shang.setBounds(732, 265, 57, 57);
    this.add(shang);

    // 下按钮
    xia = new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\xia.png"));
    xia.setBounds(732, 347, 57, 57);
    this.add(xia);

    // 左按钮
    zuo = new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\zuo.png"));
    zuo.setBounds(650, 347, 57, 57);
    this.add(zuo);

    // 右按钮
    you = new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\you.png"));
    you.setBounds(813, 347, 57, 57);
    this.add(you);

    // 求助按钮
    qiuzhu = new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\qiuzhu.png"));
    qiuzhu.setBounds(626, 444, 108, 45);
    this.add(qiuzhu);

    // 重置按钮
    chongzhi =
        new JButton(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\chongzhi.png"));
    chongzhi.setBounds(786, 444, 108, 45);
    this.add(chongzhi);

    // 背景图片的绘制
    //    提示:最后再创建背景图,不然容易遮盖住之前写的窗体组件
    JLabel background =
        new JLabel(new ImageIcon("E:\\Program Files\\GameMadeByMyself\\images\\background.png"));
    background.setBounds(0, 0, 960, 530);
    this.add(background);
  }
}

2.测试类

代码如下(示例):


/**
 * @Description
 * @Author:ZhangShuai
 * @CreateTime:2022/7/1 15:24
 **/
public class App {
  public static void main(String[] args) {
    //


    PictureFrame pictureFrame=new PictureFrame();
}
}

3.游戏玩法:

玩家在测试类运行之后会弹出一个JFrame窗体,其中有上下左右按钮,玩家可以通过按钮来移动图片的位置;有帮助按钮,可以一键完成拼图,但是进行此操作后移动按钮将不再提供移动功能;还有重置按钮,玩家可以通过此按钮将图片重新打乱,移动按钮将恢复使用功能。

4.提示:

在玩家把15张图片按照参照图对应的位置放置好后,第16张图片将自动补齐。

5.相关图片自取哦,当然也可以自己选取图片来设置拼图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6. 运行结果展示:

这是随机打乱的图片

点击求助按钮可以一键归正图片
点击重置按钮就能得到随机打乱的一张图啦

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来个82年的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值