Appearance
收集组件
前言
收集组件是一个用于收集交互场景的组件,它包含收集按钮、收集进度条、结果弹窗等元素。通过在橙光剧情中呼叫一个 LmCode(代码模式)制作的收集组件,实现收集交互场景。 完成数值在橙光剧情和 LmCode(代码模式)之间的流动。
文档和模块效果示意

流程说明
text
【收集按钮】→【进度条动画】→【生成随机数量】→【收集结果弹窗】→【返回上一层】传入参数说明
| 参数 | 类型 | 用途 | 默认 |
|---|---|---|---|
params[0] | int | 进度条动画时长(秒) | - |
params[1] | int | 随机数下限 | - |
params[2] | int | 随机数上限 | - |
params[3] | int | 按钮/进度条 X坐标 | 居中 |
params[4] | int | 按钮/进度条 Y坐标 | 居中 |
params[5] | str | 按钮文本 | "收集按钮" |
params[6] | str | 物品名称 | "收集物品名称" |
开始教程
1. 新建工程
使用橙光编辑器新建一个工程。
2. 转换编辑器到高级模式
点击 工具 > 转为高级模式 
3. 使用呼叫scene
点击 逻辑 > 呼叫Scene 
4. 开启脚本
- 勾选Script 弹出弹窗即将开启脚本模式
- 点击确认 开启脚本模式

5. 新增呼叫scene事件
确认新增呼叫Scene事件后就为工程添加了 LmCode(代码模式)功能啦 
6. 打开工程
想要使用 LmCode(代码模式)写代码,首先需要找到 LmCode(代码模式)文件。
点击工程 > 打开工程文件夹

找到 LmCode(代码模式)文件夹,这就是 LmCode(代码模式)整个功能所在,将其拖入到我们的代码编辑器中

