基于VBA实现可变车厢数的列车驶离车站动画技术问询
解决Twitch Raid/Hype Train动态列车动画的VBA实现
需求概述
针对Twitch直播的Raid和Hype Train场景,实现动态列车动画:
- Raid场景:每68名观众对应1节车厢(如750人对应12节)
- Hype Train场景:每升1级对应1节车厢(如5级对应5节)
- 列车首尾均有机车(类似英国InterCity 125),新增车厢需先将现有列车(含后机车)左移腾出前端空间
- 完成编组后执行向右Fly Out离场动画,动画时长按车厢数设置(5秒/节)
修正后的完整VBA代码
Sub BuildRaidTrain() Dim raid As Integer Dim raidFile As String Dim carriageWidth As Single Dim trainSlide As Slide Dim carriageSlide As Slide Dim trainGroup As Shape Dim newCarriage As Shape Dim animationDuration As Double ' 读取Raid人数并计算所需车厢数(向上取整) raidFile = ActivePresentation.Path & "\raid.txt" Open raidFile For Input As #1 Input #1, raid Close #1 Dim carriageCount As Integer carriageCount = WorksheetFunction.RoundUp(raid / 68, 0) ' 初始化幻灯片与对象引用 Set trainSlide = ActivePresentation.Slides(23) Set carriageSlide = ActivePresentation.Slides(27) Set trainGroup = trainSlide.Shapes("Group 1") carriageWidth = carriageSlide.Shapes(1).Width ' 循环添加车厢 carriageSlide.Shapes(1).Copy Do While carriageCount > 0 ' 移动现有列车左移1节车厢宽度,腾出空间 trainGroup.Left = trainGroup.Left - carriageWidth ' 获取刚粘贴的新车厢 Set newCarriage = trainSlide.Shapes.Paste(1) ' 将新车厢并入列车编组 Dim tempShapes As ShapeRange Set tempShapes = trainSlide.Shapes.Range(Array(trainGroup.Name, newCarriage.Name)) Set trainGroup = tempShapes.Group carriageCount = carriageCount - 1 Loop ' 设置并执行离场动画 animationDuration = WorksheetFunction.RoundUp(raid / 68, 0) * 5 With trainGroup.AnimationSettings .EntryEffect = ppEffectFlyOut .EffectParameters.Direction = ppEffectDirectionRight .Duration = animationDuration .TextLevelEffect = ppAnimateLevelNone End With trainSlide.SlideShowTransition.AdvanceOnTime = True trainSlide.SlideShowTransition.AdvanceTime = animationDuration ActivePresentation.SlideShowWindow.View.GotoSlide trainSlide.SlideIndex End Sub Sub BuildHypeTrain() Dim hypeLevel As Integer Dim hypeFile As String Dim carriageWidth As Single Dim trainSlide As Slide Dim carriageSlide As Slide Dim trainGroup As Shape Dim newCarriage As Shape Dim animationDuration As Double ' 读取Hype Train等级 hypeFile = ActivePresentation.Path & "\hype.txt" Open hypeFile For Input As #1 Input #1, hypeLevel Close #1 Dim carriageCount As Integer carriageCount = hypeLevel ' 初始化幻灯片与对象引用 Set trainSlide = ActivePresentation.Slides(23) Set carriageSlide = ActivePresentation.Slides(27) Set trainGroup = trainSlide.Shapes("Group 1") carriageWidth = carriageSlide.Shapes(1).Width ' 循环添加车厢 carriageSlide.Shapes(1).Copy Do While carriageCount > 0 trainGroup.Left = trainGroup.Left - carriageWidth Set newCarriage = trainSlide.Shapes.Paste(1) Dim tempShapes As ShapeRange Set tempShapes = trainSlide.Shapes.Range(Array(trainGroup.Name, newCarriage.Name)) Set trainGroup = tempShapes.Group carriageCount = carriageCount - 1 Loop ' 设置并执行离场动画 animationDuration = hypeLevel * 5 With trainGroup.AnimationSettings .EntryEffect = ppEffectFlyOut .EffectParameters.Direction = ppEffectDirectionRight .Duration = animationDuration .TextLevelEffect = ppAnimateLevelNone End With trainSlide.SlideShowTransition.AdvanceOnTime = True trainSlide.SlideShowTransition.AdvanceTime = animationDuration ActivePresentation.SlideShowWindow.View.GotoSlide trainSlide.SlideIndex End Sub
关键问题修复说明
- 文本读取修正:修复原代码中错误的变量赋值逻辑,正确从txt文件读取观众数/等级数值
- 新车厢获取:使用
Shapes.Paste(1)直接获取刚粘贴的形状,无需手动选中 - 编组更新:每次粘贴后将现有列车与新车厢重新编组,并更新编组引用,确保后续操作针对最新列车
- 动画时长计算:基于最终车厢数设置5秒/节的动画时长,保证动画节奏匹配列车长度
- 循环优化:提前复制车厢资源,避免重复复制操作提升执行效率
使用步骤
- 将
raid.txt(写入Raid观众数)或hype.txt(写入Hype等级)放在演示文稿同目录下 - 确保幻灯片23中的初始列车编组命名为
Group 1,包含后机车与初始车厢 - 运行对应宏(
BuildRaidTrain或BuildHypeTrain)自动完成编组与动画设置
内容的提问来源于stack exchange,提问作者Robert Whitehill
相关产品推荐
相关产品推荐

