Java猜拳游戏
AnLingYi 人气:0前言
“java.lang.NullPointerException” 空指针异常可以说是Java程序最容易出现的异常了,我写了一个 IDEA
插件,每当程序出现空指针异常时就会弹出一个“猜拳游戏”窗口,该窗口不能直接关闭,只有当你游戏获胜时,窗口才会自动关闭。
作用是啥?
嘲讽罢了。
插件实现
创建项目
IDEA
创建一个插件开发项目非常方便,已经内置了。
猜拳游戏实现
很简单。
实现原理:提供3个按钮,分别为“石头、剪刀、布”,对应值“1、2、3”,再为按钮绑定点击事件,按键点击之后调用处理函数传入对应的值即可。
处理函数 handle(int selectedValue)
的实现:利用随机数随机为电脑生成一个值与用户选择的值做比较,“石头赢剪刀、剪刀赢布、布赢石头”,然后显示游戏结果,用户获胜时会触发回调函数(用于关闭弹窗)。
package cn.xeblog.mora.ui; import javax.swing.*; import java.awt.*; import java.util.Random; /** * @author anlingyi * @date 2022/8/11 8:02 PM */ public class MoraGame extends JPanel { /** * 猜拳获胜调用 */ private Runnable runnable; /** * 提示标签 */ private JLabel tipsLabel; /** * 结束标记 */ private boolean isOver; public MoraGame(Runnable runnable) { setMinimumSize(new Dimension(250, 100)); setLayout(new BorderLayout()); this.runnable = runnable; init(); } private void init() { this.tipsLabel = new JLabel("请出拳!", JLabel.CENTER); this.tipsLabel.setPreferredSize(new Dimension(250, 50)); this.tipsLabel.setFont(new Font("", 0, 15)); this.tipsLabel.setForeground(new Color(255, 128, 128)); JButton stoneButton = new JButton("石头"); JButton shearsButton = new JButton("剪刀"); JButton clothButton = new JButton("布"); stoneButton.setFocusPainted(false); stoneButton.setBorderPainted(false); stoneButton.addActionListener(l -> handle(1)); shearsButton.setFocusPainted(false); shearsButton.setBorderPainted(false); shearsButton.addActionListener(l -> handle(2)); clothButton.setFocusPainted(false); clothButton.setBorderPainted(false); clothButton.addActionListener(l -> handle(3)); JPanel centerPanel = new JPanel(); centerPanel.setPreferredSize(new Dimension(250, 30)); centerPanel.add(stoneButton); centerPanel.add(shearsButton); centerPanel.add(clothButton); add(tipsLabel, BorderLayout.NORTH); add(centerPanel, BorderLayout.CENTER); } private void handle(int selectedValue) { if (isOver) { return; } int value = new Random().nextInt(3) + 1; boolean isWin = selectedValue == (value - 1 == 0 ? 3 : value - 1); String result; if (isWin) { isOver = true; result = "你赢~"; } else if (selectedValue == value) { result = "平局~"; } else { result = "电脑赢~"; } showTips("电脑 -> " + getText(value) + ",你 -> " + getText(selectedValue) + "," + result); if (isWin) { new Thread(() -> { try { Thread.sleep(800); this.runnable.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } }).start(); } } private String getText(int value) { switch (value) { case 1: return "石头"; case 2: return "剪刀"; case 3: return "布"; } return ""; } private void showTips(String tips) { tipsLabel.setText(tips); } }
游戏弹窗实现
将窗口设置为不可关闭,传递弹窗关闭回调函数到游戏处理对象。
package cn.xeblog.mora.ui; import com.intellij.openapi.ui.DialogWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; /** * @author anlingyi * @date 2022/8/11 7:58 PM */ public class MoraDialog extends DialogWrapper { public MoraDialog() { super(true); setTitle("猜拳游戏?"); setResizable(false); setCrossClosesWindow(false); init(); } @Override protected @Nullable JComponent createCenterPanel() { return new MoraGame(() -> SwingUtilities.invokeLater(() -> this.close(0))); } @Override protected @NotNull Action[] createActions() { return new Action[]{}; } }
监听空指针异常
实现控制台过滤接口,判断控制台的输出内容是否包含 java.lang.NullPointerException
,如果包含则弹出游戏窗口。
package cn.xeblog.mora.filter; import cn.xeblog.mora.ui.MoraDialog; import com.intellij.execution.filters.ConsoleFilterProvider; import com.intellij.execution.filters.Filter; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import javax.swing.*; /** * @author anlingyi * @date 2022/8/11 11:46 PM */ public class ConsoleFilter implements ConsoleFilterProvider { @Override public Filter @NotNull [] getDefaultFilters(@NotNull Project project) { return new Filter[]{(line, entireLength) -> { if (line.contains("java.lang.NullPointerException")) { SwingUtilities.invokeLater(() -> new MoraDialog().show()); } return null; }}; } }
注册过滤器
plugin.xml
添加我们自定义的控制台过滤器实现。
<extensions defaultExtensionNs="com.intellij"> <consoleFilterProvider implementation="cn.xeblog.mora.filter.ConsoleFilter"/> </extensions>
安装插件
插件打包
Gradle -> Tasks -> build -> assemble
打包之后的文件位于项目的 build
目录下:build/distributions/xxx.zip
插件安装
进入插件中心,选择本地文件安装即可。
演示
会出现空指针的代码
public static void main(String[] args) { Object obj = null; System.out.println(obj.toString()); }
运行之后
当我猜拳赢了之后,窗口就自动关闭了。
最后
加载全部内容