8. 新增收集场景
- 我们将图片素材放入到
assets/Graphics文件夹中,使用的图片都放在这个文件夹下 - 在
src目录下新建一个CollectScene,并在文件中添加初始化代码。所有的代码都在src目录下编写。
typescript
//注册类名
@LM.Class("CollectScene")
export class CollectScene extends LM.Scene {
// 初始化方法
init(): void {
}
}
我们终于可以正式开始制作收集组件功能啦!
实现收集场景
步骤1: 实现收集按钮
typescript
collectBtn:LM.Button
// 初始化收集按钮
initCollectBtn() {
// 创建收集按钮
this.collectBtn = new LM.Button()
// 给按钮设置图片
this.collectBtn.src = "Graphics/教学采集界面素材/按钮底图.webp";
//有传入参数时使用传入参数默默认值为收集按钮
this.collectBtn.text = this.params[5] || "收集按钮"
// 设置按钮颜色为白色
this.collectBtn.fontColor = "#ffffff"
// 设置按钮字体大小
this.collectBtn.fontSize = 50;
//文本竖向居中
this.collectBtn.alignVertical = LM.ALIGN_VERTICAL.MIDDLE
//文本横向居中
this.collectBtn.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER
//传入参数4有值时使用传入参数,没值时使用默认场景内居中,(舞台宽度-按钮宽度)/2
this.collectBtn.x = Number(this.params[3]) || (ENGINE_CONFIG.stageW - this.collectBtn.width) / 2;
//传入参数5有值时使用传入参数,没值时使用默认场景内居中,(舞台高度-按钮高度)/2
this.collectBtn.y = Number(this.params[4]) || (ENGINE_CONFIG.stageH - this.collectBtn.height) / 2;
//添加到场景内
this.addChild(this.collectBtn);
//生成按钮时默认隐藏,在初始化结尾将统一做显示
this.collectBtn.visible = false;
}在场景中声明collectBtn, 并实现初始化方法initCollectBtn 。在初始化中,我们为收集按钮添加背景图片,文本。并且让设置按钮相对场景居中。
步骤2: 实现收集进度条
typescript
collectProgressBar:LM.ProgressBar
// 初始化进度条方法
initCollectProgressBar() {
// 创建进度条
this.collectProgressBar = new LM.ProgressBar();
// 给进度条设置背景底图
this.collectProgressBar.background = "Graphics/教学采集界面素材/进度条-2底图.webp";
// 给进度条设置前景
this.collectProgressBar.progress = "Graphics/教学采集界面素材/进度条-1填充图.webp"
// 进度条当前值
this.collectProgressBar.current = 0.5;
// 默认场景内居中
this.collectProgressBar.x = Number(this.params[3]) || (ENGINE_CONFIG.stageW - this.collectProgressBar.width) / 2
// 默认场景内居中
this.collectProgressBar.y = Number(this.params[4]) || (ENGINE_CONFIG.stageH - this.collectProgressBar.height) / 2;
// 把进度条添加到场景上
this.addChild(this.collectProgressBar)
// 进度条初始化的时候直接隐藏,等初始化完毕后统一操作
this.collectProgressBar.visible = false;
}在场景中声明collectProgressBar, 并实现初始化方法initCollectProgressBar 。在初始化中,我们为进度条添加背景底图,前景填充图。并且让设置进度条相对场景居中。并且先将进度条隐藏。
步骤3: 实现收集结果弹窗
typescript
collectResultAlert:LM.Container
// 初始化结果弹窗方法
initCollectResultAlert(collectNum: number) {
// 创建弹窗容器
this.collectResultAlert = new LM.Container();
// 弹窗背景
const alertBg = new LM.ImgView();
// 给弹窗背景图片设置素材
alertBg.src = "Graphics/教学采集界面素材/获得弹窗-底图.webp";
// 背景添加到弹窗上
this.collectResultAlert.addChild(alertBg);
// 物品名称
const collectGoodsName = new LM.TextView();
// 物品名称
collectGoodsName.text = this.params[6] || "收集物品名称";
// 物品名称字体大小
collectGoodsName.fontSize = 50;
// 物品名称字体颜色 黑色
collectGoodsName.fontColor = "#000000";
// 物品名称x坐标与背景图片坐标一致 后续设置宽度一致,直接剧中 比较省事
collectGoodsName.x = alertBg.x;
// 设置物品y坐标
collectGoodsName.y = 100;
// 物品宽度设置与背景图片宽度一致 便于剧中
collectGoodsName.width = alertBg.width;
// 设置文本居中
collectGoodsName.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER;
// 物品名称添加到弹窗上
this.collectResultAlert.addChild(collectGoodsName);
// 收集物品数量文本
const collectGoodsNum = new LM.TextView();
// 收集物品数量文本内容 X 加上 收集的数量, 默认是99
collectGoodsNum.text = "X " + (collectNum || 99);
// 收集物品数量文本字体大小
collectGoodsNum.fontSize = 50;
// 收集物品数量文本字体颜色 黑色
collectGoodsNum.fontColor = "#000000";
// 收集物品数量文本x坐标与背景图片坐标一致 后续设置宽度一致,直接剧中 比较省事
collectGoodsNum.x = alertBg.x;
// 收集物品数量文本的y坐标
collectGoodsNum.y = 180;
// 收集物品数量文本宽度与背景图片宽度一致 便于剧中
collectGoodsNum.width = alertBg.width;
// 收集物品数量文本居中
collectGoodsNum.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER
// 收集物品数量文本添加到弹窗上
this.collectResultAlert.addChild(collectGoodsNum);
// 创建确认按钮
const sureBtn = new LM.Button();
// 确认按钮设置素材
sureBtn.src = "Graphics/教学采集界面素材/获得弹窗-对号按钮.webp";
// 确认按钮坐标要相对于弹窗背景居中,所以使用弹窗背景x + (弹窗背景宽度 - 确认按钮宽度) / 2
sureBtn.x = alertBg.x + (alertBg.width - sureBtn.width) / 2
// 确认按钮 要在弹窗背景下,所以使用弹窗背景y+弹窗背景高度
sureBtn.y = alertBg.y + alertBg.height;
// 确认按钮添加到弹窗上
this.collectResultAlert.addChild(sureBtn);
// 弹窗相对整个场景横向居中
this.collectResultAlert.x = (ENGINE_CONFIG.stageW - this.collectResultAlert.width) / 2;
// 弹窗相对整个场景纵向居中
this.collectResultAlert.y = (ENGINE_CONFIG.stageH - this.collectResultAlert.height) / 2;
// 弹窗添加到场景上
this.addChild(this.collectResultAlert)
// 给确认按钮添加点击事件
sureBtn.onClick(() => {
// 传出参数1 也就是第0位 设置为手机数量
this.result[0] = collectNum;
// 关闭当前场景 并将传出参数传出
this.close(this.result)
// 关闭所有场景 回到上一级,这里回到剧情
LM.killAllScenesToParent();
})
}初始化弹窗方法中,收集数量作为传入参数。在结果弹窗中,我们创建弹窗容器,添加背景图片,物品名称文本,物品数量文本,确认按钮。将弹窗设置居中,并且设置确认按钮点击事件,点击后关闭当前场景,传出参数,关闭所有场景,回到上一级剧情。
步骤4:完成初始化方法
typescript
init() {
//初始化收集按钮
this.initCollectBtn();
//初始化收集进度条
this.initCollectProgressBar();
// 第一个界面内只有这个按钮可见
this.collectBtn.visible = true;
}在初始化方法中,我们调用收集按钮初始化方法,收集进度条初始化方法。并将收集按钮设置为可见。
步骤5: 完成收集按钮点击后流程
typescript
//为按钮添加点击事件,点击后显示第二个画面,展示进度条
this.collectBtn.onClick(() => {
// 收集按钮隐藏
this.collectBtn.visible = false;
// 进度条显示
this.collectProgressBar.visible = true;
// 进度条进度设置成0
this.collectProgressBar.current = 0;
// 给进度条设置动画
LM.Tween.get(this.collectProgressBar)
// 进度条上的属性从当前值到目标值
.to({
current: 1 // 进度条当前值从0-1
}, Number(this.params[0]) * 1000) // 进度条动画时间 params[0] 是秒,动画时间是ms,所以乘了1000
.wait(100) // 等待100毫秒
.call(() => { // 上面的动画和等待完之后 执行这个传入的方法 到第三个画面
// 隐藏进度条
this.collectProgressBar.visible = false;
//通过api生成一个随机数
const collectNum = LM.getRandom(Number(this.params[1]), Number(this.params[2]));
// 初始化收集弹窗
this.initCollectResultAlert(collectNum);
})
})收集按钮点击后,收集进度条显示,进度条进度从0-1动画,等待100毫秒后,生成收集数量的随机数,隐藏进度条,显示结果弹窗,结果弹窗内显示物品名称,获得物品数量。
完整代码
至此我们完成了整个收集组件
typescript
//注册类名
@LM.Class("CollectScene")
export class CollectScene extends LM.Scene {
//收集按钮
collectBtn: LM.Button;
//收集进度条
collectProgressBar: LM.ProgressBar;
//收集弹窗
collectResultAlert: LM.Container;
//传出数组
result: [number] = [0];
// 初始化方法
init(): void {
//初始化收集按钮
this.initCollectBtn();
//初始化收集进度条
this.initCollectProgressBar();
// 第一个界面内只有这个按钮可见
this.collectBtn.visible = true;
}
// 初始化收集按钮
initCollectBtn() {
// 创建收集按钮
this.collectBtn = new LM.Button()
// 给按钮设置图片
this.collectBtn.src = "Graphics/教学采集界面素材/按钮底图.webp";
//有传入参数时使用传入参数默默认值为收集按钮
this.collectBtn.text = this.params[5] || "收集按钮"
// 设置按钮颜色为白色
this.collectBtn.fontColor = "#ffffff"
// 设置按钮字体大小
this.collectBtn.fontSize = 50;
//文本竖向居中
this.collectBtn.alignVertical = LM.ALIGN_VERTICAL.MIDDLE
//文本横向居中
this.collectBtn.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER
//传入参数4有值时使用传入参数,没值时使用默认场景内居中,(舞台宽度-按钮宽度)/2
this.collectBtn.x = Number(this.params[3]) || (ENGINE_CONFIG.stageW - this.collectBtn.width) / 2;
//传入参数5有值时使用传入参数,没值时使用默认场景内居中,(舞台高度-按钮高度)/2
this.collectBtn.y = Number(this.params[4]) || (ENGINE_CONFIG.stageH - this.collectBtn.height) / 2;
//添加到场景内
this.addChild(this.collectBtn);
//为按钮添加点击事件,点击后显示第二个画面,展示进度条
this.collectBtn.onClick(() => {
// 收集按钮隐藏
this.collectBtn.visible = false;
// 进度条显示
this.collectProgressBar.visible = true;
// 进度条进度设置成0
this.collectProgressBar.current = 0;
// 给进度条设置动画
LM.Tween.get(this.collectProgressBar)
// 进度条上的属性从当前值到目标值
.to({
current: 1 // 进度条当前值从0-1
}, Number(this.params[0]) * 1000) // 进度条动画时间 params[0] 是秒,动画时间是ms,所以乘了1000
.wait(100) // 等待100毫秒
.call(() => { // 上面的动画和等待完之后 执行这个传入的方法 到第三个画面
// 隐藏进度条
this.collectProgressBar.visible = false;
//通过api生成一个随机数
const collectNum = LM.getRandom(Number(this.params[1]), Number(this.params[2]));
// 初始化收集弹窗
this.initCollectResultAlert(collectNum);
})
})
//生成按钮时默认隐藏,在初始化结尾将统一做显示
this.collectBtn.visible = false;
}
// 初始化进度条方法
initCollectProgressBar() {
// 创建进度条
this.collectProgressBar = new LM.ProgressBar();
// 给进度条设置背景底图
this.collectProgressBar.background = "Graphics/教学采集界面素材/进度条-2底图.webp";
// 给进度条设置前景
this.collectProgressBar.progress = "Graphics/教学采集界面素材/进度条-1填充图.webp"
// 进度条当前值
this.collectProgressBar.current = 0.5;
// 默认场景内居中
this.collectProgressBar.x = Number(this.params[3]) || (ENGINE_CONFIG.stageW - this.collectProgressBar.width) / 2
// 默认场景内居中
this.collectProgressBar.y = Number(this.params[4]) || (ENGINE_CONFIG.stageH - this.collectProgressBar.height) / 2;
// 把进度条添加到场景上
this.addChild(this.collectProgressBar)
// 进度条初始化的时候直接隐藏,等初始化完毕后统一操作
this.collectProgressBar.visible = false;
}
// 初始化结果弹窗方法
initCollectResultAlert(collectNum: number) {
// 创建弹窗容器
this.collectResultAlert = new LM.Container();
// 弹窗背景
const alertBg = new LM.ImgView();
// 给弹窗背景图片设置素材
alertBg.src = "Graphics/教学采集界面素材/获得弹窗-底图.webp";
// 背景添加到弹窗上
this.collectResultAlert.addChild(alertBg);
// 物品名称
const collectGoodsName = new LM.TextView();
// 物品名称
collectGoodsName.text = this.params[6] || "收集物品名称";
// 物品名称字体大小
collectGoodsName.fontSize = 50;
// 物品名称字体颜色 黑色
collectGoodsName.fontColor = "#000000";
// 物品名称x坐标与背景图片坐标一致 后续设置宽度一致,直接剧中 比较省事
collectGoodsName.x = alertBg.x;
// 设置物品y坐标
collectGoodsName.y = 100;
// 物品宽度设置与背景图片宽度一致 便于剧中
collectGoodsName.width = alertBg.width;
// 设置文本居中
collectGoodsName.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER;
// 物品名称添加到弹窗上
this.collectResultAlert.addChild(collectGoodsName);
// 收集物品数量文本
const collectGoodsNum = new LM.TextView();
// 收集物品数量文本内容 X 加上 收集的数量, 默认是99
collectGoodsNum.text = "X " + (collectNum || 99);
// 收集物品数量文本字体大小
collectGoodsNum.fontSize = 50;
// 收集物品数量文本字体颜色 黑色
collectGoodsNum.fontColor = "#000000";
// 收集物品数量文本x坐标与背景图片坐标一致 后续设置宽度一致,直接剧中 比较省事
collectGoodsNum.x = alertBg.x;
// 收集物品数量文本的y坐标
collectGoodsNum.y = 180;
// 收集物品数量文本宽度与背景图片宽度一致 便于剧中
collectGoodsNum.width = alertBg.width;
// 收集物品数量文本居中
collectGoodsNum.alignHorizontal = LM.ALIGN_HORIZONTAL.CENTER
// 收集物品数量文本添加到弹窗上
this.collectResultAlert.addChild(collectGoodsNum);
// 创建确认按钮
const sureBtn = new LM.Button();
// 确认按钮设置素材
sureBtn.src = "Graphics/教学采集界面素材/获得弹窗-对号按钮.webp";
// 确认按钮坐标要相对于弹窗背景居中,所以使用弹窗背景x + (弹窗背景宽度 - 确认按钮宽度) / 2
sureBtn.x = alertBg.x + (alertBg.width - sureBtn.width) / 2
// 确认按钮 要在弹窗背景下,所以使用弹窗背景y+弹窗背景高度
sureBtn.y = alertBg.y + alertBg.height;
// 确认按钮添加到弹窗上
this.collectResultAlert.addChild(sureBtn);
// 弹窗相对整个场景横向居中
this.collectResultAlert.x = (ENGINE_CONFIG.stageW - this.collectResultAlert.width) / 2;
// 弹窗相对整个场景纵向居中
this.collectResultAlert.y = (ENGINE_CONFIG.stageH - this.collectResultAlert.height) / 2;
// 弹窗添加到场景上
this.addChild(this.collectResultAlert)
// 给确认按钮添加点击事件
sureBtn.onClick(() => {
// 传出参数1 也就是第0位 设置为手机数量
this.result[0] = collectNum;
// 关闭当前场景 并将传出参数传出
this.close(this.result)
// 关闭所有场景 回到上一级,这里回到剧情
LM.killAllScenesToParent();
})
}
}剧情内使用 LmCode(代码模式)制作的scene
接下来我们将制作好的CollectScene接入到剧情中
选择收集场景
- 双击剧情内的呼叫Scene事件
- 点击Scene选择下拉框,选择
CollectScene

