饥荒Mod 开发(十三):木牌传送

news2025/1/13 13:56:59

饥荒Mod 开发(十二):一键制作
饥荒Mod 开发(十四):制作屏幕弹窗

一键传送源码
饥荒的地图很大,跑地图太耗费时间和饥饿值,如果大部分时间都在跑图真的是很无聊,所以需要有一个能够传送的功能,不仅可以快速到达还能节省饥饿值。
饥荒二本之后可以制作出木牌,我们可以在地图各个位置创建木牌,右键点击木牌就可以传送到其他的木牌

1 功能演示

1.1 创建木牌

需要先升级到一本,制作一个科学机器,这样就可以制作木牌了。
在这里插入图片描述

1.2 右键传送

将鼠标放到木牌上, 会显示 “传送”, 右键单击会显示一个传送面板
在这里插入图片描述

1.3 传送面板

这个面板会列出所有的木牌,可以修改木牌的名字, 也可以直接点击 “传送” 就可以不消耗饥饿值 瞬间移动到了目的地
在这里插入图片描述
接下来介绍如何实现 传送功能

2 实现鼠标悬浮显示 “传送”

要和饥荒中的物品“交互”,可以自定义一个Action,这样鼠标右键悬浮的时候会显示一个自定义的“操作提示”,右键单击的时候可以执行指定的操作。那如何自定义一个action?

2.1 创建action

在Mod 根目录下创建一个 travel.lua文件,这个文件用来定义action在这里插入图片描述

-- 创建一个新的动作(Action),这个动作可以通过右键触发,优先级为10
local TRAVEL = GLOBAL.Action({}, 10, false, true)
TRAVEL.id = "TRAVEL"  -- 设置动作的ID为"TRAVEL"
TRAVEL.str = "传送"  -- 设置动作的字符串表示为"传送"
TRAVEL.fn = function(act)  -- 设置动作的函数,这个函数定义了动作的行为
    local tar = act.target  -- 目标实体
    local traveller = act.doer  -- 执行动作的实体
    --traveller说一句话
    traveller.components.talker:Say("传送中...")
 	return true  -- 先全部返回true看看效果 动作成功
end

-- 将新的动作添加到游戏中
AddAction(TRAVEL)
-- 为"wilson"状态图添加新的动作处理器,当执行"TRAVEL"动作时,使用"give"动画
AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(TRAVEL, "give"))

创建完这个action之后,我们把鼠标移动到物品上时,却没有任何的变化,我们还需要让具体的物品支持这个动作。

2.2 仅让木牌显示“传送”,自定义 “Travelable”组件

传送功能只能发生在木牌上,所以我们需要给“木牌”增加一个组件,让鼠标悬浮在木牌上的时候显示一个自定义的提示“传送”。在 scripts/components 目录下新建 travelable.lua
在这里插入图片描述

-- 定义 Travelable 类
local Travelable = Class(function(self, inst)
    -- 初始化实例
    self.inst = inst
    -- 设置名称
    self.name = "木牌"
end)

-- 定义收集场景动作的方法
function Travelable:CollectSceneActions(doer, actions, right)
    -- 如果是右键操作,则添加 TRAVEL 动作
    if right then
        table.insert(actions, ACTIONS.TRAVEL)
    end
end

-- 定义保存状态的方法
function Travelable:OnSave()
    -- 创建一个表来存储数据
    local data = {}
    -- 保存名称
    data.name = self.name
    -- 返回保存的数据
    return data
end   

-- 定义加载状态的方法
function Travelable:OnLoad(data)
    -- 如果有数据,则加载名称
    if data then
        self.name = data.name
    end
end

-- 定义执行旅行的方法
function Travelable:DoTravel(traveller)
    -- 如果没有旅行者,则返回
    if not traveller then
        return
    end
    -- 如果旅行者已经死亡,则返回
    if traveller.components.health and traveller.components.health:IsDead() then
        return
    end
    -- 获取当前实例的世界位置
    local x, y, z = self.inst.Transform:GetWorldPosition()
    -- 设置旅行者的位置
    traveller.Transform:SetPosition(x-1, y, z)
end

-- 返回 Travelable 类
return Travelable

