#时间规则

#时间规则

# 时间规则 温馨提示:开始阅读这篇指南之前,我们希望你对《我的世界》基岩版附加包有一定了解,有能力撰写 JSON 数据格式,对 Python 进行模组开发有了解,并能够独立阅读《我的世界》开发者官网-开发指南或其他技术引用文档。

本文将带你了解 MC 中的时间的问题,并从零开始带你搭建起一个基础的 UI 来帮助我们了解当前 MC 中的时间情况。

在本教程中,您将学习以下内容。

✅MC 中的时间规则; ✅简单 UI 搭建指南; # MC 中的时间规则 这一部分可以查看 MC 的官方介绍 (opens new window)。

# 时间换算 在我的世界中的时间正好是现实时间中流逝速度的 72 倍。这是因为现实世界中的 1 天有 24 * 60 = 1440 分钟,而在我的世界中,1 个完整的 Minecraft 天只有 20 分钟。1440 / 20 = 72,正好是 72 倍。

如果要进行时间单位的换算的话,那么可以得到下面两个表。

一个表是 Minecraft → 现实时间的换算表:

Minecraft时间 Minecraft 刻 现实时间 1秒 0.27 0.0138秒 1分钟 16.6 0.83秒 1小时 1,000 50秒 1天 24,000 20分钟 1周(7天) 168,000 2.3小时 1个月(30天) 720,000 10小时 1年(365.25 天) 8,766,000 121.75小时(5.072916天 另一个表是现实时间 → Minecraft 时间的换算表:

现实时间 Minecraft时间 1⁄20秒(1游戏刻) 3.6秒 1秒 1分钟12秒(72秒) 10秒 12分钟(720秒) 50秒 1小时(60分,3600秒) 1分钟 1小时12分钟 1小时 3天 1天 2.4个月 = 72天 1周 约1.385年 ≈ 17个月 = 72周 = 504天 1个月 6年 = 72个月 ≈ 308.5周 = 2,160天 1年 72年 ≈ 876.5个月 ≈ 3,757周 ≈ 26,297.5天 # 游戏刻 你可以把游戏想象成一个巨大的机器,它需要不断地运转才能工作。MC 就是这样一个机器。就像时钟里的每个部件都要跟着钟摆的节奏一起动一样,游戏里的每个事情都要跟着游戏的节奏一起发生。我们把游戏的节奏叫做游戏循环,它就像是游戏的心跳。每次心跳,游戏就会更新一下自己的状态,比如玩家的位置,方块的变化,怪物的行动等等。我们把每次心跳的时间叫做一刻(tick),它是游戏的最小时间单位。

游戏的一刻是指 Minecraft 的游戏循环运行一次所占用的时间。正常情况下,游戏固定以每秒钟 20 刻的速率运行,因此一刻的时间为 0.05 秒(50 毫秒,或一秒钟的二十分之一),使得游戏内的一天 (opens new window)刚好持续 24000 刻,也就是 20 分钟。

# 游戏中的时间 有了上面我们对 MC 时间的了解,加上时间刻与现实时间的换算关系,我们就知道了游戏中的一天是如何度过的了。

# 白天

白天是一天周期中最长的一节,历时 10 分钟。

开始:0 刻(早上06:00:00.0)

中午:6000 刻(下午12:00:00.0)

结束:12000 刻(下午06:00:00.0)

# 日落

日落是介于白天和夜晚之间的时间段,持续 1 分半钟。

开始:12000 刻(下午06:00:00.0)

中点:12400 刻(下午06:54:00.0)

结束:13800 刻(下午07:48:00.0)

# 夜晚

夜晚持续 7 分钟。

开始:13800 刻(下午07:48:00.0)

午夜:18000 刻(早上12:00:00.0)

结束:22200 刻(早上04:12:00.0)

晴朗的夜晚时,玩家可以在 12542 刻(下午06:32:31.2)到 23460 刻(早上05:27:36.0)时睡觉。在雨天,玩家可以在 12010 刻(下午06:00:36.0)到 23992 刻(早上05:59:31.2)时睡觉。

# 日出/黎明

日出是介于夜晚和白天之间的时间段,持续 1 分半钟。

开始:22200 刻(早上04:12:00.0)

中点:23100 刻(早上05:06:00.0)

结束:24000(0)刻(早上06:00:00.0)

# 月相 游戏中每过一天,时间计数便会增加 24000 刻。虽然每天的交替是一样的,但月亮 (opens new window)会经历 8 种月相。虽然没有命令直接更改月相,但/time add 24000命令可以快进至下一个月相。进一步而言,使用以下命令可以直接指定不同的月相:

命令 月相 /time set night 满月 /time set 38000 亏凸月 /time set 62000 下弦月 /time set 86000 残月 /time set 110000 新月 /time set 134000 娥眉月 /time set 158000 上弦月 /time set 182000 盈凸月 游戏中月亮的原版贴图,自行对应:

# 昼夜更替 如果开启了命令。我们可以使用 /gamerule doDaylightCycle [*true/false*] 来控制是否开启昼夜更替。

当我们关闭昼夜更替之后,游戏中的时间刻虽然会继续运行,但是数值上不会有所变动了,而是固定在某一刻。

# 时间相关的 API 我们可以在官方的文档 (opens new window)中查看到最新的、与时间相关的 API:

看着这么多,如果不算设置昼夜更替的 API 的话,其实总体就分为了两类:

获取时间类; 设置时间类; 不管是维度的局部时间,还是其他任何时间,都符合上面介绍的时间规则。

# 实操:左上角时钟 UI 显示 接下来我们将带大家实操制作一个 UI,能够实时显示当前维度的时间,效果如下:

# Step1. 新增界面文件 首先,打开我们的 MC Studio,在界面一览选择新建一个「界面文件」:

点击下一步之后命名为「timeDisplayUI」就可以了:

我们的需求很简单,只需要在界面的左上角,使用「文本」控件显示出当前维度的时间就可以了,所以整个界面也十分简单,一个「文本」控件,设置在左上方即可:

把文本大小选择为大,并且把层级设置在 20 层以上(保证在原版的 UI 上方,不会被遮挡),这样方便我们查看。

OK,界面文件就此告成。

# Step2. 注册 UI 注册和创建 UI 需要监听 UiInitFinished 之后执行:

# -*- coding: utf-8 -*-

import mod.client.extraClientApi as clientApi

CompFactory = clientApi.GetEngineCompFactory()

class TimeRuleClientSystem(clientApi.GetClientSystemCls()):

def __init__(self, namespace, name):

super(TimeRuleClientSystem, self).__init__(namespace, name)

self.ListenEvent()

self.mUINode = None

def ListenEvent(self):

self.ListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "UiInitFinished",

self, self.OnUiInitFinished)

