分享一个动漫拼图小游戏项目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
利用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. 运行结果展示: