用java编写一个简单的拼图游戏全过程-kb88凯时官网登录

来自:网络
时间:2024-09-10
阅读:
免费资源网,https://freexyz.cn/

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("关于kb88凯时官网登录");
	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("关于kb88凯时官网登录");
			// 创建弹框对象
			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/
返回顶部
顶部
网站地图