教程:记分板

教程:记分板

本文章所述内容仅适用于Java版。

此教程已确认至少适用于Java版1.21.5。

请帮助我们检查该内容是否仍在最新版本有效。

目录

1 基础

1.1 记分项和分数持有者

1.1.1 创建记分项

1.1.2 显示记分项分数

1.1.3 修改显示

1.1.4 虚拟玩家

1.1.5 重置分数

1.1.6 清空侧边栏

1.1.7 移除记分项

1.2 基本整数运算

1.3 取最值

1.4 以分数为条件

1.5 trigger准则

2 进阶

2.1 浮点数处理

2.2 伪数组

2.3 存储命令输出

3 实例

3.1 血量显示

3.2 侧边栏公告

3.3 排行榜

4 导航

本教程主要包含了记分板命令在Java版中的基本用法和常见使用细节。

基础[编辑 | 编辑源代码]

记分项和分数持有者[编辑 | 编辑源代码]

在记分板系统中,记分项是用来管理一系列分数的基本单位。所有对记分项进行操作的命令都以scoreboard objectives开头。

分数持有者可以是一个玩家或者其他实体,也可能是一个抽象的对象(虚拟玩家)。所有对分数持有者进行操作的命令都以scoreboard players开头。

每个记分项都可以关联若干分数持有者。

创建记分项[编辑 | 编辑源代码]

创建一个test记分项,指定其准则为dummy,这将确保它几乎只能通过记分板命令来修改。

scoreboard objectives add test dummy

列出当前世界的所有记分项,其中也应当包含你刚才创建的记分项:

scoreboard objectives list

显示记分项分数[编辑 | 编辑源代码]

将test记分项显示在侧边栏sidebar:

scoreboard objectives setdisplay sidebar test

侧边栏默认所有玩家可见。当前还没有命令允许直接设置到左侧,也不能针对某个玩家单独显示或隐藏。

默认情况下你可能看不到任何分数,这是因为记分项中目前还没有关联到的分数持有者。对于没有关联记分项的玩家,执行/scoreboard players get会输出:

无法获取%2$s的%1$s的值,其尚未被赋值

我们可以使用players set来指定记分项要关联到的分数持有者。以下命令让test记分项中的分数关联到执行者,并且设置分数为100。如果你在聊天栏执行,这就是在设置你自己的分数。

scoreboard players set @s test 100

然后,你可以通过add或remove来加减分数:

# 加100分

scoreboard players add @s test 100

# 减100分

scoreboard players remove @s test 100

当然,你也可以通过这些命令来初始化——它们默认将分数视作0,然后再进行加或减。

修改显示[编辑 | 编辑源代码]

记分项显示名称和持有者的显示名称、分数均为文本组件

记分项还存在一个显示名称。

修改test记分项的显示名称为233:

scoreboard objectives modify test displayname {"text":"233", "color":"aqua"}

记分项名称是一个文本组件,这意味着你还可以显示引用的分数。如下,这将设置记分项显示名称为执行者在test记分项中的分数。

scoreboard objectives modify test displayname {"score":{"name":"@s", "objective":"test"}}

注意

实际上,{"score":{"name":"@s", "objective":"test"}}会在命令执行时被预解析为静态文本组件。例如,若执行者在test中的分数为123,则将被预解析为{"text", "123"}。若需要让分数实时变化则需要高频执行以更新预解析的静态文本组件。

你也可以修改分数持有者的显示名。修改执行者在test记分项中的显示名为(-V-):

scoreboard players display name @s test {"text":"(-V-)","color":"green"}

你也可以修改分数的显示。以下命令执行后,执行者在test记分项中的分数将显示为(-V-):

scoreboard players display numberformat @s test fixed {"text":"(-V-)","color":"green"}

虚拟玩家[编辑 | 编辑源代码]

侧边栏可显示多个分数以及持有者名称,分数会按照上大下小的顺序自动排序

记分项所关联的分数持有者可能并不是一个真实存在的玩家或其他实体。比如这里直接将分数持有者A关联到test记分项,A可被称为一个虚拟玩家。

scoreboard objectives set A test 1

在侧边栏中,以#开头的虚拟玩家将不会显示。

重置分数[编辑 | 编辑源代码]

重置执行者在test记分项中的分数:

scoreboard players reset @s test

注意,这会直接解除分数持有者与记分项的关联。相应的,若一个生物死亡,其关联的分数也将从记分项中清除。

通配符*可代表记分项中的所有分数持有者。以下命令将清除test记分项中的所有分数持有者:

scoreboard players reset * test

