前端打字机效果如何实现?一行一行展示内容 一行内容里面的文字又是一个一个展示的或者一段一段展示的 一行里面的元素不固定 可能文本 可能特效
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-03-27 10:20:12 |
👁️ 阅读: 10
要实现打字机效果,一行一行展示内容,并且每行内的文字可以逐个或分段显示,同时支持混合文本和特效元素,可以参考以下方案:
```lua
-- 创建父节点
local parent = GUI:Win_Create("TypewriterMain", 0, 0, 0, 0, false, false, true, false, false, false, 1)
-- 打字机效果控制器
local TypewriterEffect = {
lines = {}, -- 存储所有行的数据
currentLineIndex = 0, -- 当前显示的行索引
currentCharIndex = 0, -- 当前显示的字符索引
lineHeight = 30, -- 行高
startX = 100, -- 起始X坐标
startY = 500, -- 起始Y坐标
lineSpacing = 10, -- 行间距
isPlaying = false, -- 是否正在播放
timer = nil -- 定时器
}
-- 初始化一行内容
function TypewriterEffect:addLine(elements)
-- elements格式示例:
-- {
-- {type = "text", content = "你好", speed = 0.1},
-- {type = "sfx", id = 1001, speed = 0.5},
-- {type = "text", content = "世界", speed = 0.1}
-- }
table.insert(self.lines, elements)
end
-- 创建文本元素
function TypewriterEffect:createTextElement(content, color)
local text = GUI:Text_Create(parent, "text_" .. os.time(), 0, 0, 20, color or "#ffffff", "")
GUI:setVisible(text, false)
return {
widget = text,
content = content,
type = "text"
}
end
-- 创建特效元素
function TypewriterEffect:createSFXElement(sfxID)
local layout = GUI:Layout_Create(parent, "sfx_" .. sfxID, 0, 0, 35, 35)
GUI:setVisible(layout, false)
-- 这里可以加载特效,根据浮生梦老师前端课程内容,特效加载需要具体实现
return {
widget = layout,
id = sfxID,
type = "sfx"
}
}
-- 显示下一行
function TypewriterEffect:showNextLine()
if self.currentLineIndex >= #self.lines then
self:stop()
return
end
self.currentLineIndex = self.currentLineIndex + 1
self.currentCharIndex = 0
local lineData = self.lines[self.currentLineIndex]
local lineY = self.startY - (self.currentLineIndex - 1) * (self.lineHeight + self.lineSpacing)
-- 创建行容器
local lineContainer = GUI:Layout_Create(parent, "line_" .. self.currentLineIndex,
self.startX, lineY, 0, self.lineHeight)
GUI:setVisible(lineContainer, true)
-- 开始播放这一行
self:playLine(lineData, lineContainer)
end
-- 播放一行内容
function TypewriterEffect:playLine(lineData, container)
local totalElements = #lineData
local currentElementIndex = 0
local currentX = 0
local function showNextElement()
currentElementIndex = currentElementIndex + 1
if currentElementIndex > totalElements then
-- 这一行播放完成
SL:ScheduleOnce(function()
self:showNextLine()
end, 0.5) -- 行间隔0.5秒
return
end
local elementData = lineData[currentElementIndex]
if elementData.type == "text" then
-- 播放文本打字效果
self:playTextTyping(elementData.content, elementData.speed or 0.1,
currentX, container, function(finalWidth)
currentX = currentX + finalWidth + 5 -- 文本间距
showNextElement()
end)
elseif elementData.type == "sfx" then
-- 播放特效
self:playSFX(elementData.id, elementData.speed or 0.5,
currentX, container, function(finalWidth)
currentX = currentX + finalWidth + 5 -- 特效间距
showNextElement()
end)
end
end
showNextElement()
end
-- 播放文本打字效果
function TypewriterEffect:playTextTyping(text, speed, startX, container, callback)
local textWidget = GUI:Text_Create(container, "typing_text", startX, 0, 20, "#ffffff", "")
GUI:setVisible(textWidget, true)
local currentIndex = 0
local fullText = text
local timer
local function typeNextChar()
currentIndex = currentIndex + 1
if currentIndex > #fullText then
-- 打字完成
if timer then
timer = nil
end
local textSize = GUI:getContentSize(textWidget)
callback(textSize.width)
return
end
local displayText = string.sub(fullText, 1, currentIndex)
GUI:Text_setString(textWidget, displayText)
-- 继续下一个字符
timer = SL:ScheduleOnce(typeNextChar, speed)
end
typeNextChar()
end
-- 播放特效(示例函数)
function TypewriterEffect:playSFX(sfxID, duration, startX, container, callback)
-- 创建特效布局
local sfxLayout = GUI:Layout_Create(container, "sfx_" .. sfxID, startX, 0, 50, 50)
GUI:setVisible(sfxLayout, true)
-- 这里可以根据sfxID加载不同的特效
-- GUI:Layout_setBackGroundImage(sfxLayout, "特效图片路径")
-- 特效播放完成后回调
SL:ScheduleOnce(function()
callback(50) -- 特效宽度50
end, duration)
end
-- 开始播放
function TypewriterEffect:start()
if self.isPlaying then
return
end
self.isPlaying = true
self.currentLineIndex = 0
self:showNextLine()
end
-- 停止播放
function TypewriterEffect:stop()
self.isPlaying = false
if self.timer then
self.timer = nil
end
end
-- 使用示例
function exampleUsage()
-- 添加第一行:混合文本和特效
TypewriterEffect:addLine({
{type = "text", content = "欢迎来到", speed = 0.1},
{type = "sfx", id = 1001, speed = 0.3},
{type = "text", content = "游戏世界", speed = 0.1}
})
-- 添加第二行:纯文本
TypewriterEffect:addLine({
{type = "text", content = "这是一个演示打字机效果的例子", speed = 0.08}
})
-- 添加第三行:分段文本
TypewriterEffect:addLine({
{type = "text", content = "第一段", speed = 0.1},
{type = "text", content = "第二段", speed = 0.1},
{type = "sfx", id = 1002, speed = 0.4},
{type = "text", content = "第三段", speed = 0.1}
})
-- 开始播放
TypewriterEffect:start()
end
-- 调用示例
exampleUsage()
```
**关键点说明:**
1. **分层控制**:通过`TypewriterEffect`对象管理整个打字机流程
2. **行级控制**:每行独立播放,支持行间间隔
3. **元素级控制**:每行内支持多种元素类型(文本、特效)
4. **文本打字**:使用`SL:ScheduleOnce`实现逐字显示效果
5. **位置计算**:自动计算每行位置和元素间距
6. **异步回调**:确保播放顺序正确
**扩展建议:**
- 可以添加暂停/继续功能
- 支持跳过当前行或全部跳过
- 添加声音效果配合文字显示
- 支持富文本样式(颜色、大小变化)
这个方案完全基于996引擎的前端函数实现,如果需要特效的具体实现方式,可以参考浮生梦老师的前端课程相关内容。
← 返回问答库