你是否想要给自己的地图添加一个有逼格而又硬核的结尾?
那就试试这个数据包!
简单的字幕是一个如此简单的数据包,以至于不同版本之间命令的隔阂也不能让它失去作用。换句话说,它在1.14到1.18的版本,乃至未来的版本都可能通用!
简单字幕允许使用者创建、播放一个电影结尾般的滚动字幕,而不用改变终末之诗,就像下面一样。
这个数据包的原理就是利用命名盔甲架不断上升的方式,以每个盔甲架展示每一行字幕,盔甲架上升就是字幕的滚动。
由于这次是一个前置数据包,因此没有过多的操作页面。下面将详细说明这个数据包的使用方法。别担心!很简单的!
字幕文件的格式
要想生成一个字幕,首先需要定义一个字幕文件(不然你的字幕要怎么显示出来啊)。字幕文件应当被统一储存在<存档名>\datapacks\Subtitle\data\subtitle\functions\txt文件夹下,这样程序才能读取出来。每一个字幕文件都是一个.txt文本文档,而这个文件的名字则是将会生成的字幕的文字。字幕文件的编辑格式非常简单,下面就是一个样本。这个样本也被包含在了数据包中。
datapacks\Subtitle\data\subtitle\functions\txt\example.txt
#/#/本文件储存字幕的内容,程序将逐行读取该文件的内容 #/#/以#/#/开头的一行不会被转为字幕函数,也就是注释 #/#/文件的名字即为字幕的名字,所有函数都将自动生成并写入 #/#/值得注意的是,所有的字幕默认中间对齐 #/#/以####开头的一行定义了下一行文字的颜色等属性,错误的属性将被忽略。不同属性间用|分割,属性不分先后 ------------------------ ####gold 简单的字幕 ####gold Simple Subtitle ####bold 制作 Alumopper ####bold 发布于 mcbbs BiliBili ####bold|green mcbbs ID Alumopper ####bold|aqua BiliBili Alumopper ####bold -感谢使用-
文件中的属性也就是指原始JSON文本中的斜体、粗体、删除线、下划线、混乱属性。颜色属性就是16中颜色。详细查看wiki:原始JSON文本格式 – Minecraft Wiki_BWIKI_哔哩哔哩 (biligame.com)
生成程序的使用
在\datapacks\Subtitle\data\subtitle\functions\文件夹下(也就是和命令函数一个文件夹)有一个叫做Subtitle.exe的程序,这个程序承担了读取字幕文件生成字幕的工作。你可以直接双击打开这个程序,然后输入这个字幕文件的文件名。注意,不用加上文件的.txt拓展名。如果成功解析了字幕文件,就会生成一堆字幕函数。如果找不到字幕文件或者字幕文件中有错误,那么程序发出错误或者警告。
当然,程序中有一些简单的命令,分别是:
<字幕文件名> 生成字幕
*exit 退出
*help 帮助(展示所有程序内部命令)
*list 展示所有可用字幕文件
*set 设置
关于设置,目前只有一个设置可以改变,就是interval 即行间距。默认是30(也就是每隔30tick生成一个盔甲架)。使用方法输入*set查看。
游戏中调用字幕
如果你成功地生成了一段字幕,那么展示字幕用的函数将会包含在..(路径省略)/functions/subtitles/<字幕名>/文件夹下,一共包含start、timer、end三个函数。调用start函数会让调用者进入观看字幕的状态,也就是说,一人一字幕,同时也要注意在调用时指明观看字幕的实体。timer就是生成字幕用的。end将会停止播放字幕。字幕播放完毕会自动调用end函数,你也可以手动调用打断字幕的播放。
例如,执行/function subtitle:subtitles/example/start就能显示example字幕。
在播放字幕时,玩家会被锁定视角以及位置。
下载
最后更新于:2021.8.5
b站使用介绍以及演示视频戳这里~:
教你在mc中做出电影般的结尾!地图瞬间高级了!
源码
Program.cs
using System; using System.Collections; using System.IO; using System.Text; namespace Subtitle { class Program { static int interval = 10; static void Main(string[] args) { Console.WriteLine("字幕生成器 by Alumopper"); Console.WriteLine("注意,请将字幕文件放到functions下的txt文件夹中,将本程序直接放到functions文件夹下,否则会读取失败"); bool b = true; while (b) { Console.Write(">>>"); string s = Console.ReadLine(); //命令使用 if (s.StartsWith("*")) { if (s.StartsWith("*set")) { s = s.Substring(4); string[] arg = s.Split(' '); if (arg.Length == 1) { //设置帮助 Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("用法:*set <设置项> [参数]"); Console.WriteLine("可用的<设置项>有:\ninterval\t\t行间距"); Console.WriteLine("参数若不设置,则为默认值"); Console.ResetColor(); } else if (arg.Length == 3) { //读取参数 switch (arg[1]) { case "interval": { try { interval = int.Parse(arg[2]); Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("已将设置interval设置为{0}", interval); Console.ResetColor(); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[错误]" + e.Message); Console.ResetColor(); } break; } default: { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[错误]未知的设置项" + arg[1]); Console.ResetColor(); break; } } } } else { switch (s) { case "*exit": { //退出 b = false; break; } case "*help": { //帮助 Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("<字幕文件名>\t\t生成字幕"); Console.WriteLine("*exit\t\t\t退出"); Console.WriteLine("*help\t\t\t帮助"); Console.WriteLine("*list\t\t\t展示所有可用字幕文件"); Console.WriteLine("*set\t\t\t设置"); Console.ResetColor(); break; } case "*list": { //列出可用文件 Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("目前可用文件"); string[] files = Directory.GetFiles("txt", "*.txt"); foreach (string file in files) { Console.WriteLine(file); } Console.ResetColor(); break; } default: { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[错误]未知的命令" + s); Console.ResetColor(); break; } } } continue; } Console.WriteLine("正在尝试读取" + s + ".txt"); try { string[] ss = File.ReadAllLines("txt\\" + s + ".txt"); Directory.CreateDirectory("subtitles\\" + s); File.Create("subtitles\\" + s + "\\timer.mcfunction").Close(); File.Create("subtitles\\" + s + "\\start.mcfunction").Close(); File.Create("subtitles\\" + s + "\\end.mcfunction").Close(); //写入timer.mcfunction ReadAndWrite(ss, s); //写入start.mcfunction WriteStart(s); //写入tick.mcfunction WriteTick(s); //写入end.mcfunction WriteEnd(s); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("字幕{0}生成完毕!", s); Console.ResetColor(); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[错误]" + e.Message); Console.ResetColor(); } } } static void WriteEnd(string s) { //tag @a remove subt_example_tag //tag @a remove subt_watching //scoreboard players set subt_example subt_timer -1 //kill @e[tag = subt_line, type = armor_stand] File.WriteAllLines("subtitles\\" + s + "\\end.mcfunction", new string[] { "tag @a remove subt_" + s + "_tag", "tag @a remove subt_watching", "scoreboard players set subt_" + s + " subt_timer -1", "kill @e[tag=subt_line, type=armor_stand]" }); } static void WriteTick(string s) { //execute if score subt_example subt_timer matches 0.. run scoreboard players add subt_example subt_timer 1 //execute as @a[tag = subt_example_tag] at @s run function subtitle: subtitles / example / timer File.AppendAllLines("subtitles\\tick.mcfunction", new string[] { "execute as @a[tag=subt_" + s + "_tag] at @s run function subtitle:subtitles/" + s + "/timer", "execute if score subt_" + s + " subt_timer matches 0.. run scoreboard players add subt_" + s + " subt_timer 1" }); } static void WriteStart(string s) { //tag @s add subt_example_tag //scoreboard players set subt_example subt_timer 0 File.AppendAllLines("subtitles\\" + s + "\\start.mcfunction", new string[] { "tag @s add subt_watching" }); File.AppendAllLines("subtitles\\" + s + "\\start.mcfunction", new string[] { "tag @s add subt_" + s + "_tag" }); File.AppendAllLines("subtitles\\" + s + "\\start.mcfunction", new string[] { "scoreboard players set subt_" + s + " subt_timer 0" }); } static void ReadAndWrite(string[] ss, string name) { //储存文本属性 Text t = new Text(); //tick数 int timer = 0; for (int i = 0; i < ss.Length; i++) { //分析每一行文字 if (ss[i].StartsWith("#/#/")) { //为注释,忽略 continue; } else if (ss[i].StartsWith("####")) { //声明了属性,进行分割 string a = ss[i].Substring(4); string[] b = a.Split('|'); t.Set(b, i); } else { //为字幕文本,进行输出 //execute if score subt_example subt_timer matches 10 run summon armor_stand ~1 ~-5 ~ {Invisible:true,CustomNameVisible:true,Tags:["subt_line"],NoGravity:1b,CustomName:'{"text string output = ("execute if score subt_" + name + " subt_timer matches " + timer + " run summon armor_stand ~2 ~-5 ~ {Invisible:true,CustomNameVisible:true,Tags:[\"subt_line\"],NoGravity:1b,CustomName:'{\"text\":\"" + ss[i] + "\""); // + "}'}" if (t.Color != null) { //如果有颜色 output += (",\"color\":\"" + t.Color + "\""); } if (t.Other.Count != 0) { //如果有属性 foreach (string s in t.Other) { output += (",\"" + s + "\":true"); } } output += "}'}\n"; //Console.WriteLine(output); using (FileStream f = new FileStream("subtitles\\" + name + "\\timer.mcfunction", FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) { byte[] buffer = Encoding.UTF8.GetBytes(output); f.Write(buffer, 0, buffer.Length); } timer += interval; t = new Text(); } } File.AppendAllLines("subtitles\\" + name + "\\timer.mcfunction", new string[] { "execute if score subt_" + name + " subt_timer matches " + (timer + 120) + " run function subtitle:subtitles/" + name + "/end" }); } } }
Text.cs
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Subtitle { public class Text{ private string _color; public string Color { get { return this._color;} } private ArrayList _other = new ArrayList(); public ArrayList Other { get { return this._other; } } public static ArrayList colors = new ArrayList(); public static ArrayList others = new ArrayList(); public Text() { colors.Add("black"); colors.Add("dark_blue"); colors.Add("dark_green"); colors.Add("dark_aqua"); colors.Add("dark_red"); colors.Add("dark_purple"); colors.Add("gold"); colors.Add("gray"); colors.Add("dark_gray"); colors.Add("blue"); colors.Add("green"); colors.Add("aqua"); colors.Add("red"); colors.Add("light_purple"); colors.Add("yellow"); colors.Add("white"); others.Add("bold"); others.Add("italic"); others.Add("underlined"); others.Add("strikethrough"); others.Add("obfuscated"); } public static bool IsColor(string s) { return colors.Contains(s); } public static bool IsOther(string s) { return others.Contains(s); } public void Set(string[] ss,int i) { //分析属性 foreach(string s in ss) { if (IsColor(s)) { if (_color != null) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("[警告]在{0}行出现过多的颜色属性", i - 1); Console.ResetColor(); } _color = s; } else if (IsOther(s)) { _other.Add(s); } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("[警告]在{0}行出现无效的属性", i - 1); Console.ResetColor(); } } } } }