首页
归档
Github
留言
工具箱
邻居
壁纸
更多
音乐
直播
视频
Search
1
欢迎访问我的日志空间
76,580 阅读
2
Typecho - Joe主题魔改版(持续更新)
8,757 阅读
3
Typecho-Joe主题实现图片评论功能
7,363 阅读
4
WEB音乐播放器源码
6,340 阅读
5
Git上传项目到Github仓库教程
5,343 阅读
学习笔记
源码库
BUG
第九艺术
登录
/
注册
Search
标签搜索
学习笔记
C语言
typecho
Java
扫雷
源码
PHP
插件
网站源码
音乐播放器
模板
git
github
bug
QQBot
AI
机器人
框架
Nekro Agent
XG.孤梦
累计撰写
53
篇文章
累计收到
201
条评论
首页
栏目
学习笔记
源码库
BUG
第九艺术
页面
归档
Github
留言
工具箱
邻居
壁纸
音乐
直播
视频
搜索到
53
篇与
XG.孤梦
的结果
2022-07-14
Git上传项目到Github仓库教程
介绍Git:一个开源的分布式版本控制工具。Github: 一个面向开源及私有软件项目保存用户的数据、代码等文件的托管平台。准备阶段Github&创建仓库Github账号点击访问Github官网,如果访问速度很慢,可以开代理或者开加速器登录直接的github账号,如果没有账号点击右上角的 Sign up 跳转到注册界面注册账号。输入邮箱、密码、用户名信息点击继续,完成邮箱验证即注册成功,然后登录注册的账号创建仓库1.登录账号后,点击右上角的+ --> 点击 New repository2.输入仓库名称,勾选上 Add a README file,然后点击 Greate repository3.仓库创建完成安装git客户端;Git官网地址: https://git-scm.com/[line]下载[/line]Git官方版Windows版Mac版Linux版Git-GUI版WindowsGUI版MacGUI版LinuxGUI版选择适合的版本进入下载,按照安装向导完成安装,不需要配置其他的东西,直接Next。下面以Windows官方版进行演示,其他操作系统操作一致。连接仓库Git配置1.选择要上传的文件,右键鼠标选择 Git Bash Here2.输入命令 ssh-keygen -t rsa -C "your
[email protected]
" ,按提示输入一直回车即可生成秘钥,找到秘钥的文件路径。3.在文件夹中打开秘钥所在路径然后选择 id_rsa.pub 右键以记事本方式打开,复制里面的秘钥。github配置创建SSH秘钥1.点击头像 --> 点击Settings2.点击 SSH and GPG keys --> 点击New SSH Keys3.输入标题名称,然后粘贴从 id_rsa.pub 文件里复制的秘钥,点击 Add SHH key 4.验证连接,输入命令 ssh -T
[email protected]
回车,根据提示输入 yes,出现图片中的提示就说明成功了。配置用户信息设置username和email,github每次commit都会记录这些信息。输入命令: git config --global user.name "注册时填写的名字" 输入命令:git config --global user.email "注册时填写的邮箱" 上传文件上面的环节配置完毕后,下次上传只需要执行以下命令选择要上传的文件,右键鼠标选择 Git Bash Here1.输入命令 git init 将本地项目变成 Git 可以管理的仓库2.输入命令 git add . 将项目的所有文件添加到暂存区3.输入命令 git commit -m "自己项目提交的描述" 将项目文件提交到仓库4.复制github仓库地址,点击 Code --> SSH --> 点击复制5.输入命令 git remote add origin 仓库地址链接 ,连接仓库6.输入命令 git pull --rebase origin master或者main 获取远程库与本地同步(远程仓库不为空需要这一步)7.输入命令 git push -u origin master 上传代码到github远程仓库更新文件进入要更新的项目文件根目录,右键鼠标选择 Git Bash Here1.输入命令 git status 查看当前的git仓库状态2.输入命令 git add * 添加全部更新3.输入命令 git commit -m "更新说明" 添加说明到项目文件4.输入命令 git pull 拉取当前分支最新代码,防止与他人更新代码冲突5.输入命令 git push origin master 更新上传代码到github远程仓库[line]教程到此结束[/line]
2022年07月14日
5,343 阅读
0 评论
4 点赞
2022-07-09
Typecho - Joe主题魔改版(持续更新)
Joe主题2.1.0版本更新特点完全兼容1.0文章编辑器与解析器修复对Typecho1.3.0新版本的页面文章链接解析兼容问题修复了部分已知bug优化了部分代码逻辑更新历史[collapse][collapse-item label="2.0.0"]重构项目,将1.x魔改迁移至新版本Joe兼容1.x主题主要功能代码更规范,简洁[/collapse-item][collapse-item label="1.2.0"]修复已知bug[/collapse-item][collapse-item label="1.1.9"]主题会随时间自动变换模式,默认(7:00-19:00)修复了自动变换模式出现bug[/collapse-item][collapse-item label="1.1.8"]主题会随时间自动变换模式,默认(7:00-19:00)增加手机端页面名片卡片显示,修改了部分css修复了部分bug[/collapse-item][collapse-item label="1.1.7"]移除原来不规范的媒体插入方式,增加评论图片上传插入开关(配置详情见文章《Typecho-Joe主题实现图片评论功能》),效果见我的博客优化了部分模块css显示效果,修复了移动端界面排版错乱问题新增b站表情包包含116个表情[/collapse-item][collapse-item label="1.1.6"]修复了排行榜,重新对接了各平台Api增加了Github页面模板文件(github.php 默认是我的github信息)修改github信息方法:页面新加字段 github,值为你的github账户名。[/collapse-item][collapse-item label="1.1.5"]修复静态资源失效问题修复了部分UI布局问题增加了扫码登录入口、评论与动态ip归属地显示、所有评论等开关增加了右下角登录按钮,下雪特效等功能[/collapse-item][collapse-item label="1.1.4"]修复部分css显示错误增加作者信息卡片个性签名配合定制后台使用增加作者信息卡片背景图片自定义配合定制后台使用[/collapse-item][collapse-item label="1.1.3"]修复部分bug增加了自定义页面模板(可根据需要自行修改)[/collapse-item][collapse-item label="1.1.2"]修复bug[/collapse-item][collapse-item label="1.1.1"]修复cdn文件被污染无法访问,改为本地文件[/collapse-item][collapse-item label="1.1.0"]修复头像显示问题修改部分页面布局修复侧边栏天气api改为和风天气增加了页面访问密码模板(MkEncrypt.php)使用方法:打开 MkEncrypt.php ,查看注释介绍;页面新加字段 passwd 值为你的要设置密码。 [/collapse-item][/collapse]注意:文件夹名必须是 Typecho-Joe-Theme如果想要修改文件名,请使用VScode或者其他编辑工具打开文件搜索 /Typecho-Joe-Theme/ ,将所有搜索出来的资源路径中Typecho-Joe-Theme替换成你想要的文件名安装教程下载后解压到网站根目录/usr/themes/文件加中;登录到typecho后台 --> 更换外观 --> 启用点击设置外观修改自己想要的设置手机端下边栏修改代码Typecho-Joe-Theme/public/footer.php文件中,将 # 修改成自己想要的链接(不打开移动下边栏设置可以忽略)展示图PC端首页移动端首页评论区模板后台管理界面github地址:https://github.com/XG2020/Joe
2022年07月09日
8,757 阅读
91 评论
14 点赞
2022-07-09
Typecho-1.1/17.10.30-定制版源码
版本特点修复了头像显示问题(因国内屏蔽了Gravatar,更换为Cravatar国内源)移除版本更新提示修改了后台部分UI,增加了权限提示增加了个性签名,登录ip显示等功能后台自带美化插件,安装后手动开启首页界面注册登录界面默认开启美化插件后台界面管理员开启美化插件关注者开启美化插件申请页面链接自行修改,在 网站根目录\admin\index.php 图片中的片段个人设置开启美化插件暗黑模式github地址:https://github.com/XG2020/TypechoDIY
2022年07月09日
2,711 阅读
0 评论
5 点赞
2022-07-01
typecho邮件通知插件
本插件建议配合定制版typecho使用效果最佳适用版本 typecho1.1.17.10.30其他版本需要修改插件文件夹目录下Plugin.php文件中的版本判断相关代码功能说明定制版Typecho可使用额外功能找回密码请求时间间隔设置,防止恶意请求找回密码功能,通过邮件找回密码评论审核通过时发送邮件给评论者用户评论文章时发送邮件给文章博主用户评论被回复时发送邮件给被评论用户邮件模板说明插件有三个模板,可以根据自己的想法修改模板,在插件文件夹的theme目录下:approved.html:邮件审核通过通知模板。author.html:文章评论通知作者模板。reply.html:评论回复通知被回复者模板。插件管理界面Github地址:https://github.com/XG2020/XGComment
2022年07月01日
2,320 阅读
0 评论
4 点赞
2022-05-26
Java实现扫雷小游戏三
接下来是完成菜单栏的功能游戏菜单添加菜单监听器(com.panel/BombJMenuBar.java)在init()方法中插入// 开局事件处理 menuItemStart.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { mainframe.reStartGame(); } }); // 添加事件监听器 MenuListener listener = new MenuListener(mainframe); menuItemStart.addActionListener(listener); menuItemLow.addActionListener(listener); menuItemMid.addActionListener(listener); menuItemHigh.addActionListener(listener); menuItemOrder.addActionListener(listener); menuHeroLow.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { new Hero(mainframe); }}); menuHeroMid.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { new Hero1(mainframe); }}); menuHeroHigh.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { new Hero2(mainframe); }}); menuItemAbout.addActionListener(listener); // 后门外挂方便测试 menuItemHole.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); menuItemExit.addActionListener(new ActionListener() { //加一个系统退出的处理监听 public void actionPerformed(ActionEvent e) { System.exit(0); } });编写等级菜单监听类(com.listener/MenuListener)// 等级菜单监听器 public class MenuListener implements ActionListener { JMenuItem jMenuItem; JTextField jTextField=new JTextField(); MainFrame mainframe; public MenuListener(MainFrame mainframe){ this.mainframe = mainframe; } public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("开局(N)")){ this.mainframe.reStartGame(); } if(e.getActionCommand().equals("初级(B)")){ Tools.rows = 9; Tools.cols = 9; Tools.allcount = 10; Tools.currentLevel = Tools.LOWER_LEVEL; this.mainframe.reStartGame(); } if(e.getActionCommand().equals("中级(I)")){ Tools.rows = 16; Tools.cols = 16; Tools.allcount = 40; Tools.currentLevel = Tools.MIDDLE_LEVEL; this.mainframe.reStartGame(); } if(e.getActionCommand().equals("高级(E)")){ Tools.rows = 16; Tools.cols = 30; Tools.allcount = 99; Tools.currentLevel = Tools.HEIGHT_LEVEL; this.mainframe.reStartGame(); } if(e.getActionCommand().equals("自定义(C)")){ new UserDefined(mainframe); } if(e.getActionCommand().equals("关于扫雷(A)")){ new About(mainframe); } } }注意:在雷区BombJPanel.java中之前是把行和列写成固定的,实现初级、中级、高级时要进行下述修改:// MineLabel[][] labels = new MineLabel[9][9]; MineLabel[][] labels = new MineLabel[Tools.rows][Tools.cols];运行效果:自定义菜单项(com.dialog/UserDefined.java)需求分析:出现弹窗界面,数据校验不能超过三位,只能为数字。通过继承JDialog实现用户自定义对话框public class UserDefined extends JDialog { // 自定义 private static final long serialVersionUID = 1L; private JLabel jLabelHigh = new JLabel("高度: "); private JLabel jLabelWide = new JLabel("宽度: "); private JLabel jLabelBomb = new JLabel("雷数: "); private JLabel jLabelMessage = new JLabel(" "); private JTextField jTextFieldHigh; private JTextField jTextFieldWide; private JTextField jTextFieldBomb; private JPanel panel; private JButton buttonSure; private JButton buttonCancer; MainFrame mainFrame; public UserDefined(final MainFrame mainFrame) { super(mainFrame); this.mainFrame = mainFrame; this.setIconImage(Tools.getImageIcon().getImage()); jLabelMessage.setFont(new Font("楷书", Font.PLAIN, 12)); jLabelMessage.setForeground(Color.red); this.setTitle("自定义雷区"); this.add(getPanel()); this.add(jLabelMessage, BorderLayout.NORTH); this.setSize(new Dimension(200, 150)); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); this.setLocationRelativeTo(null); this.setResizable(false); this.addWindowListener(new WindowAdapter() { @Override public void windowDeactivated(WindowEvent e) { mainFrame.reStartGame(); } }); this.setModal(true); this.setVisible(true); } public JPanel getPanel() { JPanel jPanel = new JPanel(); Border border1 = BorderFactory.createEmptyBorder(5, 20, 5, 5); panel = new JPanel(); panel.setLayout(new GridLayout(1, 2)); Box boxHigh = Box.createHorizontalBox(); jTextFieldHigh = new JTextField(Tools.rows + ""); jTextFieldHigh.setPreferredSize(new Dimension(30, 20)); jTextFieldHigh.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { String text = jTextFieldHigh.getText(); Pattern pattern = Pattern.compile("^[0-9]{1,3}$"); Matcher matcher = pattern.matcher(text); if (!matcher.matches()) { jLabelMessage.setText("请输入数字,不能超过三位"); if (text.length() > 3) { jTextFieldHigh.setText(text.substring(0, 3)); } } } @Override public void keyTyped(KeyEvent e) { char ch = e.getKeyChar(); if ((ch < '0') || (ch > '9')) { jLabelMessage.setText("请输入数字,不能超过三位"); e.setKeyChar((char) 8); } else { jLabelMessage.setText(" "); } } @Override public void keyPressed(KeyEvent e) { } }); boxHigh.add(jLabelHigh); boxHigh.add(jTextFieldHigh); Box boxWide = Box.createHorizontalBox(); jTextFieldWide = new JTextField(Tools.cols + ""); jTextFieldWide.setPreferredSize(new Dimension(30, 20)); jTextFieldWide.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { String text = jTextFieldWide.getText(); Pattern pattern = Pattern.compile("^[0-9]{1,3}$"); Matcher matcher = pattern.matcher(text); if (!matcher.matches()) { jLabelMessage.setText("请输入数字,不能超过三位"); if (text.length() > 3) { jTextFieldWide.setText(text.substring(0, 3)); } } } @Override public void keyTyped(KeyEvent e) { char ch = e.getKeyChar(); if ((ch < '0') || (ch > '9')) { jLabelMessage.setText("请输入数字,不能超过三位"); e.setKeyChar((char) 8); } else { jLabelMessage.setText(" "); } } @Override public void keyPressed(KeyEvent e) { } }); boxWide.add(jLabelWide); boxWide.add(jTextFieldWide); Box boxBomb = Box.createHorizontalBox(); jTextFieldBomb = new JTextField(Tools.bombCount + ""); jTextFieldBomb.setPreferredSize(new Dimension(30, 20)); jTextFieldBomb.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { String text = jTextFieldBomb.getText(); Pattern pattern = Pattern.compile("^[0-9]{1,3}$"); Matcher matcher = pattern.matcher(text); if (!matcher.matches()) { jLabelMessage.setText("请输入数字,不能超过三位"); if (text.length() > 3) { jTextFieldBomb.setText(text.substring(0, 3)); } } } @Override public void keyTyped(KeyEvent e) { char ch = e.getKeyChar(); if ((ch < '0') || (ch > '9')) { jLabelMessage.setText("请输入数字,不能超过三位"); e.setKeyChar((char) 8); } else { jLabelMessage.setText(" "); } } @Override public void keyPressed(KeyEvent e) { } }); boxBomb.add(jLabelBomb); boxBomb.add(jTextFieldBomb); Box boxS = new Box(BoxLayout.Y_AXIS); boxS.add(boxHigh); boxS.add(Box.createVerticalStrut(8)); boxS.add(boxWide); boxS.add(Box.createVerticalStrut(8)); boxS.add(boxBomb); boxS.add(Box.createVerticalStrut(8)); boxS.setBorder(border1); Box boxT = new Box(BoxLayout.Y_AXIS); buttonSure = new JButton("确定"); UserDefinedListener definedListener = new UserDefinedListener(this, mainFrame); buttonSure.setPreferredSize(new Dimension(70, 30)); buttonSure.setMargin(new Insets(0, 2, 0, 2)); buttonSure.addActionListener(definedListener); buttonCancer = new JButton("取消"); buttonCancer.setMargin(new Insets(0, 2, 0, 2)); buttonCancer.setSize(new Dimension(70, 30)); buttonCancer.addActionListener(definedListener); boxT.add(buttonSure); boxT.add(Box.createVerticalStrut(25)); boxT.add(buttonCancer); boxT.setBorder(border1); panel.add(boxS); panel.add(boxT); Border border = BorderFactory.createEmptyBorder(3, 15, 5, 15); jPanel.setBorder(border); jPanel.add(panel); return jPanel; } }自定义窗口监听器(com.listener/UserDefinedListener.java)public class UserDefinedListener implements ActionListener { UserDefined userDefined; MainFrame mainFrame; public UserDefinedListener(UserDefined userDefined, MainFrame mainFrame) { this.mainFrame = mainFrame; this.userDefined = userDefined; } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == userDefined.getButtonCancer()) { userDefined.dispose(); mainFrame.reStartGame(); } else if (e.getSource() == userDefined.getButtonSure()) { String highT = userDefined.getjTextFieldHigh().getText(); Pattern pattern = Pattern.compile("^[0-9]{1,3}$"); Matcher matcher = pattern.matcher(highT); int row = 0; if (!matcher.matches()) { userDefined.getjLabelMessage() .setText("输入的行数范围应在9-30之间"); return; } else { row = Integer.parseInt(highT); if (row < 9 || row > 30) { userDefined.getjLabelMessage().setText( "输入的行数范围应在9-30之间"); return; } } String colT = userDefined.getjTextFieldWide().getText(); int col = 0; try { col = Integer.parseInt(colT); if (col < 9 || col > 30) { userDefined.getjLabelMessage().setText( "输入的列数范围应在9-30之间"); return; } } catch (Exception e2) { userDefined.getjLabelMessage().setText( "列数应该为数字且范围应在9-30之间"); return; } String mineT = userDefined.getjTextFieldBomb().getText(); int mine = 0; try { mine = Integer.parseInt(mineT); if (mine < 10) { mine = 10; } else { mine = Math.min(mine, Tools.rows * Tools.cols * 4 / 5); } } catch (Exception e3) { userDefined.getjLabelMessage().setText("雷数应该为数字"); return; } userDefined.dispose(); Tools.rows = row; Tools.cols = col; Tools.allcount = mine; mainFrame.reStartGame(); } } }运行效果:英雄榜弹出胜利窗口(com.dialog/Win.java)public class Win extends JDialog { MainFrame mainframe; private JTextField text; TreeSet<Own> LOWER = new TreeSet<Own>(); TreeSet<Own> MIDDLE = new TreeSet<Own>(); TreeSet<Own> HEIGHT = new TreeSet<Own>(); public Win(MainFrame mainframe){ this.mainframe = mainframe; this.setIconImage(Tools.getImageIcon().getImage()); this.setTitle("扫雷成功"); this.setLocationRelativeTo(null); this.setSize(200, 150); this.init(); this.setVisible(true); } private void init() { // 存放记入 JPanel panel = new JPanel(); panel.setLayout(new GridLayout(4,1)); JLabel label = new JLabel("好厉害!请留下你的大名"); panel.add(label); text = new JTextField(); panel.add(text); // times = mainframe.getTimer().getTimes(); JLabel labTime = new JLabel("你所使用的时间:"+Tools.timecount); panel.add(labTime); JButton butys = new JButton("保存"); butys.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(Tools.currentLevel.equals("初级")){ if(Tools.time1>=Tools.timecount && Tools.time2>=Tools.timecount && Tools.time3>=Tools.timecount){ Tools.time3 = Tools.time2; Tools.name3 = Tools.name2; Tools.time2 = Tools.time1; Tools.name2 = Tools.name1; Tools.time1 = Tools.timecount; Tools.name1=text.getText(); }else if(Tools.time2>=Tools.timecount && Tools.time3>=Tools.timecount && Tools.time1<=Tools.timecount){ Tools.time3 = Tools.time2; Tools.name3 = Tools.name2; Tools.time2 = Tools.timecount; Tools.name2=text.getText(); }else if(Tools.time3>=Tools.timecount && Tools.time1<=Tools.timecount && Tools.time2<=Tools.timecount){ Tools.time3 = Tools.timecount; Tools.name3=text.getText(); } } if(Tools.currentLevel.equals("中级")){ if(Tools.time01>=Tools.timecount && Tools.time02>=Tools.timecount && Tools.time03>=Tools.timecount){ Tools.time03 = Tools.time02; Tools.name03 = Tools.name02; Tools.time02 = Tools.time01; Tools.name02 = Tools.name01; Tools.time01 = Tools.timecount; Tools.name01=text.getText(); }else if(Tools.time02>=Tools.timecount && Tools.time03>=Tools.timecount && Tools.time01<=Tools.timecount){ Tools.time03 = Tools.time02; Tools.name03 = Tools.name02; Tools.time02 = Tools.timecount; Tools.name02=text.getText(); }else if(Tools.time03>=Tools.timecount && Tools.time01<=Tools.timecount && Tools.time02<=Tools.timecount){ Tools.time03 = Tools.timecount; Tools.name03=text.getText(); } } if(Tools.currentLevel.equals("高级")){ if(Tools.time001>=Tools.timecount && Tools.time002>=Tools.timecount && Tools.time003>=Tools.timecount){ Tools.time003 = Tools.time002; Tools.name003 = Tools.name002; Tools.time002 = Tools.time001; Tools.name002 = Tools.name001; Tools.time001 = Tools.timecount; Tools.name001=text.getText(); }else if(Tools.time002>=Tools.timecount && Tools.time003>=Tools.timecount && Tools.time001<=Tools.timecount){ Tools.time003 = Tools.time002; Tools.name003 = Tools.name002; Tools.time002 = Tools.timecount; Tools.name002=text.getText(); }else if(Tools.time003>=Tools.timecount && Tools.time001<=Tools.timecount && Tools.time002<=Tools.timecount){ Tools.time003 = Tools.timecount; Tools.name003=text.getText(); } } Win.this.dispose(); } }); panel.add(butys); this.add(panel); } public JTextField getText() { return text; }运行效果:英雄榜类(com.dialog/Hero.java)英雄榜分为初级、中级、高级英雄榜;每个英雄榜类逻辑是一样的,通过胜利窗口的事件监听器判断是哪个等级的英雄榜数据,然后写入临时变量中保存。以此类推编写中级、高级英雄榜Hero1,Hero2,当然也可以只写一个类,不过需要多加一些判断条件。public class Hero extends JDialog{ private JLabel jlabel1; private JLabel jlabel2; private JLabel jlabel3; private JLabel jlabel4; private JLabel jlabel5; private JLabel jlabel6; private JLabel time1; private JLabel time2; private JLabel time3; private JLabel name1; private JLabel name2; private JLabel name3; private JButton jbutton1; private JButton jbutton2; private MainFrame mainframe; private JPanel jpanel; public Hero(MainFrame mainframe) { this.mainframe=mainframe; this.setIconImage(Tools.getImageIcon().getImage()); this.setTitle("初级英雄榜"); this.setVisible(true); this.setSize(220,220); this.setResizable(false); this.setLocationRelativeTo(mainframe); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); init(); } public JLabel getJLabel1() { return jlabel1; } public void setJLabel1(JLabel jlabel1) { this.jlabel1 = jlabel1; } public JLabel getJLabel2() { return jlabel2; } public void setJLabel2(JLabel jlabel2) { this.jlabel2 = jlabel2; } public JLabel getJLabel3() { return jlabel3; } public void setJLabel3(JLabel jlabel3) { this.jlabel3 = jlabel3; } public JLabel getJLabel4() { return jlabel4; } public void setJLabel4(JLabel jlabel4) { this.jlabel4 = jlabel4; } public JLabel getJLabel5() { return jlabel5; } public void setJLabel5(JLabel jlabel5) { this.jlabel5 = jlabel5; } public JLabel getJLabel6() { return jlabel6; } public void setJLabel6(JLabel jlabel6) { this.jlabel6 = jlabel6; } public JLabel getTime1() { return time1; } public void setTime1(JLabel time1) { this.time1 = time1; } public JLabel getTime2() { return time2; } public void setTime2(JLabel time2) { this.time2 = time2; } public JLabel getTime3() { return time3; } public void setTime3(JLabel time3) { this.time3 = time3; } public JLabel getName1() { return name1; } public void setName1(JLabel name1) { this.name1 = name1; } public JLabel getName2() { return name2; } public void setName2(JLabel name2) { this.name2 = name2; } public JLabel getName3() { return name3; } public void setName3(JLabel name3) { this.name3 = name3; } public void init(){ HeroListener heroListener = new HeroListener(); jlabel1 = new JLabel(" 名次"); jlabel2 = new JLabel(" 成绩"); jlabel3 = new JLabel(" 玩家"); jlabel4 = new JLabel(" 第一名:"); jlabel5 = new JLabel(" 第二名:"); jlabel6 = new JLabel(" 第三名:"); time1 = new JLabel(""+Tools.time1); time2 = new JLabel(""+Tools.time2); time3 = new JLabel(""+Tools.time3); name1 = new JLabel(" "+Tools.name1); name2 = new JLabel(" "+Tools.name2); name3 = new JLabel(" "+Tools.name3); jbutton1=new JButton("确定"); jbutton1.addActionListener(heroListener); jbutton2=new JButton("重新设置"); jbutton2.addActionListener(heroListener); jpanel=new JPanel(); Box box1 = Box.createVerticalBox(); box1.add(jlabel1); box1.add(Box.createVerticalStrut(10)); box1.add(jlabel4); box1.add(Box.createVerticalStrut(10)); box1.add(jlabel5); box1.add(Box.createVerticalStrut(10)); box1.add(jlabel6); Box box2 = Box.createVerticalBox(); box2.add(jlabel2); box2.add(Box.createVerticalStrut(10)); box2.add(time1); box2.add(Box.createVerticalStrut(10)); box2.add(time2); box2.add(Box.createVerticalStrut(10)); box2.add(time3); Box box3 = Box.createVerticalBox(); box3.add(jlabel3); box3.add(Box.createVerticalStrut(10)); box3.add(name1); box3.add(Box.createVerticalStrut(10)); box3.add(name2); box3.add(Box.createVerticalStrut(10)); box3.add(name3); Box box4 = Box.createHorizontalBox(); box4.add(jbutton1); box4.add(Box.createHorizontalStrut(20)); box4.add(jbutton2); Box box5 = Box.createHorizontalBox(); box5.add(box1); box5.add(box2); box5.add(box3); Box box6 = Box.createVerticalBox(); box6.add(Box.createVerticalStrut(20)); box6.add(box5); box6.add(Box.createVerticalStrut(20)); box6.add(box4); jpanel.add(box6); this.add(jpanel); } class HeroListener implements ActionListener{ public void actionPerformed(ActionEvent e){ String command = e.getActionCommand(); if(command.equals("确定")){ dispose(); } else { Tools.time1 = 999; Tools.time2 = 999; Tools.time3 = 999; Tools.name1 = " 匿名"; Tools.name2 = " 匿名"; Tools.name3 = " 匿名"; time1.setText(""+Tools.time1); name1.setText(Tools.name1); time2.setText(""+Tools.time2); name2.setText(Tools.name2); time3.setText(""+Tools.time3); name3.setText(Tools.name3); //dispose(); } } } }运行效果:帮助菜单关于扫雷(com.dialog/About.java)可以根据自己的需求添加想要的窗口内容。public class About extends JDialog { MainFrame mainframe; public About(MainFrame mainframe){ this.setIconImage(Tools.getImageIcon().getImage()); this.mainframe = mainframe; this.setTitle("关于扫雷"); this.setLocationRelativeTo(null); this.setResizable(false); this.setSize(200, 130); this.init(); this.setVisible(true); } private void init() { Box box = Box.createVerticalBox(); JPanel jpanel = new JPanel(); JLabel jlabel = new JLabel("扫雷 ©2022"); JLabel jlabel1 = new JLabel("作者:XG.孤梦"); JLabel jlabel2 = new JLabel("我的博客:https://www.xggm.top"); box.add(jlabel); box.add(Box.createVerticalStrut(10)); box.add(jlabel1); box.add(Box.createVerticalStrut(10)); box.add(jlabel2); jpanel.add(box); this.add(jpanel); } }运行效果:外挂后门(com.listener/MenuListener.java)可以在布雷完成之后就编写这个方法,目的为了方便测试,节省时间,点击外挂,就会将是雷的小方格图片替换成其他图片,比如弄成中间有个小黑点的小方格// 后门外挂方便测试 menuItemHole.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (Tools.isStart) { Tools.isHole = true; // 判断每一个雷块是否是雷 for (MineLabel[] mineLabel : BombJMenuBar.this.mainframe .getBombJPanel().getLabels()) { for (MineLabel m : mineLabel) { if (m.isMineTag()) { m.setIcon(Tools.hole); } } } } } });运行效果:最后一个Java实现扫雷项目就这样完成了。
2022年05月26日
2,919 阅读
0 评论
0 点赞
2022-05-26
Java实现扫雷小游戏二
布雷上一篇已经完成了界面UI的实现,接下来开始功能的实现。定义布雷类(com.tools/LayMine.java)(1)布雷采用随机生成的布雷方式,玩家第一次点击小方格不应该是雷,故布雷功能设计在玩家第一次左键时开始布雷。参数row和col是第一次点击的鼠标坐标。public class LayMine { /** * labels:存储方格的二维数据 * row:当前鼠标点击的x值 * col:当前鼠标点击的y值 */ public static void lay(MineLabel[][] labels, int row, int col) { int count = 0; Random random = new Random(); // 随机 while (count<Tools.allcount) { int x = random.nextInt(Tools.rows); int y = random.nextInt(Tools.cols); if(!labels[x][y].isMineTag() && (x !=row && y!= col)) { // 布雷 labels[x][y].setMineTag(true); count++; } } countBomb(labels); }(2)计算小方格周围雷的数量分析当前方格(x,y)周围方格的坐标:设 x 和 y的最大值分别为 X 和 Y :([0, x+1],[0, y+1])([x-1, x+1],[0, y+1])([x-1, X],[0, y+1])([0, x+1],[y-1, y+1])([x-1, x+1],[y-1, y+1])([x-1, X],[y-1, y+1])([0, x+1],[y-1, Y])([x-1, x+1],[y-1, Y])([x-1, X],[y-1, Y])当前点(x,y)的周围方格x值最小值或者为0,或者为x-1,且不能小于0,x的最小值取Math.max(0, x- 1),x的最大值x+1,或者为X,且x+1最大不能超过X,故x的范围:Math.max(0, x - 1) 至 Math.min(Tools.rows - 1, x + 1)同理y的范围:Math.max(0, y - 1) 至 Math.min(Tools.cols - 1, y + 1)实现方法一理解简单,通俗易懂,代码执行效率较低,不推荐使用public static void countBomb(MineLabel[][] labels) { int count = 0; if (!mineLabel[i][j].isMine()) { // 计算雷块周围八个方向雷数 /** * 上 */ if (i > 0) { if (labels[i - 1][j].isMine()) { count++; } } /** * 左上 */ if (i > 0 && j>0) { if (labels[i - 1][j-1].isMine()) { count++; } } /** * 右上 */ if (i > 0&&j+1< Tools.cols) { if (labels[i - 1][j+1].isMine()) { count++; } } /** * 左 */ if (j>0) { if (labels[i][j-1].isMine()) { count++; } } /** * 右 */ if (j+1< Tools.cols) { if (labels[i][j+1].isMine()) { count++; } } /** * 左下 */ if (i+1< Tools.rows && j>0) { if (labels[i + 1][j-1].isMine()) { count++; } } /** * 下 */ if (i+1< Tools.rows) { if (labels[i + 1][j].isMine()) { count++; } } /** * 右下 */ if (i+1< Tools.rows && j+1< Tools.cols) { if (labels[i + 1][j+1].isMine()) { count++; } } } }实现方法二 /** * |计算周围雷数 */ public static void countBomb(MineLabel[][] labels) { int count = 0; for (int i = 0; i < Tools.rows; i++) { for (int j = 0; j < Tools.cols; j++) { count = 0; // 当前方格不是雷才计算周围雷的数量 if (!labels[i][j].isMineTag()) { for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, Tools.rows - 1); x++) { for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, Tools.cols - 1); y++) { if (labels[x][y].isMineTag()) { count++; } } } labels[i][j].setCountAround(count); } } } }编写测试类(test/TestBomb.java)测试布雷和计数是否准确public class TestBomb { /** * 测试类 */ public static void main(String[] args) { MainFrame mainframe = new MainFrame(); MineLabel[][] labels = mainframe.getBombJPanel().getLabels(); LayMine.lay(labels, 3, 3); // 假设当前鼠标点击位置【3,3】 LayMine.countBomb(labels); for (int i = 0; i < Tools.rows; i++) { for (int j = 0; j < Tools.cols; j++) { if (labels[i][j].isMineTag()) { labels[i][j].setIcon(Tools.mine); }else { int count = labels[i][j].getCountAround(); labels[i][j].setIcon(Tools.mineCount[count]); } } } } }运行效果鼠标事件监听添加鼠标事件监听(com.listener/MouListener)public class MouListener implements MouseListener { MainFrame mainframe; MineLabel[][] labels; Boolean isDoublePress = false;; public MouListener(MineLabel[][] labels, MainFrame mainframe) { this.labels = labels; this.mainframe = mainframe; }在 BombJPanel.java 中为雷区小方块添加事件监听 public BombJPanel(MainFrame mainframe) { this.mainframe = mainframe; //定义布局方式,网格布局 this.setLayout(new GridLayout(Tools.rows, Tools.cols)); listener = new MouListener(labels,mainframe); init(); } // 初始化 private void init() { // 实例化小方格 for(int i = 0;i<labels.length;i++) { for(int j = 0; j<labels[i].length;j++) { labels[i][j] = new MineLabel(i, j); labels[i][j].setIcon(Tools.blank); this.add(labels[i][j]); labels[i][j].addMouseListener(listener); } } // 实现边框效果 Border lowerBorder = BorderFactory.createLoweredBevelBorder(); Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); //边框大小 CompoundBorder compoundBorder = BorderFactory.createCompoundBorder(emptyBorder, lowerBorder) ; this.setBorder(compoundBorder); this.setBackground(Color.LIGHT_GRAY); } }需求分析:鼠标操作包含:左键、右键、左右键同时按下、右键一次、右键两次、右键三次。鼠标按下鼠标左键按下时效果:(1)设置笑脸为惊叹(2)左右键同时按下:设置鼠标所在位置周围小方格为背景效果左键按下时效果:(1)设置笑脸为惊叹(2)如果未被展开的,则显示鼠标所在位置的小方格的背景(3)已被展开则不做处理鼠标右键按下时效果:(1)第一次按下:标记插上红旗(2)第二次按下:标记显示问号(3)第三次按下:还原 // 鼠标按下时 @Override public void mousePressed(MouseEvent e) { MineLabel mineLabel = (MineLabel) e.getSource(); // 获取事件源 int row = mineLabel.getRowx(); int col = mineLabel.getColy(); // 判断是否是鼠标双击(左右键)操作 if (e.getModifiersEx() == InputEvent.BUTTON1_DOWN_MASK + InputEvent.BUTTON3_DOWN_MASK) { isDoublePress = true; doublePress(row, col); // 鼠标左键按下事件 } else if (e.getModifiers() == InputEvent.BUTTON1_MASK && !mineLabel.isFlagTag()) { // 对没有被展开或标记的方格 if (!mineLabel.isExpendTag()) { // 鼠标左键按下背景 mineLabel.setIcon(Tools.mineCount[0]); } // 表情变惊讶 mainframe.getFaceJPanel().getLabelFace().setIcon(Tools.face2); // 鼠标右键按下事件 } else if (e.getModifiers() == InputEvent.BUTTON3_MASK && !mineLabel.isExpendTag()) { // 右键点击数为 0 时 if (mineLabel.getRightClickCount() == 0) { mineLabel.setIcon(Tools.flag); // 设置旗子标记 mineLabel.setRightClickCount(1); mineLabel.setFlagTag(true); Tools.bombCount--; mainframe.getFaceJPanel().setNumber(Tools.bombCount); // 改变计数区雷数图片 // 右键点击数为 1 时 } else if (mineLabel.getRightClickCount() == 1) { mineLabel.setIcon(Tools.ask); // 设置问号标记 mineLabel.setRightClickCount(2); mineLabel.setFlagTag(false); Tools.bombCount++; mainframe.getFaceJPanel().setNumber(Tools.bombCount); // 改变计数区雷数图片 // 第3次点击还原回 未标记状态 } else { mineLabel.setIcon(Tools.blank); mineLabel.setRightClickCount(0); mineLabel.setFlagTag(false); } } }FaceJPanel.java类中添加:// 计数器 根据当前旗子数计算剩余雷数 public void setNumber(int count) { int b = 0; if (count < 0) { b = 10; } else { b = count / 100; } int g = Math.abs(count) % 10; int s = Math.abs(count) / 10 % 10; labelCountG.setIcon(Tools.timeCount[g]); labelCountS.setIcon(Tools.timeCount[s]); labelCountB.setIcon(Tools.timeCount[b]); }鼠标释放需求分析:包含左右键双击释放,左键释放,鼠标右键弹起没有任何动作。鼠标左右键双击释放(1)如果当前方格(被点击的方格)没有标记,且之前未被展开,则还原成点击前的状态(外观);(2)否则(已标记,或者已被展开),就判断方格周围雷的数量与周围被标记旗子的方格数是否相等,如果相等就展开周围的方格A.相等的情况有标记存在两种情况:标记正确:如下图对圆圈所在方格双击释放时将打开其周围的方格标记错误:会有惩罚,相当于触雷,游戏结束。即当前方格周围的雷全部并且正确标记,则会迅速打开当前方格周围未打开的方格,如果标记有错误,则进行惩罚B.不相等:还原小方格状态鼠标左键释放(1)如果是第一次点击,则布雷,且点击的方格不布雷,确保第一次点击不触雷。(2)如果踩到雷,则引发触雷,游戏结束(3)否则展开方格// 鼠标左右键同时按下 private void doublePress(int row, int col) { for (int x = Math.max(0, row - 1); x <= Math.min(Tools.rows - 1, row + 1); x++) { for (int y = Math.max(0, col - 1); y <= Math.min(Tools.cols - 1, col + 1); y++) { if (!labels[x][y].isExpendTag() && !labels[x][y].isFlagTag()) { int rightClickCount = labels[x][y].getRightClickCount(); // 对标记旗子或者展开的不做处理 if (rightClickCount == 1) { labels[x][y].setIcon(Tools.flag); } else { labels[x][y].setIcon(Tools.mineCount[0]); } } } } } // 左键展开方格 private void expand(int x, int y) { int count = labels[x][y].getCountAround(); if (!labels[x][y].isExpendTag() && !labels[x][y].isFlagTag()) { // 周围雷为0,递归调用继续展开 if (count == 0) { labels[x][y].setIcon(Tools.mineCount[count]); labels[x][y].setExpendTag(true); for (int i = Math.max(0, x - 1); i <= Math.min(Tools.rows -1, x + 1); i++) { for (int j = Math.max(0, y - 1); j <= Math.min(Tools.cols -1, y + 1); j++) { expand(i, j); } } } else { // 显示周围雷数 labels[x][y].setIcon(Tools.mineCount[count]); labels[x][y].setExpendTag(true); } } } @Override public void mouseReleased(MouseEvent e) { MineLabel mineLabel= (MineLabel) e.getSource(); // 当前方格 int row = mineLabel.getRowx(); int col = mineLabel.getColy(); // 鼠标双击释放(右键不做处理) if(isDoublePress) { isDoublePress = false; if (!mineLabel.isExpendTag() && !mineLabel.isFlagTag()) { backIcon(row, col); } else { boolean isEquals = isEquals(row, col); if (isEquals) { doubleExpend(row, col); } else { backIcon(row, col); } } mainframe.getFaceJPanel().getLabelFace().setIcon(Tools.face0); // 左键释放 }else if (e.getModifiers() == InputEvent.BUTTON1_MASK && !mineLabel.isFlagTag()) { if(!Tools.isStart) { // 第一次鼠标左键点击,在弹起事件中进行布雷 LayMine.lay(labels, row, col); // 布雷 Tools.isStart = true; //设置isStart=true,表示不是第一次点击了 mainframe.getTimer().start(); // 开启计时器 } if (mineLabel.isMineTag()) {//判断是否踩到地雷 bombAction(row, col); //如果踩到地雷,游戏结束,显示全部的地雷 mineLabel.setIcon(Tools.blood); mainframe.getFaceJPanel().getLabelFace().setIcon(Tools.face3); } else { mainframe.getFaceJPanel().getLabelFace().setIcon(Tools.face0); expand(row, col); } } //判断雷是否已全被清除完 isWin(); } // 左右键双击展开 private void doubleExpend(int i, int j) { for (int x = Math.max(0, i - 1); x <= Math.min(Tools.rows - 1, i + 1); x++) { for (int y = Math.max(0, j - 1); y <= Math.min(Tools.cols - 1, j + 1); y++) { if (labels[x][y].isMineTag()) { // 如果是雷 if (!labels[x][y].isFlagTag()) { // 没有旗子标记 bombAction(x, y); } } else { // 不是雷 if (!labels[x][y].isFlagTag()) { // 没有旗子标记 expand(x, y); } } } } } // 触雷 private void bombAction(int row, int col) { for (int i = 0; i < labels.length; i++) { for (int j = 0; j < labels[i].length; j++) { if (labels[i][j].isMineTag()) { // 是雷 if (!labels[i][j].isFlagTag()) { // 没有标记 labels[i][j].setIcon(Tools.mine0); } else { labels[i][j].setIcon(Tools.mine1); } } } } // 修改踩雷状态 Tools.isBoom = true; // 停止计时器 mainframe.getTimer().stop(); // 取消鼠标监听器 for (int i = 0; i < labels.length; i++) { for (int j = 0; j < labels[i].length; j++) { labels[i][j].removeMouseListener(this); } } } //还原方格显示效果(因为鼠标按下时显示背景) private void backIcon(int i, int j) { for (int x = Math.max(0, i - 1); x <= Math.min(Tools.rows - 1, i + 1); x++) { for (int y = Math.max(0, j - 1); y <= Math.min(Tools.cols - 1, j + 1); y++) { if (!labels[x][y].isFlagTag() && !labels[x][y].isExpendTag()) { int rightClickCount = labels[x][y].getRightClickCount(); if (rightClickCount == 2) { labels[x][y].setIcon(Tools.ask); } else { if(!labels[x][y].isFlagTag()){ labels[x][y].setIcon(Tools.blank); } } } } } } 计数区面板点击事件(1)计时(com.timer/Timers)在主窗体中添加计时器timer控件,并编写事件监听器 // 计时器 public class Timers implements ActionListener { private int times; MainFrame mainfame; public Timers(MainFrame mainfame){ this.mainfame = mainfame; } @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub Tools.timecount++; if(Tools.timecount>999){ Tools.timecount=999; }else{ mainfame.getFaceJPanel().setTime(Tools.timecount); } } }在FaceJPanel.java中添加:// 计时器 public void setTime(int count) { int b = 0; if (count < 0) { b = 10; } else { b = count / 100; } int g = Math.abs(count) % 10; int s = Math.abs(count) / 10 % 10; labelTimeG.setIcon(Tools.timeCount[g]); labelTimeS.setIcon(Tools.timeCount[s]); labelTimeB.setIcon(Tools.timeCount[b]); }(2)“笑脸”事件处理(com.panel/FaceJPanel.java)public class FacelabelListener extends MouseAdapter{ @Override public void mousePressed(MouseEvent e) { if (e.getModifiers() == InputEvent.BUTTON1_MASK) { mainframe.getTimer().stop(); labelFace.setIcon(Tools.face1); } } @Override public void mouseReleased(MouseEvent e) { if (e.getModifiers() == InputEvent.BUTTON1_MASK) { mainframe.getTimer().start(); mainframe.reStartGame(); labelFace.setIcon(Tools.face0); } }(3)重新开始方法(com.main/mainFrame.java) BombJPanel bombJPanel = new BombJPanel(this); FaceJPanel faceJPanel = new FaceJPanel(this); public void reStartGame() { // 游戏重新开始方法 this.remove(faceJPanel); this.remove(bombJPanel); Tools.bombCount = Tools.allcount; Tools.timecount = 0; Tools.isStart = false; Tools.isBoom = false; faceJPanel = new FaceJPanel(this); bombJPanel = new BombJPanel(this); this.add(faceJPanel, BorderLayout.NORTH); this.add(bombJPanel); this.pack(); this.validate(); getTimer().stop(); }在的init方法中添加 private void init() { // 菜单栏 this.setJMenuBar(menuBar); BorderLayout layout = new BorderLayout(); this.setLayout(layout); // 计数区 this.add(faceJPanel,layout.NORTH); // 雷区 this.add(bombJPanel,layout.CENTER); }扫雷成功需求分析:把不是雷的方格全部展开,如果不是雷的方格全部展开了,但雷没被标记也算扫雷成功,以下等式成立即可。被展开的方格数量 = 所有方格数量 - 雷的数量private void isWin() { int expendCount = 0; for (int i = 0; i < labels.length; i++) { for (int j = 0; j < labels[i].length; j++) { if (labels[i][j].isExpendTag()) { expendCount++; } } } if (Tools.rows * Tools.cols - expendCount == Tools.allcount) { for (int i = 0; i < Tools.rows; i++) for (int j = 0; j < Tools.cols; j++) { if (mainframe.getBombJPanel().getLabels()[i][j].isMineTag() && !mainframe.getBombJPanel().getLabels()[i][j].isFlagTag()) { mainframe.getBombJPanel().getLabels()[i][j].setIcon(Tools.flag); } // 移除监听 mainframe.getBombJPanel().getLabels()[i][j] .removeMouseListener(mainframe.getBombJPanel() .getListener()); } mainframe.getFaceJPanel().getLabelFace().setIcon(Tools.face4); mainframe.getFaceJPanel().setNumber(0); mainframe.getTimer().stop(); new Win(mainframe); //成功后弹出英雄记录版 Tools.isStart = false; } } //判断方格周围雷的数量与周围被标记的方格数是否相等 private boolean isEquals(int i, int j) { int count = labels[i][j].getCountAround(); int flagCount = 0; for (int x = Math.max(0, i - 1); x <= Math.min(Tools.rows - 1, i + 1); x++) { for (int y = Math.max(0, j - 1); y <= Math.min(Tools.cols - 1, j + 1); y++) { if (labels[x][y].isFlagTag()) { flagCount++; } } } if (count == flagCount) { return true; }else { return false; } }
2022年05月26日
1,756 阅读
0 评论
1 点赞
2022-05-18
Java扫雷源码
编译软件:IntelliJ IDEA / Eclipse环境: JDK1.5以上介绍:重写了一遍扫雷,代码更加规范,修复了一些小bug,优化了部分代码的算法,将各等级英雄榜独立运行效果图github项目地址:https://github.com/XG2020/Mine-sweeping[card-default width="100%" label="下载地址"][btn href="https://www.lanzoum.com/iUNza0527yhg" type="primary"]点击下载[/btn] 复制密码: [copy]xggm[/copy] [/card-default]
2022年05月18日
2,053 阅读
0 评论
0 点赞
2022-05-18
Java实现扫雷小游戏一
实现项目结构分析主界面主窗体(com.main/MainFrame.java)包含菜单栏、计数区panel和雷区panel。(1)构造方法public MainFrame() { init(); this.setIconImage(Tools.getImageIcon().getImage()); // 设置图标 this.setTitle("扫雷"); // 设置标题 this.setSize(new Dimension(220,300)); // 窗口大小 this.setResizable(false); // 这样让窗口不可放大 this.setLocationRelativeTo(null); this.setLocation(new Point(800,300)); // 设置窗口位置 this.setVisible(true); // 设置窗口显示 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口 }(2)初始化方法 private void init() { // 菜单栏 this.setJMenuBar(menuBar); }菜单栏(com.panel/BombJMenuBar.java)(1)添加菜单、菜单项等public class BombJMenuBar extends JMenuBar { // 菜单项 JMenu menuGame = new JMenu("游戏(G)"); JMenuItem menuItemStart = new JMenuItem("开局(N)"); JMenuItem menuItemLow = new JMenuItem("初级(B)"); JMenuItem menuItemMid = new JMenuItem("中级(I)"); JMenuItem menuItemHigh = new JMenuItem("高级(E)"); JMenu menuHero = new JMenu("英雄榜(T)"); JMenuItem menuHeroLow = new JMenuItem("初级英雄榜"); JMenuItem menuHeroMid = new JMenuItem("中级英雄榜"); JMenuItem menuHeroHigh = new JMenuItem("高级英雄榜"); JMenuItem menuItemOrder = new JMenuItem("自定义(C)"); JMenuItem menuItemExit = new JMenuItem("退出(X)"); JMenu menuHelp = new JMenu("帮助(H)"); JMenuItem menuItemAbout = new JMenuItem("关于扫雷(A)"); JMenuItem menuItemHole = new JMenuItem("外挂(W)"); // 需要在类中声明主窗体变量(属性):作为菜单栏与主窗体交互的媒介 // 声明主窗体对象 MainFrame mainframe; // 编写构造函数和初始化界面方面 public BombJMenuBar(MainFrame mainframe) { this.mainframe = mainframe; init(); }(2)初始化方法 public void init() { // 设置快捷键 menuGame.setMnemonic('G'); // Alt + G menuItemStart.setMnemonic('N'); menuItemLow.setMnemonic('B'); menuItemMid.setMnemonic('I'); menuItemHigh.setMnemonic('E'); menuHero.setMnemonic('T'); menuItemOrder.setMnemonic('C'); menuItemExit.setMnemonic('X'); menuHelp.setMnemonic('H'); menuItemAbout.setMnemonic('A'); menuItemHole.setMnemonic('W'); // 把菜单添加到菜单栏 // 游戏菜单 this.add(menuGame); menuGame.add(menuItemStart); menuGame.addSeparator(); // 添加分隔线 menuGame.add(menuItemLow); menuGame.add(menuItemMid); menuGame.add(menuItemHigh); menuGame.addSeparator(); menuGame.add(menuHero); menuHero.add(menuHeroLow); menuHero.add(menuHeroMid); menuHero.add(menuHeroHigh); menuGame.addSeparator(); menuGame.add(menuItemOrder); menuGame.addSeparator(); menuGame.add(menuItemExit); // 帮助菜单 this.add(menuHelp); menuHelp.add(menuItemAbout); menuHelp.addSeparator(); menuHelp.add(menuItemHole); }运行雷区(com.panel/BombJPanel)雷区是由小方格组成,在众多小方格中随机布雷。(先设计MineLable)(1)MineLablepublic class MineLabel extends JLabel { private boolean mineTag = false; // 判断是否是雷 private boolean expendTag = false; // 判断雷块是否展开 private boolean flagTag = false; // 判断雷块是否插了旗子 private int rowx; // 雷块所在的行 private int coly; // 雷块所在的列 private int countAround; // 计算雷块周围的雷数 private int rightClickCount; // 记录右键点击次数 }(2)编写构造方法public class BombJPanel extends JPanel { // 定义属性 MineLabel[][] labels = new MineLabel[9][9]; // 声明主窗体对象 MainFrame mainframe; MouListener listener; public BombJPanel(MainFrame mainframe) { this.mainframe = mainframe; //定义布局方式,网格布局 this.setLayout(new GridLayout(Tools.rows, Tools.cols)); listener = new MouListener(labels,mainframe); init(); }程序写到这里很多地方都需要要到图片以及雷区行列数等,故定义工具类定义好一些可能在程序中多次用到且后期会改变的资源或者变量。见工具类Tools(3)初始化private void init() { // 实例化小方格 for(int i = 0;i<labels.length;i++) { for(int j = 0; j<labels[i].length;j++) { labels[i][j] = new MineLabel(i, j); labels[i][j].setIcon(Tools.blank); this.add(labels[i][j]); labels[i][j].addMouseListener(listener); } }创建一个合成边框,指定了用于外部和内部边缘的 border 对象在init() 里插入 // 实现边框效果 Border lowerBorder = BorderFactory.createLoweredBevelBorder(); Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); //边框大小 CompoundBorder compoundBorder = BorderFactory.createCompoundBorder(emptyBorder, lowerBorder); this.setBorder(compoundBorder); this.setBackground(Color.LIGHT_GRAY);createLoweredBevelBorder();创建一个具有凹入斜面边缘的边框,将组件当前背景色的较亮的色度用于高亮显示,较暗的色度用于阴影。(在凹入边框中,阴影位于顶部,高亮显示位于其下。)BorderFactory.createEmptyBorder(5, 5, 5, 5);创建占用空间但不绘制的空边框,指定顶部、左侧、底部和右侧的宽度。运行在MainFrame的构造函数中添加 this.pack(); public MainFrame() { init(); ...... this.pack(); // 使控件更紧凑,窗口自动适应大小 ...... }运行计数区(com.panel/FaceJPanel)(1)定义雷的数量与时间显示public class FaceJPanel extends JPanel { // 雷数 private JLabel labelCountG = new JLabel(); // 个位 private JLabel labelCountS = new JLabel(); // 十位 private JLabel labelCountB = new JLabel(); // 百位 // 笑脸 private JLabel labelFace = new JLabel(); // 时间 private JLabel labelTimeG = new JLabel(); // 个位 private JLabel labelTimeS = new JLabel(); // 十位 private JLabel labelTimeB = new JLabel(); // 百位 // // 声明主窗体对象 MainFrame mainframe; (2)编写构造方法 public FaceJPanel(MainFrame mainframe) { this.mainframe = mainframe; this.setLayout(new BorderLayout()); this.setVisible(true); init(); }(3)初始化private void init() { JPanel panel = new JPanel(); // 布局盒子 BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.LINE_AXIS); panel.setLayout(boxLayout); labelFace.addMouseListener(new FacelabelListener()); // 添加表情按钮监听器 // 添加计数区监听器 panel.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent arg0) { if(!Tools.isBoom) { labelFace.setIcon(Tools.face2); } } public void mouseReleased(MouseEvent arg0) { if(!Tools.isBoom) { labelFace.setIcon(Tools.face0); } } }); Icon icon0 = new ImageIcon("./image/d0.gif"); // 计算雷的每位数图片 Icon icon3 = new ImageIcon("./image/d" + Tools.allcount / 100 + ".gif");// 百位 Icon icon2 = new ImageIcon("./image/d" + Tools.allcount /10%10 + ".gif"); // 十位 Icon icon1 = new ImageIcon("./image/d" + Tools.allcount % 10 + ".gif"); // 个位 Icon iconSmile = new ImageIcon("./image/face0.gif"); // 雷数显示图片 labelCountG.setIcon(icon1); labelCountS.setIcon(icon2); labelCountB.setIcon(icon3); // 时间显示图片 labelTimeG.setIcon(icon0); labelTimeS.setIcon(icon0); labelTimeB.setIcon(icon0); // 表情显示图片 labelFace.setIcon(iconSmile); // 添加控件到panel panel.add(Box.createHorizontalStrut(2)); // 最左侧 panel.add(labelCountB); panel.add(labelCountS); panel.add(labelCountG); panel.add(Box.createHorizontalGlue()); // 添加水平方向的构件,占位 panel.add(labelFace); panel.add(Box.createHorizontalGlue()); panel.add(labelTimeB); panel.add(labelTimeS); panel.add(labelTimeG); panel.add(Box.createHorizontalStrut(2)); // 最右侧 // 实现边框效果 Border borderLow = BorderFactory.createLoweredBevelBorder(); // 内边框 Border borderEmpty = BorderFactory.createEmptyBorder(2, 2, 2, 2); Border borderCom1 = BorderFactory.createCompoundBorder(borderLow, borderEmpty); panel.setBorder(borderCom1); panel.setBackground(Color.LIGHT_GRAY); // 外边框 Border borderEmpty1 = BorderFactory.createEmptyBorder(5, 5, 0, 5); this.setBorder(borderEmpty1); this.setBackground(Color.LIGHT_GRAY); this.add(panel); }(4)在主窗体MainFrame中添加FaceJPanelpublic class MainFrame extends JFrame{ ...... private BombJMenuBar menuBar = new BombJMenuBar(this); FaceJPanel faceJPanel = new FaceJPanel(this); BombJPanel bombJPanel = new BombJPanel(this); ...... }在init方法中插入private void init() { ...... this.add(faceJPanel,layout.NORTH); ...... }运行工具类(com.tools/Tools)public class Tools { // 窗口图标 public static ImageIcon imageIcon = new ImageIcon("./image/icon.gif"); public static ImageIcon getImageIcon() { return imageIcon; } public static int rows = 9; // 雷区行数 public static int cols = 9; // 雷区列数 public static int timecount = 0; // 计时 public static int allcount = 10; // 所有雷的数量 public static int bombCount = allcount; // 剩余为未被标记雷数 public static boolean isBoom = false; // 是否踩雷 public static boolean isStart = false; // 是否开始 public static boolean isHole = false; // 是否开启后门外挂 // 排行榜 public static int time = 0; // 初级 public static int time1= 999; public static int time2= 999; public static int time3= 999; public static String name1="匿名"; public static String name2="匿名"; public static String name3="匿名"; // 中级 public static int time01= 999; public static int time02= 999; public static int time03= 999; public static String name01="匿名"; public static String name02="匿名"; public static String name03="匿名"; // 高级 public static int time001= 999; public static int time002= 999; public static int time003= 999; public static String name001="匿名"; public static String name002="匿名"; public static String name003="匿名"; // 游戏等级 public static final String LOWER_LEVEL = "初级"; public static final String MIDDLE_LEVEL = "中级"; public static final String HEIGHT_LEVEL = "高级"; public static final String CUSTOM_LEVEL = "自定义"; // 游戏当前等级 public static String currentLevel = LOWER_LEVEL; // 用来存放0-8地雷数字标签图片 public static ImageIcon mineCount[]; // 用来存放时间数字标签图片 public static ImageIcon timeCount[]; // 静态块 static { mineCount = new ImageIcon[9]; for (int i = 0; i <= 8; i++) { mineCount[i] = new ImageIcon("./image/" + i + ".gif"); } timeCount = new ImageIcon[11]; for (int i = 0; i < 10; i++) { timeCount[i] = new ImageIcon("./image/d" + i + ".gif"); } timeCount[10] = new ImageIcon("./image/d10.gif"); } // 笑脸表情标签图片 public static ImageIcon face0 = new ImageIcon("./image/face0.gif"); public static ImageIcon face1 = new ImageIcon("./image/face1.gif"); public static ImageIcon face2 = new ImageIcon("./image/face2.gif"); public static ImageIcon face3 = new ImageIcon("./image/face3.gif"); public static ImageIcon face4 = new ImageIcon("./image/face4.gif"); public static ImageIcon face5 = new ImageIcon("./image/face5.gif"); public static ImageIcon face6 = new ImageIcon("./image/face6.gif"); public static ImageIcon face7 = new ImageIcon("./image/face7.gif"); public static ImageIcon face8 = new ImageIcon("./image/face8.gif"); // 分别对应 mine雷标签图片 public static ImageIcon mine = new ImageIcon("./image/mine.gif"); public static ImageIcon mine0 = new ImageIcon("./image/mine0.gif"); public static ImageIcon mine1 = new ImageIcon("./image/mine1.gif"); //分别对应 ask问号标签图片 public static ImageIcon ask = new ImageIcon("./image/ask.gif"); public static ImageIcon ask1 = new ImageIcon("./image/ask1.gif"); public static ImageIcon iconTemp = new ImageIcon("./image/icon.gif"); public static Image icon = iconTemp.getImage(); public static ImageIcon blank = new ImageIcon("./image/blank.gif"); public static ImageIcon blood = new ImageIcon("./image/blood.gif"); public static ImageIcon error = new ImageIcon("./image/error.gif"); // 旗子标签图片 public static ImageIcon flag = new ImageIcon("./image/flag.gif"); // hole外挂标签图片 public static ImageIcon hole = new ImageIcon("./image/hole.gif"); }
2022年05月18日
1,902 阅读
0 评论
1 点赞
1
2
3
...
7
简体中文
繁體中文
English
日本語
한국어