免费资源网,https://freexyz.cn/
目录
  • 1.思路与分析
  • 2.程序代码及分析
    • 1.拼图游戏app总代码
    • 2.登录页面代码
    • 3.注册页面代码
    • 4.游戏页面代码
  • 3.总结

    1.思路与分析

    首先我们需要提供几个面板,一些菜单栏以及一些按钮,按照你所需要拼成的图片的一些小切片(可以4*4或者5*5,总之按照你的图片大小来定),定义一个控制图片移动的函数,还需要对你的函数方法及菜单按钮提供监听,然后我们就可以将这些想法付诸行动了。

    2.程序代码及分析

    1.拼图游戏app总代码

    package op1;
    
    public class App {
    
    	public static void main(String[] args) {
    	//	new RegistFrame(); //注册
    		new LoginFrame();  //登录
    	//	new GameFrame();   //游戏
    	}
    }
    

    我们由登录页面引出其他页面,先调用登录函数,运行代码时,先弹出登录页面

    用Java编写一个简单的拼图游戏全过程

    如果输入为空,则会弹出如下提示框

    用Java编写一个简单的拼图游戏全过程

    如果输入错误或者没有注册,则会弹出如下提示框

    用Java编写一个简单的拼图游戏全过程

    随后弹出注册页面

    用Java编写一个简单的拼图游戏全过程

    如果输入为空,则会弹出如下提示框

    用Java编写一个简单的拼图游戏全过程

    如果注册成功,则会弹出如下提示框

    用Java编写一个简单的拼图游戏全过程

    然后便可进入登录页面,进行登录

    用Java编写一个简单的拼图游戏全过程

    随后进入游戏页面

    用Java编写一个简单的拼图游戏全过程

    2.登录页面代码

    package op1;
    
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import javax.swing.*;
    
    public class LoginFrame extends JFrame implements ActionListener {
    	JFrame dk = new JFrame("登录");
    	// 添加按钮
    	JButton login = new JButton("登录");
    	JButton exit = new JButton("退出");
    	// 添加标签
    	JLabel name1 = new JLabel("用户名");
    	JLabel pwd1 = new JLabel("密码");
    	// 添加文本输入框
    	JTextField name = new JTextField(13);
    	JTextField password = new JTextField(13);
    
    	public LoginFrame() {
    		initLoginJFrame();// 初始化界面
    	}
    
    	private void initLoginJFrame() {
    		dk.setSize(210, 200);
    		dk.setAlwaysOnTop(true);
    		// dk.setLocationRelativeTo(null);
    		dk.setDefaultCloseOperation(2);
    		dk.setLayout(new FlowLayout());
    		dk.add(name1);
    		dk.add(name);
    		dk.add(pwd1);
    		dk.add(password);
    		dk.add(login);
    		dk.add(exit);
    		login.addActionListener(this);
    		exit.addActionListener(this);
    		dk.setVisible(true);
    
    	}
    
    	private void initView() {
    
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if (e.getSource() == login) {
    			if (name.getText().equals("") || password.getText().equals("")) {  当用户名或密码文本框内的内容为空时
    				JOptionPane.showMessageDialog(this, "用名或密码不能为空");// 出现对话框提醒
    				name.setText("");// 清空文本框
    				password.setText("");// 清空文本框
    			} else {
    				try {
    					BufferedWriter w = new BufferedWriter(new FileWriter("D:\\用户信息2.0.txt", true));// true追加录入,录入用户信息
    					String sum = name.getText() + " " + password.getText();// 用户名与密码之间用空格连接
    					BufferedReader r = new BufferedReader(new FileReader("D:\\用户信息2.0.txt"));// 读出用户信息
    					String text;
    					Boolean c = false;
    					while ((text = r.readLine()) != null) {
    						if (sum.equals(text)) { // 循环排查,看录入的信息是否与读取的信息相同,如果相同
    							c = true;
    						} // 则c为true,登陆成功,不同,c为false,则登录失败
    					}
    					if (c == true) {
    						JOptionPane.showMessageDialog(this, "登录中!!!");
    						dk.setVisible(false);// 关闭当前窗口
    						new GameFrame();
    					} else {
    						JOptionPane.showMessageDialog(this, "用名或密码错误或没有注册,请重新输入或进入注册!!!");
    						new RegistFrame();
    						name.setText("");// 清空文本框
    						password.setText("");// 清空文本框
    					}
    
    				} catch (IOException ee) {
    				}
    			}
    
    		}
    		if (e.getSource() == exit) {
    			dk.setVisible(false);// 关闭当前窗口
    		}
    
    	}
    }
    

    这是实现登录页面的函数,为了方便理解,我添加了注释。

    3.注册页面代码

    package op1;
    
    import javax.swing.*;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class RegistFrame extends JFrame implements ActionListener {
    	JFrame dk = new JFrame("注册");
    	// 添加按钮
    	JButton regist = new JButton("注册");
    	JButton exit = new JButton("退出");
    	// 添加标签
    	JLabel name1 = new JLabel("用户名");
    	JLabel pwd1 = new JLabel("密码");
    	// 添加文本输入框
    	JTextField name = new JTextField(13);
    	JTextField password = new JTextField(13);
    
    	public RegistFrame() {
    		initregistJFrame();// 初始化界面
    	}
    
    	private void initregistJFrame() {
    		dk.setSize(210, 200);
    		dk.setAlwaysOnTop(true);
    		dk.setLocationRelativeTo(null);
    		dk.setLocation(200, 200); // 设置窗口位置
    		dk.setDefaultCloseOperation(2);
    		dk.setLayout(new FlowLayout());
    		dk.add(name1);
    		dk.add(name);
    		dk.add(pwd1);
    		dk.add(password);
    		dk.add(regist);
    		dk.add(exit);
    		regist.addActionListener(this);
    		exit.addActionListener(this);
    		dk.setVisible(true);
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if (e.getSource() == regist) {
    			if (name.getText().equals("") || password.getText().equals("")) {// 当用户名或密码文本框内的内容为空时
    				JOptionPane.showMessageDialog(this, "用户名或密码不能为空"); // 出现对话框提醒
    				name.setText("");// 清空文本框
    				password.setText("");// 清空文本框
    			} else {
    				try {
    					BufferedWriter w = new BufferedWriter(new FileWriter("D:\\用户信息2.0.txt", true));// true追加录入,录入用户信息
    					String sum = name.getText() + " " + password.getText();// 用户名与密码之间用空格连接
    					BufferedReader r = new BufferedReader(new FileReader("D:\\用户信息2.0.txt"));// 读出用户信息
    					Boolean c = true;
    					String text;
    					while ((text = r.readLine()) != null) {
    						if (sum.equals(text)) { // 循环排查,看录入的信息是否与读取的信息相同,如果相同
    							c = false; // 则c为false,该用户已存在,不同,c为true,则注册成功
    
    						}
    					}
    					if (c == true) {
    						w.write(sum); // 将信息写入文件
    						w.newLine();// 生成换行符
    						w.close();// 关闭文件
    						r.close();
    						JOptionPane.showMessageDialog(this, "注册成功!");
    						dk.setVisible(false);// 关闭当前窗口
    						new LoginFrame();
    					} else {
    						JOptionPane.showMessageDialog(this, "该用户已存在!");
    						name.setText("");// 清空文本框
    						password.setText("");// 清空文本框
    					}
    				} catch (IOException ee) {
    				}
    			}
    
    		}
    		if (e.getSource() == exit) {
    			dk.setVisible(false);// 关闭当前窗口
    		}
    	}
    }
    

    与登录页面的代码差不多。

    4.游戏页面代码

    package op1;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.Random;
    import javax.swing.*;
    import javax.swing.border.BevelBorder;
    
    public class GameFrame extends JFrame implements KeyListener, ActionListener {// 继承一个,实现两个接口
    	// JFrame 界面,窗体
    	// GameFrame即游戏主界面
    	// 与游戏相关的逻辑都比在此JavaBean类中
    	// 创建一个二维数组,加载图片
    	int[][] data = new int[4][4];
    	// 记录空白格在二维数组中的位置
    	int x = 0;
    	int y = 0;
    	// 定义二维数组,正确存储数据,即拼图胜利时,图片的正确顺序
    	int[][] win = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 0 } };
    	// 定义变量统计步数
    	int step = 0;
    	// 创建菜单选项相关的对象(这几项之所以放在initJMenuBar()之外,是因为后面方法重写时要调用)
    	JMenuItem replayItem = new JMenuItem("重新游戏"); // 菜单项,创建选项下面的条目对象
    	JMenuItem closeItem = new JMenuItem("退出");
    	JMenuItem accountItem = new JMenuItem("关于我们");
    	JMenuItem reLoginItem = new JMenuItem("重新登录");
    
    	public GameFrame() {
    		initJFrame();// 初始化界面
    		initJMenuBar();// 初始化菜单
    		initData();// 初始化数据(打乱数据)
    		initImage();// 初始化图片(根据打乱的结果加载图片)
    		this.setVisible(true);// 让界面显示出来,可视化
    	}
    
    	// 初始化数据(打乱数据)
    	private void initData() {
    		// 定义一维数组
    		int[] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    		// 打乱数组中的数据的顺序,遍历数组
    		Random r = new Random(); // 产生随机数r
    		for (int i = 0; i < arr.length; i++) {
    			// 获取到随机索引
    			int index = r.nextInt(arr.length);
    			// 将数组中的每一个元素与随机索引上的数据进行交换
    			int temp = arr[i];
    			arr[i] = arr[index];
    			arr[index] = temp;
    		}
    		// 遍历一维数组arr中的每一个元素,并依次添加到二维数组中
    		for (int i = 0; i < arr.length; i++) {
    			if (arr[i] == 0) { // 确定空白格的位置
    				x = i / 4;
    				y = i % 4;
    			}
    			data[i / 4][i % 4] = arr[i]; // 一维数组转二维数组,并打乱顺序
    		}
    	}
    
    	// 按二维数组中管理的数据添加图片
    	private void initImage() {
    		// 清空原本已经出现的所有图片
    		this.getContentPane().removeAll(); // 将方框里的内容全部清除
    		if (victory()) {
    			// 显示胜利的图标
    			JLabel winJLabel = new JLabel(new ImageIcon("E:/JAVA/OP1/OP1/win.png"));
    			winJLabel.setBounds(203, 283, 197, 73); // 距屏幕左面203个像素,上方283个像素,窗口宽197,长73
    			this.getContentPane().add(winJLabel); // 将胜利图标添加到内容方框
    		}
    		JLabel stepCount = new JLabel("步数:" + step);
    		stepCount.setBounds(50, 30, 100, 20);
    		this.getContentPane().add(stepCount); // 将步数添加到内容方框
    		// 先加载的图片在上方,后加载的图片在下面
    		// 外循环:将内循环重复执行4次
    		for (int i = 0; i < 4; i++) {
    			// 内循环:一行添加4张图片,例:第一行(0,0),(0,1),(0,2),(0,3)
    			for (int j = 0; j < 4; j++) {
    				// 获取要加载图片序号
    				int num = data[i][j];
    				// 创建JLabel的对象(管理容器)
    				JLabel jLabel = new JLabel(new ImageIcon("E:/JAVA/op1/op1/" + num + ".jpg"));// 菜单上的图标
    				// 指定图片位置
    				jLabel.setBounds(105 * j + 90, 105 * i + 130, 105, 105);
    				// 图片添加边框,0:凸,1:凹
    				jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
    				// 把管理容器添加到界面
    				this.getContentPane().add(jLabel);
    			}
    		}
    		// 添加背景图片
    		JLabel background = new JLabel(new ImageIcon("E:/JAVA/op1/op1/background.png"));
    		background.setBounds(50, 40, 508, 560);
    		// 把背景图片添加到界面
    		this.getContentPane().add(background);
    		// 刷新界面
    		this.getContentPane().repaint();
    	}
    
    	private void initJMenuBar() { // 总菜单,菜单条
    		// 创建菜单对象
    		JMenuBar jMenuBar = new JMenuBar();
    		// 创建菜单上面的两个选项的对象
    		JMenu functionJMenu = new JMenu("功能"); // 子菜单,创建两个菜单选项的对象
    		JMenu aboutJMenu = new JMenu("帮助");
    		// 将每一个选项下面的条目添加到选项当中
    		functionJMenu.add(replayItem);
    		functionJMenu.add(reLoginItem);
    		functionJMenu.add(closeItem);
    		aboutJMenu.add(accountItem);
    		// 给条目绑定事件,以便实现动作监听
    		replayItem.addActionListener(this); // 添加动作监听,则必有ActionListener接口,必有唯一的方法重写
    		closeItem.addActionListener(this);
    		accountItem.addActionListener(this);
    		reLoginItem.addActionListener(this);
    		// 将两个选项添加到菜单
    		jMenuBar.add(functionJMenu);
    		jMenuBar.add(aboutJMenu);
    		//设置菜单
    		this.setJMenuBar(jMenuBar);
    	}
    
    	private void initJFrame() {
    		// 设置界面的宽高
    		this.setSize(700, 700);
    		// 设置一个标题为拼图V2.0的窗口
    		this.setTitle("拼图V2.0");
    		// 设置界面置顶
    		this.setAlwaysOnTop(true);
    		// 设置界面居中
    		this.setLocationRelativeTo(null);
    		// 设置关闭模式
    		this.setDefaultCloseOperation(2); // 根据参数的取值不同,做出不同的处理
    		// 取消默认居中放置,按照XY轴形式添加组件
    		this.setLayout(null); // 空布局,相当于自定义布局
    		// 添加键盘监听事件
    		this.addKeyListener(this); // 添加键盘监听,触发KeyEvent事件,调用三种方法,看情况选择
    	
    	}
    
    	@Override
    	public void keyTyped(KeyEvent e) { // 调用keyTyped()方法,并重写
    	}
    
    	// 如果是65,就是按下不松调用的方法,如果是112,就是按下松开调用的方法
    	@Override
    	public void keyPressed(KeyEvent e) {
    		int code = e.getKeyCode();
    		if (code == 112 || code == 65) { // 112代表F1,65代表A,查看原图
    			// 删除界面中所有图片
    			this.getContentPane().removeAll();
    			// 加载已经拼好原图
    			JLabel all = new JLabel(new ImageIcon("E:/JAVA/OP1/OP1/all.jpg"));
    			all.setBounds(30, 70, 420, 420);
    			this.getContentPane().add(all);
    			// 加载背景图片
    			// JLabel background = new JLabel(new ImageIcon("background.png"));
    			// background.setBounds(30, 30, 400, 500);
    			// 把背景图片添加到界面
    			// this.getContentPane().add(background);
    			// 刷新界面
    			this.getContentPane().repaint();
    		}
    	}
    
    	// 松开按键时调用的方法
    	@Override
    	public void keyReleased(KeyEvent e) {
    		// 判断游戏是否胜利,if胜,直接结束,不再执行之后的移动代码
    		if (victory()) {
    			// 结束方法
    			return;
    		}
    		// 判断左:37 上:38 右:39 下:40 讨论四种情况
    		int code = e.getKeyCode(); // 采用键码值
    		System.out.println(code);
    		if (code == 37) {
    			System.out.println("向左移动");
    			if (y == 3) {
    				return;
    			}
    			// 空白格右方的数字往左移动
    			data[x][y] = data[x][y + 1]; // 交换所移动图片与空白格的位置
    			data[x][y + 1] = 0;
    			y++; // 空白格位置改动,所以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) { // 65代表A,刷新界面
    			initImage();
    		} else if (code == 87) { // 87代表W,作弊码,一键生成
    			data = new int[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 0 } };
    			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;
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e) { // 方法重写,并实现ActionEvent类的getSource()方法
    		// 获取当前被点击的条目对象
    		Object obj = e.getSource();
    		// 判断
    		if (obj == replayItem) {
    			System.out.println("重新游戏");
    			// 计步器清零
    			step = 0;
    			// 再次打乱二维数组中的数据
    			initData();
    			// 重新加载图片
    			initImage();
    		} else if (obj == reLoginItem) {
    			System.out.println("重新登录");
    			// 关闭当前界面
    			this.setVisible(false);
    			// 返回登录界面
    			new LoginFrame();
    		} else if (obj == closeItem) {
    			System.out.println("关闭游戏");
    			// 直接关闭虚拟机
    			System.exit(0);
    		} else if (obj == accountItem) {
    			System.out.println("关于我们");
    			// 创建弹框对象
    			JDialog jDialog = new JDialog(); // 发现新大陆,实现弹窗
    			// 创建管理图片的容器对象JLabel
    			// JLabel jLabel = new JLabel(new ImageIcon("about.png"));
    			// 设置位置和宽高
    			// jLabel.setBounds(0,0,258,258);
    			// 把图片添加到弹框
    			// jDialog.getContentPane().add(jLabel);
    			// 弹框大小
    			jDialog.setSize(344, 344);
    			// 设置提示语
    			JLabel clue = new JLabel("按F1或长按A显示原图,按A刷新一下,按W一键拼好");
    			clue.setBounds(0, 0, 100, 20);
    			jDialog.getContentPane().add(clue);
    			// 弹框置顶
    			jDialog.setAlwaysOnTop(true);
    			// 弹框居中
    			jDialog.setLocationRelativeTo(null);
    			// 弹框不关闭则无法操作下面的界面
    			jDialog.setModal(true);
    			// 弹框显示出来
    			jDialog.setVisible(true);
    		}
    	}
    }
    

    这里的代码就显得复杂一些,它包括窗口组件的实现,事件监听的实现,以及拼图移动的实现,如果拼图成功,则会弹出拼图成功的提示图片。

    用Java编写一个简单的拼图游戏全过程

    3.总结

    以上就是就是简单的拼游戏的代码的实现及分析,大家有兴趣可以自己去试试

    免费资源网,https://freexyz.cn/
    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。