简化版拼图小游戏

前言:简化版的拼图小游戏,无需注册和登录。内含作弊码(。_ 。)
欢迎clone我的GitHub仓库!
https://github.com/Antarctica000/puzzle-game-Java.git

业务逻辑分析:

功能模块:

  • 拼图块上下移动功能
  • 步数统计功能
  • 更换图片功能
  • 重新游戏功能
  • 关闭游戏功能
  • 游戏成功判定
  • 作弊码W设置

关于作者模块:

  • 作者微信弹窗

游戏展示:

拼图游戏1 拼图游戏2 拼图游戏3 拼图游戏4 拼图游戏项目结构

代码:

1
2
3
4
5
6
7
8
//App测试类
public class App {
//程序的启动入口
public static void main(String[] args) {
//如果想要开启一个界面,创建对象即可
new GameJFrame();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
package UI;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

//游戏的主界面,包括和游戏相关的所有逻辑
public class GameJFrame extends JFrame implements KeyListener, ActionListener {
//创建选项的条目对象
JMenuItem people = new JMenuItem("人物");
JMenuItem animal = new JMenuItem("动物");
JMenuItem replayItem = new JMenuItem("重新游戏");
/*JMenuItem reLoginItem = new JMenuItem("重新登录");*/
JMenuItem closeItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("作者微信");
//定义一个变量用来展示当前图片的路径
String path = "image\\rtwo\\rtwo-";
//很多图片路径的数组
String[] peoplePath = {
"image\\rtwo\\rtwo-",
"image\\rone\\rone-",
"image\\Eron\\Eron-",
"image\\levi\\levi-"
};
String[] animalPath = {
"image\\cat\\cat-",
"image\\cutty\\cutty-"
};
//创建二维数组记录顺序
int[][] data = new int[3][3];
//记录空白方块在二维数组中的位置
int x = 0;
int y = 0;
//定义一个存储正确数据的二维数组(判断胜利)
int[][] win = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 0}
};
//定义统计步数的变量
int step = 0;

public GameJFrame() {
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化数据(打乱顺序)
initData();
//初始化图片(打乱之后)
initImage();
//让界面显示
this.setVisible(true);
}

private void initJFrame() {
//设置界面的宽高
this.setSize(603, 680);
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置关闭模式
this.setDefaultCloseOperation(3);
//取消默认的居中模式
this.setLayout(null);
//给整个界面添加键盘监听事件
this.addKeyListener(this);
}

private void initJMenuBar() {
//创建整个菜单对象
JMenuBar jMenuBar = new JMenuBar();
//创建菜单上面两个选项
JMenu fonctionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于作者");
//创建更换图片
JMenu changeImage = new JMenu("更换图片");
//将每个选项下的条目添加到选项中
fonctionJMenu.add(changeImage);
changeImage.add(people);
changeImage.add(animal);
fonctionJMenu.add(replayItem);
/*fonctionJMenu.add(reLoginItem);*/
fonctionJMenu.add(closeItem);
aboutJMenu.add(accountItem);
//给条目绑定事件
people.addActionListener(this);
animal.addActionListener(this);
replayItem.addActionListener(this);
/*reLoginItem.addActionListener(this);*/
closeItem.addActionListener(this);
accountItem.addActionListener(this);
//将选项添加进菜单中
jMenuBar.add(fonctionJMenu);
jMenuBar.add(aboutJMenu);
//给界面设置菜单
this.setJMenuBar(jMenuBar);
}

private void initData() {
Random r = new Random();
int[] tem = {0, 1, 2, 3, 4, 5, 6, 7, 8};
for (int i = 0; i < tem.length; i++) {
int x = r.nextInt(tem.length);
int temp = tem[i];
tem[i] = tem[x];
tem[x] = temp;
}
for (int i = 0; i < tem.length; i++) {
//记录0索引的位置
if (tem[i] == 0) {
x = i / 3;
y = i % 3;
}
data[i / 3][i % 3] = tem[i];
}
}

private void initImage() {
//清空原本出现的所有图片
this.getContentPane().removeAll();
if (victory()) {
JLabel winJLabel = new JLabel(new ImageIcon("image\\else\\win.png"));
winJLabel.setBounds(0, 0, 600, 650);
this.getContentPane().add(winJLabel);
}
JLabel stepCount = new JLabel("步数:" + step);
stepCount.setBounds(0, 0, 100, 20);
this.getContentPane().add(stepCount);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//获取当前加载图片的序号
int num = data[i][j];
//创建一个JLabel的对象
JLabel jLabel = new JLabel(new ImageIcon(path + num + ".jpg"));
//指定图片位置
jLabel.setBounds(200 * j, 216 * i, 200, 216);
//给图片添加边框(优化)
jLabel.setBorder(new BevelBorder(0));
//把管理容器添加到界面中!=this.add(jLabel);
this.getContentPane().add(jLabel);
}
}
//刷新界面
this.getContentPane().repaint();
}
@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.jpg"));
all.setBounds(0, 0, 600, 650);
this.getContentPane().add(all);
}
}
@Override
public void keyReleased(KeyEvent e) {
//若游戏胜利,则不需要再移动了
if (victory())
return;
//对上下左右判断(左37上38右39下40)
int code = e.getKeyCode();
switch (code) {
case 37:
if (y == 2)
return;
data[x][y] = data[x][y + 1];
data[x][y + 1] = 0;
y++;
step++;
initImage();
break;
case 38:
if (x == 2)
return;
data[x][y] = data[x + 1][y];
data[x + 1][y] = 0;
x++;
step++;
initImage();
break;
case 39:
if (y == 0)
return;
data[x][y] = data[x][y - 1];
data[x][y - 1] = 0;
y--;
step++;
initImage();
break;
case 40:
if (x == 0)
return;
data[x][y] = data[x - 1][y];
data[x - 1][y] = 0;
x--;
step++;
initImage();
break;
case 65:
initImage();
case 87:
data = new int[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 0}
};
initImage();
}
}
@Override
public void actionPerformed(ActionEvent e) {
//获取当前被点击的条目对象
Object obj = e.getSource();
Random r = new Random();
if (obj == replayItem) {
System.out.println("重新游戏");
//再次打乱顺序
initData();
//计步器清零(先清零再加载)
step = 0;
//重新加载图片(小bug解决)
initImage();
} /*else if (obj == reLoginItem) {
System.out.println("重新登录");
//关闭当前游戏界面
this.setVisible(false);
//打开登录界面
new LoginJFrame();
}*/ else if (obj == closeItem) {
System.out.println("关闭游戏");
System.exit(0);
} else if (obj == accountItem) {
System.out.println("作者微信");
//创建一个弹窗对象
JDialog jDialog = new JDialog();
//创建一个管理图片的容器对象
JLabel jLabel = new JLabel(new ImageIcon("image\\else\\wechat.png"));
jLabel.setBounds(0, 0, 249, 289);
jDialog.getContentPane().add(jLabel);
//弹框设置大小且置顶居中
jDialog.setSize(344, 344);
jDialog.setAlwaysOnTop(true);
jDialog.setLocationRelativeTo(null);
//弹框不关闭则无法下面的操作
jDialog.setModal(true);
//让弹框显示出来
jDialog.setVisible(true);
} else if (obj == people) {
int x = r.nextInt(4);
path=peoplePath[x];
initData();
step = 0;
initImage();
}
else if (obj == animal) {
int x = r.nextInt(2);
path=animalPath[x];
initData();
step = 0;
initImage();
}
}
//判断是否胜利
public boolean victory() {
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (data[i][j] != win[i][j])
return false;
}
}
return true;
}
}