清空侧边栏[编辑 | 编辑源代码]

将侧边栏还原回初始状态:

scoreboard objectives setdisplay sidebar

移除记分项[编辑 | 编辑源代码]

移除test记分项,并清理相关联的分数持有者:

scoreboard objectives remove test

基本整数运算[编辑 | 编辑源代码]

/scoreboard players operation类命令一般是先进行运算,然后再将运算结果存储在第一个分数持有者中。

给定A在test记分项中的分数为1,虚拟玩家B在test记分项中的分数为2,则以下命令执行后A在test记分项中的分数将变为3,而B保持不变:

scoreboard players operation A test += B test

以下是一段类python的伪代码:

a = 2

b = 3

a = a + 10

a = a + b

c = a + b

我们可以用以下命令实现:

scoreboard objectives add var dummy

# 设置常量

scoreboard players set #10 var 10

# a = 2

scoreboard players set a var 2

# b = 3

scoreboard players set b var 3

# a = a + 10

scoreboard players operation a var += #10 var

# a = a + b

scoreboard players operation a var += b var

# c = a + b

scoreboard players operation c var += a var

scoreboard players operation c var += b var

对于更复杂的运算式:

res = (a + b) / (c - d)

可借助中间虚拟玩家来实现:

scoreboard objectives add var dummy

# #temp1 = a + b

scoreboard players operation #temp1 var = a var

scoreboard players operation #temp1 var += b var

# #temp2 = c - d

scoreboard players operation #temp2 var = c var

scoreboard players operation #temp2 var -= d var

# res = #temp1 / #temp2

scoreboard players operation res var = #temp1 var

scoreboard players operation res var /= #temp2 var

取最值[编辑 | 编辑源代码]

找到var记分项中所有玩家的最小值:

scoreboard players operation #min var < @a var

取最大值同理。

以分数为条件[编辑 | 编辑源代码]

通过execute

若虚拟玩家#temp在var记分项中的分数非负则执行say 1:

execute if score #temp var matches 0.. run say 1

若虚拟玩家#temp1在var记分项中的分数大于等于虚拟玩家#temp2在test记分项中的分数则执行say 1:

execute if score #temp1 var >= #temp2 test run say 1

若分数不存在,则无论为何值都将检测失败。因此,可以利用这一点检测玩家在test记分项中的分数是否存在。以下命令当且仅当分数存在时检测成功:

# 方法一:利用分数的取值范围

execute if score @s test matches -2147483648..

# 方法二:检测分数是否与自身相等

execute if score @s test = @s test

通过选择器

若执行者在test记分项中的分数大于等于20,且其在var记分项中的分数等于1,则执行say 1:

execute as @s[scores={test=20..,var=1}] run say 1

通过谓词

通过谓词value_check检查执行者在test记分项中的分数是否介于1到2之间:

execute if predicate {condition:"minecraft:value_check",value:{type:"minecraft:score",target:"this",score:"test"},range:{min:0,max:2}}

由于value_check会将未初始化的分数视作0,所以无法用来检测分数存在性。

如果你希望检测某实体的分数存在性,可考虑使用entity_scores:

# 语义:若执行者实体在test记分项中的分数存在时,则...

execute if predicate {condition:"entity_scores", entity:"this", scores:{test:{}}}

当然,前提是目标必须为可定位到的实体。如果你的检测目标是一个虚拟玩家,则只能通过execute if score ...来检测分数存在性。

trigger准则[编辑 | 编辑源代码]

在多人游戏中,无权限玩家可以通过/trigger改变其在trigger准则记分项中的分数。

创建trigger准则记分项tr:

scoreboard objectives add tr trigger

指定能够使用/trigger命令触发一次的玩家(这里为所有玩家,若目标玩家的分数不存在,则会自动初始化为0):

scoreboard players enable @a tr

对于reset,其不仅能将目标从指定记分项中清除,其还可用来剥夺所选玩家的触发能力:

scoreboard players reset @a tr

所有拥有触发能力的玩家能够执行一次trigger,然后他的触发能力将自动复原:

trigger tr set 1

大多数时候,我们希望玩家在触发后立即重置分数并重新给予触发能力:

execute if score @s tr matches 1 run function example:tr

example:trmcfunction

# 这里为其他要执行的命令

say trigger!

scoreboard players reset @s tr

scoreboard players enable @s tr

进阶[编辑 | 编辑源代码]

浮点数处理[编辑 | 编辑源代码]

这段python伪代码又该如何实现?

a = 1.23

b = 1000.1

c = a + b