2.3 木牌添加 自定义组件 “Travelable”

在modmain.lua 文件中导入 travel.lua,然后拦截 木牌的 构造,添加自定义组件,这样将鼠标移动到木牌上就会显示传送按钮了。

modimport("travel.lua")

AddPrefabPostInit("homesign", function(inst)
    inst:AddComponent("travelable")
end)

2.4 进入游戏测试是否显示 “传送”

打开调试控制台, 输入c_spawn(“homesign”)可以创建一个木牌,将鼠标悬浮到木牌上将会出现 “传送” 提示
在这里插入图片描述
右键点击之后会显示“传送中”
在这里插入图片描述

3 制作传送面板

在scripts 目录下创建 widgets 目录,然后创建travelitem.lua,travelscreen.lua
在这里插入图片描述

3.1 travelitem 实现

每个 travelitem 都表示一个 传送点

--  travelitem.lua
local UIAnim = require "widgets/uianim"
local Widget = require "widgets/widget"
local Text = require "widgets/text"
local TextEdit = require "widgets/textedit"
local Image = require "widgets/image"
local ImageButton = require "widgets/imagebutton"

local TravelItem = Class(Widget, function(self, homesign, isCurrent, traveller, screen)
    Widget._ctor(self, "TravelItem") -- 构造函数,创建一个名为"TravelItem"的小部件
    self.homesign = homesign -- 将homesign赋值给self.homesign
    self.traveller = traveller -- 将traveller赋值给self.traveller
    self.screen = screen -- 将screen赋值给self.screen
    --添加一个背景
    self.bg = self:AddChild(UIAnim()) -- 在self上添加一个UIAnim
    self.bg:GetAnimState():SetBuild("savetile") -- 设置UIAnim的Build为"savetile"
    self.bg:GetAnimState():SetBank("savetile") -- 设置UIAnim的Bank为"savetile"
    self.bg:GetAnimState():PlayAnimation("anim") -- 播放UIAnim的"anim"动画
    self.bg:SetScale(1, 0.8, 1) -- 设置UIAnim的缩放比例

    self.name = self.bg:AddChild(TextEdit(BODYTEXTFONT, 35)) -- 在bg上添加一个TextEdit
    self.name:SetVAlign(ANCHOR_MIDDLE) -- 设置TextEdit的垂直对齐方式为中间
    self.name:SetHAlign(ANCHOR_LEFT) -- 设置TextEdit的水平对齐方式为左边
    self.name:SetPosition(0, 10, 0) -- 设置TextEdit的位置
    self.name:SetRegionSize(300, 40) -- 设置TextEdit的区域大小

    self.name:SetString(homesign.components.travelable.name) -- 设置TextEdit的内容为homesign.components.travelable.name
    if isCurrent then -- 如果是当前的
        self.name:SetColour(0, 1, 0, 0.4) -- 设置TextEdit的颜色
    else
         --添加一个传送按钮
        self.go = self.bg:AddChild(ImageButton("images/ui.xml", "button_small.tex", "button_small_over.tex", "button_small_disabled.tex")) -- 在bg上添加一个ImageButton
        self.go:SetPosition(220, 0) -- 设置ImageButton的位置
        self.go:SetText("传送") -- 设置ImageButton的文本为"传送"
        self.go:SetFont(BUTTONFONT) -- 设置ImageButton的字体
        self.go:SetOnClick(function() -- 设置ImageButton的点击事件
            self:Go()
        end)
    end

    --添加一个编辑按钮
    self.button = self.bg:AddChild(ImageButton("images/ui.xml", "button_small.tex", "button_small_over.tex", "button_small_disabled.tex")) -- 在bg上添加一个ImageButton
    self.button:SetPosition(-220, 0) -- 设置ImageButton的位置
    self.button:SetText("编辑") -- 设置ImageButton的文本为"编辑"
    self.button:SetFont(BUTTONFONT) -- 设置ImageButton的字体
    self.button:SetOnClick(function() -- 设置ImageButton的点击事件
        self:Edit()
    end)
end)

