如何让substring()忽略特定字符,实现无卡顿的带格式字符串动画
解决带格式控制字符的字符串逐帧动画卡顿问题
这问题我之前做MC插件文本动画时也碰到过!核心痛点就是要保留格式控制字符的功能,同时不让它们干扰动画的视觉节奏——毕竟玩家看不到这些§开头的代码,但它们又直接影响文本颜色/样式,绝对不能删。
问题根源分析
你原来的代码是按原始字符串的每个字符位置截断,而§a/§b这类格式码是双字符的控制序列,它们本身不占视觉位置。直接按索引截断会导致:
- 单独截断到
§时,视觉上是空的 - 截断到
§a时,视觉上还是空的 - 直到截断到
§aT,用户才看到第一个可见字符,这就出现了多帧重复的卡顿感
解决方案:区分控制序列与可见字符
思路很简单:遍历字符串时,遇到§就直接处理整个控制序列(§+后续字符),不单独生成状态;只有遇到可见字符时,才将当前完整的字符串(包含已处理的所有控制序列)加入状态列表。
直接上可运行的代码:
Collection<String> states = new ArrayList<>(); String text = "§aTest §bTest2"; StringBuilder currentText = new StringBuilder(); // 先加入初始空状态(如果你的动画需要从空白开始) states.add(""); for (int i = 0; i < text.length(); i++) { char currentChar = text.charAt(i); // 识别格式控制序列:§后面紧跟一个字符(颜色/样式码) if (currentChar == '§' && i + 1 < text.length()) { // 直接追加整个控制序列,不生成单独状态 currentText.append(currentChar).append(text.charAt(i + 1)); i++; // 跳过下一个字符,因为已经处理完整个控制序列了 } else { // 处理可见字符:追加后生成一个新的视觉状态 currentText.append(currentChar); states.add(currentText.toString()); } }
代码效果说明
用你提供的测试文本§aTest §bTest2,生成的状态列表会是:
"""§aT""§aTe""§aTes""§aTest""§aTest ""§aTest §bT""§aTest §bTe"- ...(直到完整字符串)
每一个状态都是视觉上有变化的帧,完全不会出现重复空白/无变化的卡顿,同时所有格式控制字符都完整保留,文本颜色显示完全正常。
额外优化点
如果你的场景中可能出现连续的控制序列(比如§a§lBold),这段代码也能完美处理——每次遇到§都会自动跳过后续的控制字符,不会生成无效状态。
内容的提问来源于stack exchange,提问作者PXAV
相关产品推荐
相关产品推荐