def UnListenEVent(self):

self.UnListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "UiInitFinished",

self, self.OnUiInitFinished)

def Destroy(self):

self.UnListenEVent()

def OnUiInitFinished(self, args=None):

# 注册 UI

uiClsPath = 'timeRuleScripts.uIScripts.UIScript'

uiScreenDef = 'timeDisplayUI.main'

clientApi.RegisterUI('timeRuleMod', 'timeDisplayUI', uiClsPath, uiScreenDef)

# 创建 UI

self.mUINode = clientApi.CreateUI('timeRuleMod', 'timeDisplayUI', {"isHud": 1})

if self.mUINode:

self.mUINode.Init() # 调用初始化函数

# Step3. UI 代码 UI 代码也非常简单,也就两个功能:1)每秒更新 label 的文字;2)把游戏时间转换成与现实世界对应的时间。

完整代码如下:

# -*- coding: utf-8 -*-

import mod.client.extraClientApi as clientApi

ScreenNode = clientApi.GetScreenNodeCls()

CompFactory = clientApi.GetEngineCompFactory()

gameComp = CompFactory.CreateGame(clientApi.GetLevelId())

class UIScript(ScreenNode):

def __init__(self, namespace, name, param):

ScreenNode.__init__(self, namespace, name, param)

self.mPlayerId = clientApi.GetLocalPlayerId()

# 组件注册地址

self.mLabelPath = '/label'

# 界面需要使用的自定义属性

self.mTimeCounter = 0

def Create(self):

print("===== UI Create =====")

# 1 秒 30 帧

def Update(self):

self.mTimeCounter += 1

perSec = self.mTimeCounter % 30 == 0

if perSec:

self.UpdateLabelContent()

# region 类函数

# --------------------------------------------------------------------------------------------

def Init(self):

print '=== UI 初始化 ==='

self.UpdateLabelContent()

def UpdateLabelContent(self):

timeComp = CompFactory.CreateTime(clientApi.GetLevelId())

pressedTime = timeComp.GetTime()

timeStr = self.GameTime2RealTime(pressedTime)

self.GetLabel(self.mLabelPath).SetText(timeStr)

def GameTime2RealTime(self, gameTick):

# 定义游戏中一天的刻数

gameDayTicks = 24000

# 定义游戏中一小时的刻数

gameHourTicks = gameDayTicks / 24

# 定义游戏中一分钟的刻数

gameMinuteTicks = gameHourTicks / 60

# 计算游戏中的天数

gameDay = gameTick // gameDayTicks + 1

# 计算游戏中的小时数

gameHour = (gameTick % gameDayTicks) // gameHourTicks

# 计算游戏中的分钟数

gameMinute = (gameTick % gameHourTicks) // gameMinuteTicks

# 把游戏中的小时数转换成现实中的小时数,加上6小时的偏移量

realHour = (gameHour + 6) % 24

# 把现实中的小时数、分钟数转换成字符串,补齐两位

realHourStr = str(realHour).zfill(2)

realMinuteStr = str(gameMinute).zfill(2)

# 返回转换后的格式

return "第{}天第{}时第{}分".format(gameDay, realHourStr, realMinuteStr)

def GetLabel(self, path):

control = self.GetBaseUIControl(path)

if control:

return control.asLabel()

return None

# endregion

# Step4. 测试并验证 我们可以尝试使用 /time set xxx 命令来设置当前的时间,来验证 UI 代码的正确性。比如 /time set 0 界面会正确显示上面规则介绍的 06:00:00 这个时间:

至此,UI 就完成了。

# 课后作业 本次课后作业,内容如下:

给模组左上角新增一个当前时间显示的 UI; 熟悉并测试时间相关的 API;

相关推荐

《芈月传》片头曲、插曲、片尾曲谁唱的?
best365彩票

《芈月传》片头曲、插曲、片尾曲谁唱的?

📅 07-26 👁️ 4609
SINoALICE下载
365官网登录网址

SINoALICE下载

📅 07-25 👁️ 7593
平民魍魉玩法,副本及战场
365官网登录网址

平民魍魉玩法,副本及战场

📅 11-10 👁️ 9674