function TravelItem:Edit() 
    local text = self.name:GetLineEditString() -- 获取name的文本内容
    --如果文本和原来的不一样
    if text ~= self.homesign.components.travelable.name then -- 如果文本内容和self.homesign.components.travelable.name不一样
        self.homesign.components.travelable.name = text -- 将self.homesign.components.travelable.name设置为新的文本内容
    end
end

function TravelItem:Go()
    self.homesign.components.travelable:DoTravel(self.traveller) -- 调用self.homesign.components.travelable的DoTravel方法,参数为self.traveller
    self.screen:OnCancel() -- 调用self.screen的OnCancel方法
end

return TravelItem

在这里插入图片描述

--   travelscreen.lua

local Screen = require "widgets/screen"
local Widget = require "widgets/widget"
local Menu = require "widgets/menu"
local Text = require "widgets/text"
local Image = require "widgets/image"
local ImageButton = require "widgets/imagebutton"
local TravelItem = require "widgets/travelitem"

local TravelScreen = Class(Screen, function(self, homesign, traveller)
    Screen._ctor(self, "TravelScreen") -- 构造函数,创建一个名为"TravelScreen"的屏幕
    self.homesign = homesign -- 将homesign赋值给self.homesign
    self.traveller = traveller -- 将traveller赋值给self.traveller
    SetPause(true, "TravelScreen") -- 暂停游戏

    -- 创建一个背景
    self.root = self:AddChild(Widget("ROOT")) -- 添加一个名为"ROOT"的小部件
    self.root:SetVAnchor(ANCHOR_MIDDLE) -- 设置垂直锚点为中间
    self.root:SetHAnchor(ANCHOR_MIDDLE) -- 设置水平锚点为中间
    self.root:SetScaleMode(SCALEMODE_PROPORTIONAL) -- 设置缩放模式为等比例

    -- 添加一个背景
    self.bg = self.root:AddChild(Image("images/globalpanels.xml", "panel.tex")) -- 在root上添加一个图像
    self.bg:SetSize(500, 650) -- 设置图像的大小
    self.bg:SetPosition(0, 25) -- 设置图像的位置

    -- 添加一个当前标题
    self.current = self.root:AddChild(Text(BODYTEXTFONT, 35)) -- 在root上添加一个文本
    self.current:SetPosition(0, 225, 0) -- 设置文本的位置
    self.current:SetRegionSize(350, 50) -- 设置文本区域的大小
    self.current:SetHAlign(ANCHOR_MIDDLE) -- 设置文本的水平对齐方式为中间
    self.current:SetString(self.homesign.components.travelable.name) -- 设置文本的内容为self.homesign.components.travelable.name

    -- 添加一个菜单,用来显示修改和取消按钮
    self.menu = self.root:AddChild(Menu(nil, 200, true)) -- 在root上添加一个菜单
    self.menu:SetScale(0.6) -- 设置菜单的缩放比例
    self.menu:SetPosition(0, -225, 0) -- 设置菜单的位置
    self.cancelbutton = self.menu:AddItem("关闭", function() -- 在菜单上添加一个名为"关闭"的项,点击后执行self:OnCancel()函数
        self:OnCancel()
    end)


    -- 添加两个按钮,用于翻页
    self.upbutton = self.root:AddChild(ImageButton("images/ui.xml", "scroll_arrow.tex", "scroll_arrow_over.tex", "scroll_arrow_disabled.tex")) -- 在root上添加一个向上的按钮
    self.upbutton:SetPosition(180, 200, 0) -- 设置向上按钮的位置
    self.upbutton:SetRotation(-90) -- 设置向上按钮的旋转角度
    self.upbutton:SetScale(0.5) -- 设置向上按钮的缩放比例
    self.upbutton:SetOnClick(
        function()
            self:ScrollUp() -- 当点击向上按钮时,执行ScrollUp函数
        end
    )

    self.downbutton = self.root:AddChild(ImageButton("images/ui.xml", "scroll_arrow.tex", "scroll_arrow_over.tex", "scroll_arrow_disabled.tex")) -- 在root上添加一个向下的按钮
    self.downbutton:SetPosition(180, -200, 0) -- 设置向下按钮的位置
    self.downbutton:SetRotation(90) -- 设置向下按钮的旋转角度
    self.downbutton:SetScale(0.5) -- 设置向下按钮的缩放比例
    self.downbutton:SetOnClick(
        function()
            self:ScrollDown() -- 当点击向下按钮时,执行ScrollDown函数
        end
    )

    self.menu:SetHRegPoint(ANCHOR_MIDDLE) -- 设置菜单的水平注册点为中间
    self.travelitems = self.root:AddChild(Widget("ROOT")) -- 在root上添加一个名为"ROOT"的小部件,用于显示项目
    self.travelitems:SetPosition(-100, 0) -- 设置项目的位置
    self.travelitems:SetScale(0.8) -- 设置项目的缩放比例
    self.currentRow = 1 -- 设置当前行为1
    self:LoadTravelItems(self.currentRow) -- 加载第一行
end)


