一、为什么要在这个阶段做这样的一个项目?
1、理解Swing框架:
这个项目使用了Swing框架来构建图形用户界面(GUI)。通过实践,你可以更好地掌握如何使用Swing组件(如JFrame, JLabel, JMenuBar等)以及它们的布局和事件处理机制。
2、提高编程技能:
完成一个实际的项目可以帮助你巩固Java基础知识,包括数组操作、循环、条件语句、类和对象等。你还可以学习到如何处理图像文件、键盘事件监听等更高级的主题。
3、增强解决问题的能力:
在开发过程中,你会遇到各种问题,例如如何正确地处理键盘输入、如何更新界面等。解决这些问题可以锻炼你的逻辑思维能力和调试技巧。
4、了解面向对象编程:
项目采用了面向对象的设计方式,这有助于加深对Java面向对象特性的理解,如封装、继承和多态等。
二、 实现思路
需要的素材:通过百度网盘分享的文件:素材.rar
链接:https://pan.baidu.com/s/1xWpsMy67xhfx9spylxN68g?pwd=yrpn
提取码:yrpn
我们在写游戏的时候,也是一部分一部分完成的。
先写游戏主界面,实现步骤如下:
1,完成最外层窗体的搭建。
2,再把菜单添加到窗体当中。
3,把小图片添加到窗体当中。
4,打乱数字图片的顺序。
5,让数字图片可以移动起来。
6,通关之后的胜利判断。
7,添加其他额外的功能。
2.1完成最外层窗体的搭建
import Gameoperation.GameJFrame;
import Gameoperation.LoginJFrame;
import Gameoperation.RegisterJFrame;
public class APP {
public static void main(String[] args) {
//程序的主入口,需要运行直接运行就可以
new GameJFrame();
// new LoginJFrame();
// new RegisterJFrame();
}
}
这个游戏涉及到java中图形化界面操作的内容,所以需要使用GUI。s
首先,有建好包,然后再包里面写三个不同的javablean类,用来操作不同的界面,在包的外面写一个APP类,用来启动游戏。
2.2完成GameJFrame中的操作
package Gameoperation;
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 {
int [][]win={
{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}
};
JMenuItem replayItem = new JMenuItem("重新游戏");
JMenuItem LoginItem = new JMenuItem("重新登录");
JMenuItem CloseItem = new JMenuItem("关闭游戏");
JMenuItem AccountItem = new JMenuItem("公众号");
String path = "E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\animal\\animal3\\";
// x y 用来记录空白图片的位置
int x = 0;
int y = 0;
// 4 个为一组 添加数据
int[][] data = new int[4][4];
// 设置 步数记录
int step = 0;
//这里写游戏界面的主框架,所有游戏内容都放到这里面
public GameJFrame() {
// 初始化界面
initJFrame();
// 初始化菜单
initMenuBar();
//(打乱图片) 初始化数据
initData();
initImageView();
// 显示游戏界面,建议放到最后
this.setVisible(true);
}
// 初始化数据
// 现在 需要按照二维数据 来添加图片
private void initData() {
// 把一个一维数组中的数据 打乱 然后放到二维数组中 4 个一组
int[] tempArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
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;
}
data[i/4][i%4]=tempArr[i];
}
}
private void initMenuBar() {
// 初始化菜单 --创建这个对象的菜单
JMenuBar jMenuBar = new JMenuBar();
// 创建 菜单上面的2个选项
JMenu functionMenu = new JMenu("功能");
JMenu abortMenu = new JMenu("关于我们");
// 创建 选项下面的对象
// 给每一个条目邦定事件
replayItem.addActionListener(this);
LoginItem.addActionListener(this);
CloseItem.addActionListener(this);
AccountItem.addActionListener(this);
//功能 把每一个对象都放到 上面的选项中
functionMenu.add(replayItem);
functionMenu.add(LoginItem);
functionMenu.add(CloseItem);
// 公众号
abortMenu.add(AccountItem);
// 把两个选项添加到 菜单中
jMenuBar.add(functionMenu);
jMenuBar.add(abortMenu);
// 给整个界面设置菜单
this.setJMenuBar(jMenuBar);
}
public void initImageView() {
// 删除所有的图片
this.getContentPane().removeAll();
if(victory()){
// 如果胜利 需要返回一个胜利的图标
JLabel win=new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\win.png"));
win.setBounds(203,283,197,73);
this.getContentPane().add(win);
}
//计数
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];
JLabel jLabel = new JLabel(new ImageIcon(path + num + ".jpg"));
// 指定图片位置
jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
// 给图片添加边框
jLabel.setBorder(new BevelBorder(1));
// 把容器放到 界面中
this.getContentPane().add(jLabel);
}
}
JLabel backgroundLabel = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\background.png"));
backgroundLabel.setBounds(40, 40, 508, 560);
this.getContentPane().add(backgroundLabel);
// 刷新所有的图片
this.getContentPane().repaint();
}
private void initJFrame() {
//设置游戏界面的宽高
this.setSize(683, 680);
// 设置游戏名称
this.setTitle("拼图小游戏.单机版1.0");
//设置游戏置顶
this.setAlwaysOnTop(true);
// 设置游戏界面居中
this.setLocationRelativeTo(null);
// 关闭游戏
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 取消默认的居中放置,才能按照x ,y 轴的新式添加图片
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();
// 加载上all图片
JLabel all = new JLabel(new ImageIcon(path + "all.jpg"));
all.setBounds(83, 134, 420, 420);
this.getContentPane().add(all);
// 添加背景图片
JLabel backgroundLabel = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\background.png"));
backgroundLabel.setBounds(40, 40, 508, 560);
this.getContentPane().add(backgroundLabel);
// 刷新图片
this.getContentPane().repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
/// 判断游戏是否已经胜利 如果胜利就不能再执行下面的代码了
if (victory()){
// 结束方法
return;
}
int code = e.getKeyCode();
// 左: 37 上:38 右:39 下:40
if ( code == 37 ) {
System.out.println("向左移动");
if ( y == 3 ) {
return;
}
data[x][y] = data[x][y + 1];
data[x][y + 1] = 0;
y++;
// 每移动一次,step就自增
step++;
initImageView();
} else if ( code == 38 ) {
System.out.println("向上移动");
if ( x == 3 ) {
return;
}
data[x][y] = data[x + 1][y];
data[x + 1][y] = 0;
x++;
// 每移动一次,step就自增
step++;
initImageView();
} 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就自增
step++;
initImageView();
} 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就自增
step++;
initImageView();
} else if ( code == 65 ) {
initImageView();
} else if ( code == 87 ) {
data = new int[][]{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
initImageView();
}
}
// 判断输赢 输 false ---- 赢 true
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;
}
@Override
public void actionPerformed(ActionEvent e) {
/// 获取当前被点击的 项目
Object obj=e.getSource();
if(obj==replayItem){
System.out.println("重新游戏");
// 计步器 清零
step=0;
// 再次打乱二维数组的数据
initData();
// 图片再次重新加载
initImageView();
}
else if(obj==LoginItem){
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 jLabel1 = new JLabel(new ImageIcon("E:\\Tool\\study_java\\day12java2024-8-13 拼图游戏\\image\\about.png"));
jLabel1.setBounds(0,0,258,258);
// 把图片添加到弹框中
this.getContentPane().add(jLabel1);
// 给弹窗设置大小
jDialog.setSize(344,344);
//给弹框置顶
jDialog.setAlwaysOnTop(true);
//给弹框据中
jDialog.setLocationRelativeTo(null);
// 弹框不关闭 就不执行下面的操作
jDialog.setModal(true);
// 让弹框显示出来
jDialog.setVisible(true);
}
}
}
代码较长,这个是游戏界面的全部代码,至于注册和登录界面后续会跟新。
2.3检测游戏中的核心代码是否实现?
接下来我们开始运行程序
1.快捷键:a 直接可以看到结果
2.作弊键:w 直接结束游戏
2.4注意事项:
由于时间较短,我没有完成登录和注册部分,但是游戏的核心的代码是完成的,需要注意的是,图片的地址是绝度路径,这个大家需要把图片下载到自己的电脑中,然后更改路径。