添加传入参数
- 我们按传入参数的顺序 类型,点击新增传入参数 查看传入参数
- 依次点击传入参数输入框,输入内容
| 传入参数名 | 类型 | 值 | 说明 |
|---|---|---|---|
传入参数1params[0] | int | 2 | 进度条动画时长(秒) |
传入参数2params[1] | int | 10 | 随机数下限 |
传入参数3params[2] | int | 20 | 随机数上限 |
传入参数4params[3] | int | 0 | 进度条x坐标 |
传入参数5params[4] | int | 0 | 进度条y坐标 |
传入参数6params[5] | str | 收集物品 | 按钮文本 |
传入参数7params[6] | str | 折耳根 | 物品名称 |

添加传出参数
- 点击传出参数
- 按传出参数类型添加一个传出参数
- 点击传出参数选择按钮 会弹出数值弹窗

选择传出数值
- 选择
数值001 - 我们可以为
数值001进行更名,改成采集物品数量。便于后续使用 - 点击确认按钮,将数值添加到传出参数。

再次点击确认,将我们对传入传出的修改应用到呼叫Scene事件

剧情内使用文本显示采集结果
添加一个文本,显示采集物品的数量,点击 消息 > 显示文本 > 输入显示内容 + 显示数值

进行测试
点击测试 开始测试收集组件

下载学习附件
完整示例工程会比较大,我将代码模式的主要内容进行压缩。压缩包内有两个文件夹
assets对应{工程目录}/Data/LmCode/assets,src对应{工程目录}/Data/LmCode/src。
先为作品添加代码模式,有了代码模式的目录后,将assets与src文件夹覆盖到对应目录即可。记得使用npm run build编译代码哦~
结语
使用 LmCode(代码模式) 进行制作,有一定门槛,如果您在使用过程中遇到问题,欢迎加入我们的交流群,我们会尽力帮助您解决问题。
qq群:877600870