function TravelScreen:ScrollUp()
    if self.currentRow >= 5 then -- 如果当前行大于等于5
        self.currentRow = self.currentRow - 5 -- 当前行减5
        self:LoadTravelItems(self.currentRow) -- 加载新的当前行的项目
    end
end

function TravelScreen:ScrollDown()
    if self.currentRow <= #Pigpet.homesigns - 5 then -- 如果当前行小于等于Pigpet.homesigns的数量减5
        self.currentRow = self.currentRow + 5 -- 当前行加5
        self:LoadTravelItems(self.currentRow) -- 加载新的当前行的项目
    end
end


function TravelScreen:LoadTravelItems(index)
    self.travelitems:KillAllChildren() -- 删除travelitems的所有子项
    --从 index 开始遍历, 只显示5个
    local num_items = 0 -- 初始化项目数量为0
    for i = index, #Pigpet.homesigns do -- 从index开始遍历Pigpet.homesigns
        if num_items >= 5 then -- 如果项目数量大于等于5,就跳出循环
            break
        end
        local v = Pigpet.homesigns[i] -- 获取Pigpet.homesigns的第i个元素
        local isCurrent = v == self.homesign -- 判断v是否等于self.homesign
        local item = self.travelitems:AddChild(TravelItem(v, isCurrent, self.traveller, self)) -- 在travelitems上添加一个TravelItem
        item:SetPosition(120, 200 - num_items * 100, 0) -- 设置TravelItem的位置
        num_items = num_items + 1 -- 项目数量加1
    end
end

function TravelScreen:OnCancel()
    SetPause(false) -- 取消暂停
    TheFrontEnd:PopScreen(self) -- 弹出当前屏幕
end

return TravelScreen

在这里插入图片描述

4 添加传送功能

4.1 处理右键点击函数

当右键点击 木牌的时候,我们需要打开一个面板,显示所有可以传送的地方,并且每个传送点后面都会有一个“传送”按钮。我们将 travel.lua代码稍微改动下。当右键点击的时候,会调用 travelable 组件的OnSelect 函数

-- 创建一个新的动作(Action),这个动作可以通过右键触发,优先级为10
local TRAVEL = GLOBAL.Action({}, 10, false, true)
TRAVEL.id = "TRAVEL"  -- 设置动作的ID为"TRAVEL"
TRAVEL.str = "传送"  -- 设置动作的字符串表示为"传送"
TRAVEL.fn = function(act)  -- 设置动作的函数,这个函数定义了动作的行为
    local tar = act.target  -- 目标实体
    local traveller = act.doer  -- 执行动作的实体
    if tar and tar.components.travelable and traveller then  -- 如果目标实体存在,且具有travelable组件,且执行动作的实体存在
        tar:DoTaskInTime(
            .2,  -- 在0.2秒后
            function()
                tar.components.travelable:OnSelect(traveller)  -- 调用目标实体的travelable组件的OnSelect方法,传入执行动作的实体
            end
        )
        return true  -- 动作成功
    end
 	return true  -- 先全部返回true看看效果 动作成功
end

-- 将新的动作添加到游戏中
AddAction(TRAVEL)
-- 为"wilson"状态图添加新的动作处理器,当执行"TRAVEL"动作时,使用"give"动画
AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(TRAVEL, "give"))

4.2 打开传送面板

