本帖最后由 Dahesor 于 2023-1-1 12:02 编辑

命令教程“真”从零开始 (五) 记分板与/scoreboard
声明:
1.
本教程 默认所有读者看过本系列的前四帖。作者不对可能冒出来的术语或方言负责。以前帖的链接在 系列目录
2. 本
系列 教程默认读者拥有关于Minecraft游戏的基础了解。
3. 本系列全部教程
适用于当前Java最新版(1.19.3) 本页内容同时适用于1.18
4. 本系列教程致力于基础原理而非使用方法,因为某些原因,这是本声明里最重要的一条。


<<<<<< 返回系列目录 ←←

Minecraft命令是一种自洽的编程语言么?
有一些人在讨论这个问题。
但我们今天要研究的并不是这个。
——编程语言嘛,有一个要素是必须的,那就是 变量(Variables)
今天,我们要看的,就是变量的问题—— 记分板,/scoreboard。

注意,/scoreboard在Java1.13之后与1.12之前相差很大。其标签与队伍的功能被分化为两条独立的指令。
你可以看看 这里
注意,基岩版并没有将标签与队伍的功能分化为两条独立的指令。对于这两个较Java多出的功能与其他的细微差异,


管理记分板

想要研究记分板,首先让我们创建一个看看:
/scoreboard这条指令分为了两个子指令:/scoreboard objectives,与/scoreboard players。
其中,/scoreboard objectives主要是用于管理记分板本身,而/scoreboard players则用于管理玩家在记分板上的分数。
添加一个记分板,我们使用的是管理记分板的/scoreboard objectives add:
格式:
  1. /scoreboard objectives add <记分板ID> <记分准则> [<显示名称>]
复制代码

add就是“添加”的意思,<记分板ID>(学名:记分项)为一串英文字符(可以使用下划线)。理论上你用什么都行,只要保证不重复而且自己记得住分得清就好了。

接下来,就是复杂一点的东西了:也就是上方出现的元素“<记分准则>”


记分准则

什么是 记分准则(criterion)
简单来讲就是,根据什么加分?
足球是进一门加一分,羽毛球是谁接不住对手加一分,这里也一样——如何加分?

好,现在找到游戏暂停页面中的"统计"这一项。
这一个功能记录了玩家非常多的数据:你走了几米,跳了几下,破坏一个特定的方块几次,杀死几只僵尸,又或者触发了几次袭击事件。
这里记录的所有项目,都可以成为准则。
而且不止,除了这些项目,还有更多可用的记分准则。
你的记分板可以让玩家“每丢出一颗钻石加一分”,又或者“有多少生命值就设定为几分”,也可以是“每杀一名玩家”加一分,甚至“每杀死一名属于特定队伍的玩家加一分”或“被特定队伍的玩家杀死加一分”等等等等。
在这里我不会列出所有准则列表——学会自己找资料看wiki吧。
你可以点这里在WIKI中寻找所有可用的记分准则。

填入准则,你就有一个记分板啦。
比如:
  1. /scoreboard objectives add 123 deathCount
复制代码

这会创建一个ID为“123”的记分板,记分方式为“deathCount”,也就是“死亡次数”——玩家每死一次就加一分。
但在这些准则中,有两项是特殊的——
一个是"dummy",另一个是"trigger"。
dummy的学名是“虚拟型”,听起来可能很唬人,但翻译过来就是“假的”,或者“货币”。
如果你使用dummy作为准则,这个记分板不会因为任何原因增加分数,只能用指令调整。所以dummy普遍地被使用在游戏的货币,计算,或者分数系统上。
至于trigger嘛,我们还涉及不到。虽然不难,但涉及到了JSON相关,现在有个印象就好。


显示名称


最后,就是显示名称。这不同于ID,是玩家在游戏中可以看到的名称。你可以使用任何字符,任何语言。
[<显示名称>] 完全是使用JSON格式表达的, 系列教程第17帖 讲到。不过在了解JSON之前,用双引号将你想要的文字引起来就好了:
  1. /scoreboard objectives add abc dummy "金钱"
复制代码
这条指令会创建一个ID为 “abc” ,显示名称为 金钱 ,记分方式为 只能指令更改 的记分板。如何使用指令更改分数,会在下面讨论。

注意!这是英文的双引号 "" 而不是中文的 “” 别搞错了! (很多人 都会出现切错中英文引号,括号,等于号,连字符等等问题。)

其他管理


接下来,是几条没啥可讲,不讲又不完整的指令:

1. 列出

如果你忘记了自己记分板的ID,怎么办?
你要使用的是
  1. /scoreboard objectives list
复制代码
这会列出所有记分板的ID,显示名称,与积分准则。




2. 修改

如果你突然对一个记分板的显示名称不满意,可以使用以下指令修改它:
  1. /scoreboard objectives modify <记分板ID> displayname <显示名称>
复制代码
......我是不知道为什么Wiki上选择记分板的方式是“<准则>”啦,这显然是错的,额,发完这帖我就去改过来。(日常Wiki挑错)
  1. /scoreboard objectives modify abc displayname "分数"
复制代码
这会将abc记分板的显示名称更改为 分数