当前,Minecraft原版的记分板还无法存储浮点数。那么如何代表浮点数?我们只能用整数来表示,所以需要放大并固定要表示的小数位数:

scoreboard objectives add var dummy

scoreboard players set #10 var 10

# 默认将所有整数当做小数点后有2位的浮点数,即123 => 1.23

scoreboard players set a var 123

# 此时10001 => 100.01,为了对齐小数位,需要将10001乘以10 => 100010 => 1000.10

scoreboard players set b var 10001

scoreboard players operation b var *= #10 var

# c = a + b

scoreboard players operation c var += a var

scoreboard players operation c var += b var

# 最后,将其转存为NBT以应用真浮点数,这里的倍数为1.0,你还可以修改为其他倍数

execute store result storage wiki:test temp double 1.0 run scoreboard players get c var

伪数组[编辑 | 编辑源代码]

这是一个数组:

d = [1, 2, 3]

我们可以用3个分数持有者来模拟:

scoreboard players set wiki.array.0 var 1

scoreboard players set wiki.array.1 var 2

scoreboard players set wiki.array.2 var 3

然后再单独通过另一个函数实现索引返回分数:

# 确保索引已经初始化

scoreboard players add wiki.array.idx var 0

execute if score wiki.array.idx matches 0 run return run scoreboard players get wiki.array.0 var

execute if score wiki.array.idx matches 1 run return run scoreboard players get wiki.array.1 var

execute if score wiki.array.idx matches 2 run return run scoreboard players get wiki.array.2 var

存储命令输出[编辑 | 编辑源代码]

对于每条命令,都可能有相应的输出值。你可以使用execute store sccuess来存储输出的成功值(仅为0或1),或者使用execute store result来存储输出的结果值(根据命令效果而定)。

每条命令都有相应的输出章节。比如,查看命令/attribute § 输出,你可以用以下命令来验证:

# 这会将执行者的方块交互距离存储到其test记分项中

execute store result score @s test run attribute @s minecraft:block_interaction_range base get 100

这里扩大100倍是为了截取到小数点后2位数

注意

当以1000倍率存储2147483.647以上的值时会导致整数溢出——正数会变为负数。对于绝对值很大的负数也会发生溢出。

更常见的应用是存储NBT数据并进行运算:

# 获取最近一只猪的移动速度向量,这里#x #y #z表示一个三元伪数组,分别依次存储Motion的3个分量(截取到小数点后3位)

execute store result score #x var run data get entity @n[type=pig] Motion[0] 1000

execute store result score #y var run data get entity @n[type=pig] Motion[1] 1000

execute store result score #z var run data get entity @n[type=pig] Motion[2] 1000

# 将获取到的Motion[1]值乘以0.5 => 乘以5再除以10

scoreboard players set #frac1 var 5

scoreboard players set #frac2 var 10

scoreboard players operation #y var *= #frac1 var

scoreboard players operation #y var /= #frac2 var

# 转回NBT数据,此时应将记分板数据缩小1000倍

execute store result entity @n[type=pig] Motion[0] double 0.001 run scoreboard players get #x var

execute store result entity @n[type=pig] Motion[1] double 0.001 run scoreboard players get #y var

execute store result entity @n[type=pig] Motion[2] double 0.001 run scoreboard players get #z var

实例[编辑 | 编辑源代码]

血量显示[编辑 | 编辑源代码]

下图列出了当前可定义的所有显示位置,并让血量记分项health在每个位置显示:

图示效果的命令如下:

scoreboard objectives add health health {"text":"❤","color":"red"}

scoreboard objectives setdisplay below_name health

scoreboard objectives setdisplay list health

scoreboard objectives modify health rendertype hearts

scoreboard objectives setdisplay sidebar health

注意,该记分项使用health准则,所以无法修改分数。

侧边栏公告[编辑 | 编辑源代码]

创建一个info记分项并显示在侧边栏:

scoreboard objectives add info dummy

scoreboard objectives modify info displayname {"text":"公告", "color":"yellow", "bold":true}

scoreboard objectives setdisplay sidebar info

修改数字格式为blank,以消除数字显示。然后添加4个虚拟玩家,分别用来充当公告的4行。最后通过/scoreboard players display name来设置这些虚拟玩家的显示名:

scoreboard players set info4 info 4

scoreboard players set info3 info 3

scoreboard players set info2 info 2

scoreboard players set info1 info 1

scoreboard objectives modify info numberformat blank

scoreboard players display name info4 info ""

scoreboard players display name info3 info [{"text":" 欢迎来到 ","color":"green"}]

scoreboard players display name info2 info [{"text":" Minecraft Wiki! ", "color":"green", "font":"minecraft:uniform"}]