实现 travelable 组件的OnSelect 函数,在这个函数中,我们会打开一个全屏的面板,展示所有的可传送点

local TravelScreen = require "widgets/travelscreen"
function Travelable:OnRemoveEntity()
    --从 homesigns 表中移除
    for k, v in pairs(Pigpet.homesigns) do
        if v == self.inst then
            table.remove(Pigpet.homesigns, k)
            break
        end
    end
end

function Travelable:OnSelect(traveller)
	if not traveller then
		return
	end
    if traveller.components.health and traveller.components.health:IsDead() then
        return
    end
    --打开选择地点页面
    TheFrontEnd:PushScreen(TravelScreen(self.inst, traveller))
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一种解决Qt5发布release文件引发的无法定位程序输入点错误的方法

目录 本地环境问题描述分析解决方案 本地环境 本文将不会解释如何利用Qt5编译生成release类型的可执行文件以及如何利用windeployqt生成可执行的依赖库&#xff0c;请自行百度。 环境值操作系统Windows 10 专业版&#xff08;22H2&#xff09;Qt版本Qt 5.15.2Qt Creator版本5.0…

数字滤波器设计——Matlab实现数字信号处理<1>

目录 一.实验内容 二.代码分析 1.信号产生部分 2.利用傅立叶级数展开的方法&#xff0c;自由生成所需的x(t) 3.通过选择不同的采样间隔T&#xff08;分别选T>或<1/2fc&#xff09;&#xff0c;从x(t)获得相应的x(n) 3.对获得的不同x(n)分别作傅立叶变换&#xff0c…

[elementPlus] teleported 在 ElSubMenu中的用途

如图 一个菜单对应的路由结构如上图 如果做适配窄屏幕 如果在 <ElSubMenu :index"route.path" >中不加入 teleported 就会出现问题 加上就OK了 <ElSubMenu :index"route.path" teleported>

git 切换远程地址分支 推送到指定地址分支 版本回退

切换远程地址 1、切换远程仓库地址&#xff1a; 方式一&#xff1a;修改远程仓库地址 【git remote set-url origin URL】 更换远程仓库地址&#xff0c;URL为新地址。 git remote set-url https://gitee.com/xxss/omj_gateway.git 方式二&#xff1a;先删除远程仓库地址&…

前端对接 —— 周末

1.点击校验 点击校验 宇哥 记得过滤 不能校验的数据&#xff08;我后端还要检验吗&#xff1f;&#xff09; 2.前端数据对接 这个可以吗&#xff1f; 这种的可以吗&#xff1f;

基于多智能体系统一致性算法的电力系统分布式经济调度策略MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 参考文献&#xff1a; 主要内容&#xff1a; 应用多智能体系统中的一致性算法&#xff0c;以发电机组的增量成本和柔性负荷的增量效益作为一致性变量&#xff0c;设计一种用于电力系统经济调度的算法&#x…

力扣第 375 场周赛 解题报告 | 珂学家 | 区间合并+组合数学

前言 整体评价 难得的手速场&#xff0c;这几题都比较套路&#xff0c;确实区间合并很久没考察到了。 不过T4有多种解&#xff0c;栈模拟/差分/链式并查集&#xff0c;都可以的。 欢迎star gitee github T1. 统计已测试设备 思路: 差分思维 class Solution {public int co…

持续集成交付CICD:基于 GitLabCI 与 JenkinsCD 实现后端项目发布

目录 一、实验 1. GitLabCI环境设置 2.优化GitLabCI共享库代码 3.JenkinsCD 发布后端项目 4.再次优化GitLabCI共享库代码 5.JenkinsCD 再次发布后端项目 一、实验 1. GitLabCI环境设置 &#xff08;1&#xff09;GitLab给后端项目添加CI配置路径 &#xff08;2&#xf…

CPU告警不用愁,用C语言编写CPU使用率限制程序

现在云服务已经深入千家万户了&#xff0c;不仅商用&#xff0c;私用也很多。很多云服务厂商也都有配套的服务器安全模块&#xff0c;可以检测网络流量异常、内存占用量和CPU占用率&#xff0c;并且允许人工设置告警阈值。例如&#xff0c;CPU持续大于90%10分钟&#xff0c;那么…