除了显示名称,你还可以修改 渲染类型 。简单来说就是,怎么表示你的得分数?
我们目前只有两种选择:使用爱心或是数字:
  1. /scoreboard objectives modify <记分板ID> rendertype (hearts|integer)
复制代码

比如:
  1. /scoreboard objectives modify hp rendertype hearts
复制代码

这条指令会使用爱心来显示abc的分数:



我的分数会以“心”的方式被显示:每一分是半颗心。但由于这个记分板的记分方式就是“生命值”,有多少血就是几分,所以上方显示的就是我的生命值
除了正常生命值,当记分准则为“生命值”时,它同样可以显示伤害吸收的金心。


3. 删除

你可以使用/scoreboard objectives remove 来移除一个记分板:
  1. /scoreboard objectives remove <记分板ID>
复制代码
例:
  1. /scoreboard objectives remove abc
复制代码
本指令会把刚才创建的记分板abc移除。

显示

各位看到这里可能有个疑问:我们在地图里看到的记分板里明明是被显示在一边的啊,如何显示一个记分板?
你要使用的子指令名叫“setdisplay”,翻译过来就是“设置显示”:
  1. /scoreboard objectives setdisplay <槽位> [<记分板ID>]
复制代码
什么是“<槽位>”?这是说,你要把分数显示在哪里?
你有3个基本选项:sidebar,list,与belowname。
sidebar就是最常见的“显示在屏幕右侧”:
  1. /scoreboard objectives setdisplay sidebar abc
复制代码
这会将记分板abc的分数显示在屏幕右侧,效果是这样的:

在上一帖中,我把自己加入了蓝队,所以你可以注意到我的ID是蓝色的。记分板总会把玩家ID更改为他队伍的颜色。

除了sidebar以外,你还可以使用list,即“显示在tab键里”。
  1. /scoreboard objectives setdisplay list hp
复制代码
将一个ID为“hp”的记分板显示在list槽位。
按下tab就可以看到:

(本图片来自Minecraft Wiki 关于/scoreboard的条目

最后是belowName,也就是显示在姓名下方:



除了这些,sidebar还有“只为特定队伍显示”的选项:
  1. /scoreboard objectives setdisplay sidebar.team.<color> abc
复制代码
(如果你忘了什么是/team,回去看第四帖)
将“<color>”替换为一种颜色,就只会向拥有特定颜色的队伍中的玩家显示本记分板——因为虽然可以创建无数个队伍,但颜色只有十六种,所以从某种角度来讲,我们最多只能创建16支队伍。
例:
  1. /scoreboard objectives setdisplay sidebar.team.red abc
复制代码
红队(red) 玩家可以在屏幕右侧看到abc记分板。

注意,一个位置上只能有一个记分板,且sidebar与sidebar.team.<color>冲突。
同样注意,基岩版没有设定特定队伍显示的选项,只有基础的三种选择。

现在,回去看我们有关显示设定的指令格式,你会发现[记分板ID]是一个可选元素。如果你不填写这个元素,指令将会清空这个位置:
  1. /scoreboard objectives setdisplay sidebar
复制代码
将槽位sidebar清空。

那好,现在,你创立了一个记分板,并输入了让其显示在屏幕右侧的指令——但你会发现,该记分板没有出现在右侧。
为什么呢?
因为上面没分。你的记分板是空的。接下来要讲的,就是如何对分数修改,运算。

管理分数


现在,假设我们有一个"dummy"(虚拟型)记分板ID为test(即"测试")
这个记分板的准则是"dummy",是不会因为任何原因自动加分的。
想要修改它的分数,只能使用指令。
这里,我们就涉及到/scoreboard的另一个子指令“/scoreboard players”。这个子指令专门用于管理分数。
当你创建一个记分板时,上面是没有分数的。注意这不是说分数为零, 而是说分数是“空” 连0都没有 。这种空的记分板,即使使用了刚才讲过的设置显示的指令,在他拥有分数之前是不会显示的。
那么现在,你有三种直接更改分数的方法: 加分(add),减分(remove),与设置(set)
  1. /scoreboard players (add|remove|set) <目标> <记分板ID> <值>
复制代码
该指令会将<目标>在记分板:“<记分板ID>” 上的分数增加/减少/设置为<值>。
不难理解:
  1. /scoreboard players remove Dahesor test 10
复制代码
这条指令会把我(Dahesor)在记分板"test"上的分数减少10。
  1. /scoreboard players add @a abc 3
复制代码
这条指令会把所有玩家(@a)在记分板'abc"上的分数增加3。
注意,如果在运行这条指令前<目标>的分数为空,也就是最开始的情况,那么当你使用:"add"或者"remove"时,将从零开始算。
注意,即使有一个运作的准则,比如“每扔出一根木棍加一分”而不是"dummy",你仍可以使用指令修改分数。但对于“是否获得某个进度”这种要么是1要么是0(要么是真要么是假)的记分板,虽然可以更改分数,但一旦该进度被更新(玩家完成或使用指令剥夺/给予进度),分数就会回到1或0。
注意,会实时更新的准则,比如“生命值”之类,是不能修改的。因为个记分板的分数
每时每刻都会更改为你目前的生命值,所以更改也没用。同样,这些记分板一旦创建就会在下一次更新时获得玩家的分数,也不存在分数为“空”的状况。(在本情况下,“下一次更新”是指你受伤或回血导致生命值更改的时候。)

而:
  1. /scoreboard players set @e test 5
复制代码
会把所有实体(@e)在记分板"test"上的分数设为5。
是的,实体也是可以在记分板上拥有分数的。
本指令会把所有玩家,村民,僵尸,其他生物,抑或是飞行中的火球,掉落的经验球这些实体在记分板abc上的分数均设为5分。

啊啊,不止可以设置实体的分数哦,你还可以使用“虚拟目标”。就是在记分板上添加一个不存在的目标的分数:
  1. /scoreboard players set tp test 5
复制代码
我这是单人游戏,名叫“tp”的玩家并不存在,但我还是可以添加它到记分板上。

这说明了什么?
你可以将一个数字保存在记分板,你可以使用变量啦!
有啥用?
呼,自己想。这里只教指令本身。
我相信,也不得不相信,MInecraft与Minecraft玩家的可能性。(这毕竟是我写教程的目的。)
如果你想要将某人的分数恢复成一开始的“啥都没有”的状态,请执行:
  1. /scoreboard players reset <目标> [<记分板ID>]
复制代码
这会清除<目标>在 特定记分板<记分板ID>上的分数。
注意“[记分板ID]”是一个可选元素——如果你不指定记分板ID,<目标>在任何(能被更改的)记分板上的分数都会被清除。

获取分数

还记得记分板显示的“槽位”吗?
槽位并不多,不算队伍类,就只有3个而已,你也只能直接获取3个记分板的分数罢了
那么,如何得到其他记分板的分数呢?
你可以使用:
  1. /scoreboard players get <目标> <记分板ID>
复制代码
这条指令会给出<目标>在特定记分板“<记分板ID>”上的分数。

那现在好了,如果你连“谁在哪里有没有分”这种问题都不知道了,你可以使用list:
  1. /scoreboard players list [<目标>]
复制代码
本指令会显示<目标>在所有记分板上的分数。
你可以发现[目标]是一个可选元素。所以如果你省略“目标”:
  1. /scoreboard players list
复制代码
本指令会列出所有在任意记分板上有分数的实体。
你也可以在“<目标>”中填“*”。
这和不填的效果是一样的,都会列出所有在任意记分板上有分数的实体:
  1. /scoreboard players list *
复制代码

运算


最后,让我们看向今天最后一项内容,也是任何编程语言的核心之一: 运算
/scoreboard players operation命令允许你对两个数字作数学或逻辑运算。你可以将一个分数加到另一个分数上,也可以做“取最小值”这样的逻辑运算,是以后数据包等高端内容的核心之一。
格式:
  1. /scoreboard players operation <目标> <目标记分板ID> <操作> <来源> <来源记分板ID>
复制代码

解析:
/soreboard players opertaion 指令头>子指令>更下级子指令: 记分板,分数操作,运算
<目标> <目标记分板ID> 被运算的分数,也就是数学说的“被减数”或“被除数”,比如“Dahesor abc” 即为我(Dahesor)在记分板abc上的分数。
<操作> 你要干嘛?要加要减要乘要除?
<来源> <来源记分板ID> 这是来源分数,也就是数学说的“减数”或“除数”,和目标分数是一个写法。

有哪些操作?

目前,你一共有9种不同的选择器:

运算符 运算名称 描述
= 赋值 把目标的分数设为来源的分数。
+=
加法 把来源的分数加到目标分数上。
-= 减法 在目标分数上减去来源的分数。
*= 乘法 将目标分数设为目标分数与来源分数的乘积。
/= 除法 将目标分数设为被来源的分数除后的结果。
%= 求余 将目标分数设为被来源的分数除后得到的余数。
< 取较小值 如果来源分数比目标分数小,则把目标分数设为来源分数。
> 取较大值 取较大值:如果来源分数比目标分数大,则把目标分数设为来源分数。
>< 交换 将来源分数与目标分数交换。


注意,在所有的9种运算中,只有最后一种交换会改变来源分数。

记分板无法存储小数,当使用除法出现小数是会向下取整。

例:
  1. /scoreboard players operation Dahesor a *= MysticNebula70 b
复制代码

将Dahesor在a记分板上的分数设定与MysticNebula70在b记分板上的乘积。
若原值:Dahesor a = 3,MysticNebula70 b = 10,
那么结束后:Dahesor a = 30,MysticNebula70 b = 10。

  1. /scoreboard players operation Dahesor money += @a money
复制代码

将Dahesor在money记分板上的分数增加所有玩家在money记分板上的分数。
若原值:Dahesor money = 10,玩家1 money = 5,玩家2 money = 15
结果为:Dahesor money = 10+5+15+10=40(Dahesor也是玩家之一,玩家也包含我,所以还要加上自己的分数),玩家1 money = 5,玩家2 money = 15

  1. /scoreboard players operation @r x >< Dianliang233 y
复制代码

将一名随机玩家在x记分板上的分数与Dianliang233在y记分板上的分数交换。
若原值:随机玩家 x = 0,Dianliang233 y = 10,
结果为:随机玩家 x = 10,Dianliang233 y = 0。
(Dianliang233是MCWiki“最年轻的编辑者”(那是段很有趣的故事))

再次提醒,“><”是唯一一个会改变来源分数的运算。

还有一件有趣的事是,这里,你可以使用" * "填在<目标> 或 <来源>(但不能同时)中用以代表 在任意记分板上有分数的实体(包括虚拟分数)
下面的内容可能有些复杂,你可以跳过,几乎不会有影响,下面的东西也很少用到。

让我们举几个带“ * ”的例子。
比如说:
  1. /scoreboard players operation * x = Dahesor y
复制代码
将所有在任意记分板上有分数的实体(包括虚拟目标)在x记分板上的分数设为Dahesor在y记分板上的分数。

若原值:
x记分板: a有4分,b有3分。
y记分板: Dahesor有10分。
z记分板: c有500分,d有24分。
那么,运算结束后:
x记分板: a有10分,b有10分,c有10分,d有10分,Dahesor有10分。
y记分板: Dahesor有10分。
z记分板: c有500分,d有24分。

你看,z记分板在指令中完全没有被指令提及,但是,只要在 任意记分板上有分数 ,就会被“*”选中。

例2:
  1. /scoreboard players operation Dahesor x = * y
复制代码
这会将Dahesor在x记分板上的分数依次设置为所有在记分板上有分数的对象在y记分板上的分数。

若原值:
x记分板:Dahesor只有0分。
y记分板:a有5分,b有10分。
那么,运算结束后:
y记分板不变,Dahesor在x记分板上的分数——还是0分。
为什么?
因为Dahesor的分数会依次被赋值为“ 所有在任意记分板上有分数的对象在y记分板上的分数 ”。
我们是一个接一个地“赋值”,所以说 哪个分数在最后,Dahesor就会变成哪个分数。

在同一记分板上分数从高到低排列。

谁在y记分板上的分数最低呢?
是Dahesor,分数为0(空的)。
所以,Dahesor在x记分板上的 零蛋 被赋值为Dahesor在y记分板上的 零蛋 ————还是 零蛋

例3:
  1. /scoreboard players operation Dahesor x *= * y
复制代码
本指令的含义为,将Dahesor在x记分板上的分数乘以所有“在任意记分板上有分数的对象的分数”。

若原值:
x记分板:
Dahesor有2分。
y记分板:
a有3分,b有8分,Dahesor有5分。
没有其他记分板。
那么,运算后,Dahesor在x记分板上的分数为:
  1. 2*3*8*5
复制代码

等于240分。

注意,在本例中,只要要有任意一个对象在y记分板上的分数等于0,那么最后Dahesor的分数都会变成零——因为无论什么数,乘以0都等于0。

以上就是本帖的全部内容了。
......实际上,还有一个子指令enable还没讲到。记得前面跳过的准则“trigger”么?这是和那相关的。本子指令会在以后讲/trigger时详细提到。

结束了呢,开心开心,又可以放假了,回到水论坛和泡Bilibili的时光了。
本帖本来是打算和上一帖一起发布的,但中间遇到了很多麻烦,连本帖都是经历了断网和断电一系列麻烦才发出的。
那,期待后续的就收藏一下好吧......还有我终于快拿到小麦种子勋章了(好感动)。


附录

#更新日志

Java 1.16.5/a  页面发布,版本1.16.5
Java 1.16.5/b  感谢种拔的提醒,加入了关于除法余数的问题
Java 1.16.5/c  前往1.12版本教程的帖子因过久而被锁定,加入了新的链接
Java 1.16.5/d  根据 Wiki命令:语法 ,更改了命令语法
Java 1.16.5/e  补充了大量对“*”的说明。

Java 1.17/a 1.17版本升级完成
Java 1.18/a 1.18版本升级完成
Java 1.19.3/a 1.19升级完成
Java 1.19.3/b 批量替换:计分-->记分

上一帖: [命令] 有关队伍/team 命令教程“真”从零开始 (四)


下一篇: [命令] /tag指令,与进阶~选择器参数 命令教程“真”从零开始 (六)




2021.12 数据,可能有更多内容 命令教程“真”从零开始 (五) 记分板与/scoreboard
声明:
1.
本教程 默认所有读者看过本系列的前四帖。作者不对可能冒出来的术语或方言负责。以前帖的链接在最后。
2. 本
系列 教程默认读者拥有关于Minecraft游戏的基础了解。
3. 本系列全部教程
适用于当前Java最新版(1.17)
4. 本系列教程致力于基础原理而非使用方法,因为某些原因,这是本声明里最重要的一条。



Minecraft命令是一种自洽的编程语言么?
有一些人在讨论这个问题。
但我们今天要研究的并不是这个。
——编程语言嘛,有一个要素是必须的,那就是 变量(Variables)
今天,我们要看的,就是变量的问题—— 记分板,/scoreboard。


注意,/scoreboard在Java1.13之后与1.12之前相差很大。其标签与队伍的功能被分化为两条独立的指令。 你可以看看 这里 注意,基岩版并没有将标签与队伍的功能分化为两条独立的指令。对于这两个较Java多出的功能与其他的细微差异, 你可以在Wiki这里查找相关信息



管理计分板


想要研究计分板,首先让我们创建一个看看:
/scoreboard这条指令分为了两个子指令:/scoreboard objectives,与/scoreboard players。
其中,/scoreboard objectives主要是用于管理计分板本身,而/scoreboard players则用于管理玩家在计分板上的分数。
添加一个计分板,我们使用的是管理计分板的/scoreboard objectives add:
格式:

代码:

  1. /scoreboard objectives add <计分板ID> <计分准则> [显示名称]

add就是“添加”的意思,&lt;计分板ID&gt;(学名:计分项)为一串英文字符(可以使用下划线)。理论上你用什么都行,只要保证不重复而且自己记得住分得清就好了。


接下来,就是复杂一点的东西了:也就是上方出现的元素“&lt;计分准则&gt;”


计分准则


什么是 计分准则(criterion)
简单来讲就是,根据什么加分?
足球是进一门加一分,羽毛球是谁接不住对手加一分,这里也一样——如何加分?


好,现在找到游戏暂停页面中的&quot;统计&quot;这一项。
这一个功能记录了玩家非常多的数据:你走了几米,跳了几下,破坏一个特定的方块几次,杀死几只僵尸,又或者触发了几次袭击事件。
这里记录的所有项目,都可以成为准则。
而且不止,除了这些项目,还有更多可用的计分准则。
你的计分板可以让玩家“每丢出一颗钻石加一分”,又或者“有多少生命值就设定为几分”,也可以是“每杀一名玩家”加一分,甚至“每杀死一名属于特定队伍的玩家加一分”或“被特定队伍的玩家杀死加一分”等等等等。
在这里我不会列出所有准则列表——学会自己找资料看wiki吧。
你可以点这里在WIKI中寻找所有可用的计分准则。


填入准则,你就有一个计分板啦。
比如:

代码:

  1. /scoreboard objectives add 123 deathCount

这会创建一个ID为“123”的计分板,记分方式为“deathCount”,也就是“死亡次数”——玩家每死一次就加一分。
但在这些准则中,有两项是特殊的——
一个是&quot;dummy&quot;,另一个是&quot;trigger&quot;。
dummy的学名是“虚拟型”,听起来可能很唬人,但翻译过来就是“假的”,或者“货币”。
如果你使用dummy作为准则,这个计分板不会因为任何原因增加分数,只能用指令调整。所以dummy普遍地被使用在游戏的货币或者分数系统上。
至于trigger嘛,我们还涉及不到。虽然不难,但涉及到了JSON相关,现在有个印象就好。


显示名称


最后,就是显示名称。这不同于ID,是玩家在游戏中可以看到的名称。你可以使用任何字符,任何语言。
[显示名称] 完全是使用JSON格式表达的,与上一帖/team的显示名称相似,在了解JSON之前,用双引号将你想要的文字引起来就好了:

代码:

  1. /scoreboard objectives add abc dummy "金钱"

这条指令会创建一个ID为 “abc” ,显示名称为 金钱 ,计分方式为 只能指令更改 的记分板。如何使用指令更改分数,会在下面讨论。

注意!这是英文的双引号 &quot;&quot; 而不是中文的 “” 别搞错了! (所有人打 代码都会出现切错中英文引号,括号,等于号,连字符等等问题。)


其他管理


接下来,是几条没啥可讲,不讲又不完整的指令:


1. 列出

如果你忘记了自己计分板的ID,怎么办?
你要使用的是

代码:

  1. /scoreboard objectives list
这会列出所有计分板的ID,显示名称,与积分准则。





2. 修改


如果你突然对一个计分板的显示名称不满意,可以使用以下指令修改它:

代码:

  1. /scoreboard objectives modify <计分板ID> displayname <显示名称>
......我是不知道为什么Wiki上选择计分板的方式是“&lt;准则&gt;”啦,这显然是错的,额,发完这帖我就去改过来。(日常Wiki挑错)

代码:

  1. /scoreboard objectives modify abc displayname "分数"

这会将abc计分板的显示名称更改为 分数


除了显示名称,你还可以修改 渲染类型 。简单来说就是,怎么表示你的得分数?
我们目前只有两种选择:使用爱心或是数字:

代码:

  1. /scoreboard objectives modify <记分板ID> rendertype (hearts|integer)

比如:

代码:

  1. /scoreboard objectives modify hp rendertype hearts

这条指令会使用爱心来显示abc的分数:





我的分数会以“心”的方式被显示:每一分是半颗心。但由于这个计分板的计分方式就是“生命值”,有多少血就是几分,所以上方显示的就是我的生命值。(这段有点绕口哈)
除了正常生命值,它同样可以显示伤害吸收的金心。


3. 删除


你可以使用/scoreboard objectives remove 来移除一个计分板:

代码:

  1. /scoreboard objectives remove <计分板ID>
例:

代码:

  1. /scoreboard objectives remove abc
本指令会把刚才创建的计分板abc移除。


显示


各位看到这里可能有个疑问:我们在地图里看到的计分板里明明是被显示在一边的啊,如何显示一个记分板?
你要使用的子指令名叫“setdisplay”,翻译过来就是“设置显示”:

代码:

  1. /scoreboard objectives setdisplay <槽位> [记分板ID]
什么是“&lt;槽位&gt;”?这是说,你要把分数显示在哪里?
你有3个基本选项:sidebar,list,与belowname。
sidebar就是最常见的“显示在屏幕右侧”:

代码:

  1. /scoreboard objectives setdisplay sidebar abc
这会将计分板abc的分数显示在屏幕右侧,效果是这样的:

在上一帖中,我把自己加入了蓝队,所以你可以注意到我的ID是蓝色的。计分板总会把玩家ID更改为他队伍的颜色。


除了sidebar以外,你还可以使用list,即“显示在tab键里”。

代码:

  1. /scoreboard objectives setdisplay list hp
将一个ID为“hp”的计分板显示在list槽位。
按下tab就可以看到:

(本图片来自Minecraft Wiki 关于/scoreboard的条目


最后是belowName,也就是显示在姓名下方:





除了这些,sidebar还有“只为特定队伍显示”的选项:

代码:

  1. /scoreboard objectives setdisplay sidebar.team.<color> abc
(如果你忘了什么是/team,回去看第四帖)
将“&lt;color&gt;”替换为一种颜色,就只会向拥有特定颜色的队伍中的玩家显示本计分板——因为虽然可以创建无数个队伍,但颜色只有十六种,所以从某种角度来讲,我们最多只能创建16支队伍。
例:

代码:

  1. /scoreboard objectives setdisplay sidebar.team.red abc
红队(red) 玩家可以在屏幕右侧看到abc计分板。


注意,一个位置上只能有一个计分板,且sidebar与sidebar.team.&lt;color&gt;冲突。
同样注意,基岩版没有设定特定队伍显示的选项,只有基础的三种选择。


现在,回去看我们有关显示设定的指令格式,你会发现[记分板ID]是一个可选元素。如果你不填写这个元素,指令将会清空这个位置:

代码:

  1. /scoreboard objectives setdisplay sidebar
将槽位sidebar清空。


那好,现在,你创立了一个计分板,并输入了让其显示在屏幕右侧的指令——但你会发现,该计分板没有出现在右侧。
为什么呢?
因为上面没分。你的计分板是空的。接下来要讲的,就是如何对分数修改,运算。


管理分数


现在,假设我们有一个&quot;dummy&quot;(虚拟型)记分板ID为test(即&quot;测试&quot;)
这个计分板的准则是&quot;dummy&quot;,是不会因为任何原因自动加分的。
想要修改它的分数,只能使用指令。
这里,我们就涉及到/scoreboard的另一个子指令“/scoreboard players”。这个子指令专门用于管理分数。
当你创建一个计分板时,上面是没有分数的。注意这不是说分数为零, 而是说分数是“空” 连0都没有 。这种空的计分板,即使使用了刚才讲过的设置显示的指令,在他拥有分数之前是不会显示的。
那么现在,你有三种直接更改分数的方法: 加分(add),减分(remove),与设置(set)

代码:

  1. /scoreboard players (add|remove|set) <目标> <计分板ID> <值>
该指令会将&lt;目标&gt;在计分板:“&lt;计分板ID&gt;” 上的分数增加/减少/设置为&lt;值&gt;。
不难理解:

代码:

  1. /scoreboard players remove Dahesor test 10
这条指令会把我(Dahesor)在计分板&quot;test&quot;上的分数减少10。

代码:

  1. /scoreboard players add @a abc 3
这条指令会把所有玩家(@a)在计分板'abc&quot;上的分数增加3。
注意,如果在运行这条指令前&lt;目标&gt;的分数为空,也就是最开始的情况,那么当你使用:&quot;add&quot;或者&quot;remove&quot;时,将从零开始算。
注意,即使有一个运作的准则,比如“每扔出一根木棍加一分”而不是&quot;dummy&quot;,你仍可以使用指令修改分数。但对于“是否获得某个进度”这种要么是1要么是0(要么是真要么是假)的计分板,虽然可以更改分数,但一旦该进度被更新(玩家完成或使用指令剥夺/给予进度),分数就会回到1或0。
注意,会实时更新的准则,比如“生命值”之类,是不能修改的。因为个计分板的分数
每时每刻都会更改为你目前的生命值,所以更改也没用。同样,这些计分板一旦创建就会在下一次更新时获得玩家的分数,也不存在分数为“空”的状况。(在本情况下,“下一次更新”是指你受伤或回血导致生命值更改的时候。)


而:

代码:

  1. /scoreboard players set @e test 5
会把所有实体(@e)在计分板&quot;test&quot;上的分数设为5。
是的,实体也是可以在计分板上拥有分数的。
本指令会把所有玩家,村民,僵尸,其他生物,抑或是飞行中的火球,掉落的经验球这些实体在计分板abc上的分数均设为5分。


啊啊,不止可以设置实体的分数哦,你还可以使用“虚拟目标”。就是在计分板上添加一个不存在的目标的分数:

代码:

  1. /scoreboard players set tp test 5
我这是单人游戏,名叫“tp”的玩家并不存在,但我还是可以添加它到计分板上。


这说明了什么?
你可以将一个数字保存在计分板,你可以使用变量啦!
有啥用?
呼,自己想。这里只教指令本身。
我相信,也不得不相信,MInecraft与Minecraft玩家的可能性。(这毕竟是我写教程的目的。)
如果你想要将某人的分数恢复成一开始的“啥都没有”的状态,请执行:

代码:

  1. /scoreboard players reset <目标> [计分板ID]
这会清除&lt;目标&gt;在 特定计分板&lt;计分板ID&gt;上的分数。
注意“[计分板ID]”是一个可选元素——如果你不指定计分板ID,&lt;目标&gt;在任何(能被更改的)计分板上的分数都会被清除。


获取分数


还记得记分板显示的“槽位”吗?
槽位并不多,不算队伍类,就只有3个而已,你也只能直接获取3个计分板的分数罢了
那么,如何得到其他记分板的分数呢?
你可以使用:

代码:

  1. /scoreboard players get <目标> <记分板ID>
这条指令会给出&lt;目标&gt;在特定计分板“&lt;记分板ID&gt;”上的分数。


那现在好了,如果你连“谁在哪里有没有分”这种问题都不知道了,你可以使用list:

代码:

  1. /scoreboard players list [目标]
本指令会显示&lt;目标&gt;在所有计分板上的分数。
你可以发现[目标]是一个可选元素。所以如果你省略“目标”:

代码:

  1. /scoreboard players list
本指令会列出所有在任意记分板上有分数的实体。
你也可以在“&lt;目标&gt;”中填“*”。
这和不填的效果是一样的,都会列出所有在任意记分板上有分数的实体:

代码:

  1. /scoreboard players list *

运算


最后,让我们看向今天最后一项内容,也是任何编程语言的核心之一: 运算
/scoreboard players operation命令允许你对两个数字作数学或逻辑运算。你可以将一个分数加到另一个分数上,也可以做“取最小值”这样的逻辑运算,是以后数据包等高端内容的核心之一。
格式:

代码:

  1. /scoreboard players operation <目标> <目标计分板ID> <操作> <来源> <来源计分板ID>

解析:
/soreboard players opertaion 指令头&gt;子指令&gt;更下级子指令: 计分板,分数操作,运算
&lt;目标&gt; &lt;目标计分板ID&gt; 被运算的分数,也就是数学说的“被减数”或“被除数”,比如“Dahesor abc” 即为我(Dahesor)在记分板abc上的分数。
&lt;操作&gt; 你要干嘛?要加要减要乘要除?
&lt;来源&gt; &lt;来源计分板ID&gt; 这是来源分数,也就是数学说的“减数”或“除数”,和目标分数是一个写法。


有哪些操作?


目前,你一共有9种不同的选择器:


运算符
运算名称
描述
=
赋值
把目标的分数设为来源的分数。
+=
加法
把来源的分数加到目标分数上。
-=
减法
在目标分数上减去来源的分数。
*=
乘法
将目标分数设为目标分数与来源分数的乘积。
/=
除法
将目标分数设为被来源的分数除后的结果。
%=
求余
将目标分数设为被来源的分数除后得到的余数。
&lt;
取较小值
如果来源分数比目标分数小,则把目标分数设为来源分数。
&gt;
取较大值
取较大值:如果来源分数比目标分数大,则把目标分数设为来源分数。
&gt;&lt;
交换
将来源分数与目标分数交换。



注意,在所有的9种运算中,只有最后一种交换会改变来源分数。

记分板无法存储小数,当使用除法出现小数是会向下取整。


例:

代码:

  1. /scoreboard players operation Dahesor a *= MysticNebula70 b

将Dahesor在a计分板上的分数设定与MysticNebula70在b记分板上的乘积。
若原值:Dahesor a = 3,MysticNebula70 b = 10,
那么结束后:Dahesor a = 30,MysticNebula70 b = 10。


代码:

  1. /scoreboard players operation Dahesor money += @a money

将Dahesor在money计分板上的分数增加所有玩家在money记分板上的分数。
若原值:Dahesor money = 10,玩家1 money = 5,玩家2 money = 15
结果为:Dahesor money = 10+5+15+10=40(Dahesor也是玩家之一,玩家也包含我,所以还要加上自己的分数),玩家1 money = 5,玩家2 money = 15


代码:

  1. /scoreboard players operation @r x >< Dianliang233 y

将一名随机玩家在x计分板上的分数与Dianliang233在y计分板上的分数交换。
若原值:随机玩家 x = 0,Dianliang233 y = 10,
结果为:随机玩家 x = 10,Dianliang233 y = 0。
(Dianliang233是MCWiki“最年轻的编辑者”(那是段很有趣的故事))


再次提醒,“&gt;&lt;”是唯一一个会改变来源分数的运算。


还有一件有趣的事是,这里,你可以使用&quot; * &quot;填在&lt;目标&gt; 或 &lt;来源&gt;(但不能同时)中用以代表 在任意计分板上有分数的实体(包括虚拟分数)
下面的内容可能有些复杂,你可以跳过,几乎不会有影响,下面的东西也很少用到。


让我们举几个带“ * ”的例子。
比如说:

代码:

  1. /scoreboard players operation * x = Dahesor y
将所有在任意计分板上有分数的实体(包括虚拟目标)在x计分板上的分数设为Dahesor在y计分板上的分数。


若原值:
x计分板: a有4分,b有3分。
y计分板: Dahesor有10分。
z计分板: c有500分,d有24分。
那么,运算结束后:
x计分板: a有10分,b有10分,c有10分,d有10分,Dahesor有10分。
y计分板: Dahesor有10分。
z计分板: c有500分,d有24分。


你看,z计分板在指令中完全没有被指令提及,但是,只要在 任意计分板上有分数 ,就会被“*”选中。


例2:

代码:

  1. /scoreboard players operation Dahesor x = * y
这会将Dahesor在x计分板上的分数依次设置为所有在计分板上有分数的对象在y计分板上的分数。


若原值:
x计分板:Dahesor只有0分。
y计分板:a有5分,b有10分。
那么,运算结束后:
y计分板不变,Dahesor在x计分板上的分数——还是0分。
为什么?
因为Dahesor的分数会依次被赋值为“ 所有在任意计分板上有分数的对象在y计分板上的分数 ”。
我们是一个接一个地“赋值”,所以说 哪个分数在最后,Dahesor就会变成哪个分数。


在同一计分板上分数从高到低排列。


谁在y计分板上的分数最低呢?
是Dahesor,分数为0(空的)。
所以,Dahesor在x计分板上的 零蛋 被赋值为Dahesor在y计分板上的 零蛋 ————还是 零蛋


例3:

代码:

  1. /scoreboard players operation Dahesor x *= * y
本指令的含义为,将Dahesor在x计分板上的分数乘以所有“在任意计分板上有分数的对象的分数”。


若原值:
x计分板:
Dahesor有2分。
y计分板:
a有3分,b有8分,Dahesor有5分。
没有其他计分板。
那么,运算后,Dahesor在x计分板上的分数为:

代码:

  1. 2*3*8*5

等于240分。


注意,在本例中,只要要有任意一个对象在y计分板上的分数等于0,那么最后Dahesor的分数都会变成零——因为无论什么数,乘以0都等于0。


以上就是本帖的全部内容了。
......实际上,还有一个子指令enable还没讲到。记得前面跳过的准则“trigger”么?这是和那相关的。本子指令会在以后讲/trigger时详细提到。


结束了呢,开心开心,又可以放假了,回到水论坛和泡Bilibili的时光了。
本帖本来是打算和上一帖一起发布的,但中间遇到了很多麻烦,连本帖都是经历了断网和断电一系列麻烦才发出的。
那,期待后续的就收藏一下好吧......还有我终于快拿到小麦种子勋章了(好感动)。


附录


#更新日志


Java 1.16.5/a页面发布,版本1.16.5
Java 1.16.5/b感谢种拔的提醒,加入了关于除法余数的问题
Java 1.16.5/c前往1.12版本教程的帖子因过久而被锁定,加入了新的链接
Java 1.16.5/d根据 Wiki命令:语法 ,更改了命令语法、
Java 1.16.5/e补充了大量对“*”的说明。


Java 1.17/a 1.17版本升级完成


上一帖: [命令] 有关队伍/team 命令教程“真”从零开始 (四)


系列《命令教程“真”从零开始》
前往来自 麻瓜草稿簿 系列教程索引
【命令】命令教程“真”从零开始 (一) 指令本身,选择器,与命令方块
【命令】命令教程“真”从零开始 (二) 命令tp与相对,局部坐标与朝向锚
【命令】 命令教程“真”从零开始 (三) 四个新手指令
【命令】 命令教程“真”从零开始 (四) 有关队伍命令/team的……差不多一切
【命令】命令教程“真”从零开始 (五) 记分板与/scoreboard
【命令】 命令教程“真”从零开始 (六) /tag指令,与进阶~选择器参数
【命令】命令教程“真”从零开始 (七) 新手指令杂烩2号
【命令】命令教程“真”从零开始 (八) 区块与强制加载命令/forceload
【命令】命令教程“真”从零开始 (九) 调整苦力怕防爆,防喷/gamerule
【命令】命令教程“真”从零开始 (十) 简单,又新手(雾)的方块指令/setblock
【命令】命令教程“真”从零开始 ( X ) 我就不信不能用大白话讲清楚NBT
【命令】命令教程&quot;真&quot;从零开始(十二)数据运算三方法之一修改NBT/data
【命令】命令教程“真”从零开始(十三)给予与替换物品,命令/replaceitem
【命令】命令教程“真”从零开始(十四 ) 修改属性/attribute【一拳打爆末影龙】 【命令】命令教程“真”从零开始(十五)最接近神的一次:填充命令/fill 【命令】命令教程&quot;真&quot;从零开始(十六)复制一片区域:复制命令/clone
下一篇: [命令] /tag指令,与进阶~选择器参数 命令教程“真”从零开始 (六)