scoreboard players display name info1 info ""

公告

欢迎来到

Minecraft Wiki!

排行榜[编辑 | 编辑源代码]

初始化记分项rank用于记录排名:

scoreboard objectives add rank dummy

scoreboard players set #cur rank 1

我们按照test记分项的分数来从大到小排序,输出的序号即rank中的分数。用@e[type=minecraft:armor_stand,distance=..6]代表每个待排序的玩家:

execute as @e[type=minecraft:armor_stand,distance=..6] run function test:sort_descending/0

# 重置标记和分数,以便下次排序

tag @e[type=minecraft:armor_stand,distance=..6] remove ranked

scoreboard players set #cur rank 1

test:sort_descending/0mcfunction

# 获取剩余待排序玩家中的最大分数

scoreboard players operation #max test > @e[type=minecraft:armor_stand,distance=..6,tag=!ranked] test

# 找到和当前待排序玩家中最小分数相等的所有玩家,设置其排名

execute as @e[type=minecraft:armor_stand,distance=..6,tag=!ranked] if score @s test = #max test run function test:sort_descending/1

test:sort_descending/1mcfunction

scoreboard players operation @s rank = #cur rank

# 每循环一次,设置的排名+1

scoreboard players add #cur rank 1

# 将该玩家从剩余待排序玩家中剔除

tag @s add ranked

执行完成后,每个分数持有者在rank中的分数即其排名(可能出现并列某个排名)。此方法仅针对非虚拟玩家的分数持有者。对于虚拟玩家,需要通过伪数组来模拟数组排序,或将其分数赋给其他非虚拟玩家的分数持有者进行处理。

导航[编辑 | 编辑源代码]

编教程

新手教程

下载、安装与购买

成功地启动游戏

菜单屏幕

游戏术语

计量单位

不该做的事

新手生存

新手指南

第一天

第二天

第三天

提示与技巧

饥饿管理

生存注意事项

庇护所

庇护所

沙漠

微型

最佳居住生物群系

最佳建筑材料

建筑与结构

房屋类型

导航

综合

无聊的时候做什么

跑酷

空置域

伪和平

节省时间的小窍门

在水下利用TNT破坏方块

成就指南[仅BE]

进度指南[仅JE]

Minecraft

下界

末地

冒险

农牧业

最佳附魔指南

拓殖

战斗

完成冒险

双持

探索洞穴

利用碰撞箱

使用地图

测量距离和角度

采矿技术

钻石

化石

远古残骸

下界快速旅行

下界传送门

支柱跳跃

幻翼防护

生成骑士

穿越和破坏基岩

防卫僵尸围城[仅JE]

考古

不可破坏的末地水晶

使用更少的末地水晶重生末影龙

区块加载器

透视镜

挂机池

整理物品

潜影盒储存

物品运输

生物运输

自动化烧炼

选择燃料

爆炸室

凋灵笼

光速船[仅BE]

无材料消耗转换药水类型[仅BE]

在超平坦世界中管理史莱姆

减少摔落伤害

Minecraft和教育

视频

游戏直播

村民和交易

村庄生存

创建村庄

村庄机制

治愈僵尸村民

村民养殖

村民交易所

流浪商人陷阱

建筑

给工程添加美感

空气闸

建筑术语

建造游轮

建造大都市

建造过山车

建造安全的家园

建造水建筑

建造几何体

防御

家具

电梯

带釉陶瓦的图案

建造地板

像素艺术

牧场

屋顶类型

弧形屋顶

屋顶建造指南

暗门

建造居住地

水下建筑

墙壁和桥墩

水闸

调色板

建造蹦床

挑战

获得潮涌核心

触发及战胜袭击

打败末影龙

打败凋灵

挑战自定义地图

制作自定义地图

征服结构

征服神殿和神庙

征服掠夺者前哨站

征服堡垒遗迹

征服林地府邸

征服海底神殿

征服试炼密室

征服下界要塞

征服末地城

探索深暗之域和远古城市

特殊玩法

冒险模式生存

极限模式

超极限模式

在一个地区中长期生存下去

沙漠生存

在无限沙漠中生存

下界生存

从零开始下界生存

末地生存

雷暴生存

超平坦世界生存[仅JE]

岛屿生存

空岛生存

在和平难度中收集资源

速通

游荡生存

无限石头生存

愚人节版本生存[仅JE]

22w13oneBlockAtATime

24w14potato

农场

方块和物品

紫水晶

骨粉

仙人掌

农作物(小麦、胡萝卜、马铃薯、甜菜根、火把花和瓶子草)