LLM大语言模型(二):Streamlit 无需前端经验也能画web页面

目录 问题 Streamlit是什么&#xff1f; 怎样用Streamlit画一个LLM的web页面呢&#xff1f; 文本输出 页面布局 滑动条 按钮 对话框 输入框 总结 问题 假如你是一位后端开发&#xff0c;没有任何的web开发经验&#xff0c;那如何去实现一个LLM的对话交互页面呢&…

学生管理系统--课程设计项目(Java+SQL server)

本科参与项目文档合集: 点击跳转~ 学生管理系统 Student Management System 学校&#xff1a;山东科技大学 指导老师&#xff1a;杨 * * 教授 学号&#xff1a;2019032**** 学生姓名&#xff1a;安** 专业班级&#xff1a;计算机19-1 山东科技大学 二〇二〇年七月 项目文档目录…

eNSP小实验--实现全网互通

目录 一、建立以下拓扑图&#xff0c;并实现全网互通 二、分析 1、接入层交换机SW4、SW5划分vlan 2、汇聚层交换机SW2,SW3配置ip作为vlan网关&#xff0c;与SW1直连 3、核心交换机SW1配置ip 与汇聚层交换机和R1直连 4、SW1,SW2,SW3,R1配置静态路由&#xff0c;使得vlan10,…

京东体育用品销售数据分析与可视化系统

京东体育用品销售数据分析与可视化系统 前言数据爬取模块1. 数据爬取2. 数据处理3. 数据存储 数据可视化模块1. 数据查看2. 店铺商品数量排行3. 整体好评率4. 不同品牌市场占比5. 品牌差评率排名6. 品牌价格排名7. 品牌评论数量分布 创新点 前言 在体育用品行业&#xff0c;了…

IDEA卡顿,进行性能优化设置(亲测有效)——情况一

需求场景 IDEA重新激活后&#xff0c;运行IDEA卡的非常卡顿&#xff0c;没有运行项目&#xff0c;CPU占比也非常高: 原因分析 可能的原因是&#xff0c;在IDEA的配置中&#xff0c;给他分配的空间比较小 解决方式 步骤一 选择顶部导航栏中的Help&#xff0c;然后点击Edi…

小项目:迷宫二

目录 引言一、题目描述二、解题思路三、代码实现四、测试 引言 这个迷宫项目是今天参加学校的一个比赛出的题目&#xff0c;从早上九点基本搞到了四五点才完成&#xff0c;其实写出来发现基本思路其实挺简单的&#xff0c;就是想不好想&#xff0c;真的要各种的尝试&#xff0…

【数据分析之Numpy】Numpy中复制函数numpy.repeat()与numpy.tile()的使用方法及区别

一、简介 numpy.repeat()与numpy.tile()都是Numpy库中的复制函数&#xff0c;用于将数组中的元素重复指定的次数。 numpy.repeat()函数接受三个参数&#xff1a;要重复的数组、重复的次数和重复的轴。 numpy.tile()函数接受两个参数&#xff1a;要重复的数组和重复的次数。 二…

C语言学习第二十六天(算法的时间复杂度和空间复杂度)

1、算法效率 衡量一个算法的好坏&#xff0c;是从时间和空间两个方面来衡量的&#xff0c;换句话说就是从时间复杂度和空间复杂度来衡量的 这里需要补充一点&#xff1a;时间复杂度是衡量一个算法的运行快慢&#xff0c;空间复杂度是主要衡量一个算法运行所需要的额外空间。 …

面试 Java 算法高频题五问五答第一期

面试 Java 算法高频题五问五答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;括号生成: 数字 n 代表生成括号的对数&#xff0c;请你设计一个…

neuq-acm预备队训练week 10 P1129 [ZJOI2007] 矩阵游戏

题目描述 小 Q 是一个非常聪明的孩子&#xff0c;除了国际象棋&#xff0c;他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个 nn 黑白方阵进行&#xff08;如同国际象棋一般&#xff0c;只是颜色是随意的&#xff09;。每次可以对该矩阵进行两种操作&#xff1a; 行…