西瓜、南瓜

紫颂果

圆石、石头或玄武岩

可可豆

泥土

滴水石锥

鸡蛋

花朵

蛙明灯

蜂蜜

海带

熔岩

蘑菇

音乐唱片

下界疣

黑曜石

袭击农场

1.21前

海泡菜

甘蔗

甜浆果

原木、树苗和苹果

海龟鳞甲

藤蔓

羊毛

药水

经验

基岩

方块和物品复制

过时方法

铁轨复制机[仅JE]

TNT复制[仅JE]

零刻作物催熟技术[仅BE]

生物

刷怪塔

怪物磨床

刷怪笼陷阱

动物(猪、牛、绵羊)

烈焰人

洞穴蜘蛛

苦力怕

闪电苦力怕

溺尸

末影人

山羊

守卫者

铁傀儡

岩浆怪

以物易物

潜影贝

史莱姆

鱿鱼

海龟

村民

女巫

流浪商人

凋灵骷髅

僵尸猪灵

悦灵

疣猪兽

红石

基础红石

基本逻辑门

高频电路

计时器

抽奖箱

漏斗

通用物品分类器

机械

侦测器稳定器

密码锁

随机发生器

红石机械

红石音乐

红石技巧

鲁布·戈德堡机械

探测器

方块更新感应器

比较器更新感应器

昼夜探测器

矿车

矿车

火车站

储存

数字化存储系统

陷阱

陷阱

陷阱设计

雪傀儡防御炮

TNT大炮

活板门利用

活塞

活塞使用

活塞电路

无延迟科技

飞行器

半连接性[仅JE]

零刻活塞[仅JE]

无头活塞[仅JE]

高级红石

光照操纵

高级红石电路

算术逻辑

计算器

时钟

摩尔斯码

打印机

红石计算机

红石电报机

多人游戏

玩法

游玩服务器

PvP

Java版1.9前、基岩版

基地

隐藏箱子

起床战争

空岛战争

猎人游戏

密室杀手

服务器管理

防止恶意破坏

服务器监狱

服务器商店

雪球菜单

架设服务器

架设Java版服务器

架设基岩版服务器

服务器架设脚本[仅JE]

服务器启动脚本

FreeBSD启动脚本

OpenBSD启动脚本

Ubuntu启动脚本

WebSocket服务器[仅BE]

架设Mod服务器[仅JE]

架设Hamachi服务器

架设Spigot服务器

虚拟硬盘服务器

使用ngrok搭建服务器

架设ZeroTier服务器

本地局域网联机

服务器维护

使用LeviLamina架设服务器[仅BE]

技术性

Minecraft帮助FAQ

自定义皮肤

地图

自定义地图

下载地图

使用MCEdit刷新旧区块[仅JE]

强制打开存档[仅JE]

降级存档

资源包

制作资源包

纹理

音效和音乐

语言和文本

模型

加载资源包

数据包[仅JE]

制作数据包

实例:射线投射

视线魔法

自定义物品

安装数据包

自定义世界生成

自定义结构生成

自定义盔甲纹饰

附加包[仅BE]

基岩版开发指南

制作资源附加包

高级

基岩版实体文档

修改实体模型

制作行为包

自定义实体

自定义方块

自定义物品

自定义附加包语言文件

自定义音效

命令格式

仅Java版

生成下落的方块

文本组件

NBT命令标签

物品堆叠组件

记分板

SNBT

命令方块

结构方块

用命令操控实体

NBT与JSON

自定义命令触发

目标选择器

游戏安装

仅Java版

提高帧率

更新Java

修复Apache Log4j2漏洞

编写启动器

快照版本安装

获取崩溃报告

查看游戏日志

仅基岩版

Minecraft URL Scheme

汇报漏洞

在U盘中使用旧版启动器运行游戏

恢复损坏的地图数据

修复因数据包损坏的世界

在Google Drive上运行游戏

将游戏数据保存到Dropbox云端

仅限地图数据

在ChromeOS上运行Java版

过时教程

到达边境之地

获取崩溃报告(旧版)

无数据包生存

升级LWJGL

更新Minecraft

命令统计值

村民养殖(村庄与掠夺前)

村庄链

水道

水车

仅英文

自定义纹理包

基于门的铁傀儡陷阱

人工湖

矿车加速器

中继器重启系统

水梯

无延迟电路

教程

新手手册

高难度通关配装总结

成就指南

高塔指南

常见问题

教程

新手手册

基地建设指南

资源收集指南

单位阵容组合

注:作下划线标记的教程为中文原创教程。