From 5f232c2ae47d985aab5b2b151ce6ee545e97169d Mon Sep 17 00:00:00 2001 From: tommy Date: Sun, 25 Aug 2024 01:27:17 -0400 Subject: [PATCH] Add image sequence code (basic video/gif player) --- ExampleImageSequence.lua | 5 ++ ExampleSpritesheetSequence.lua | 7 ++ ImageSequence.lua | 149 +++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 ExampleImageSequence.lua create mode 100644 ExampleSpritesheetSequence.lua create mode 100644 ImageSequence.lua diff --git a/ExampleImageSequence.lua b/ExampleImageSequence.lua new file mode 100644 index 0000000..3937bd6 --- /dev/null +++ b/ExampleImageSequence.lua @@ -0,0 +1,5 @@ +return { + FrameCount = 103, + FrameTime = 1/30, + AssetIds = {'rbxassetid://18300069384','rbxassetid://18300069589','rbxassetid://18300069926','rbxassetid://18300070468','rbxassetid://18300070631','rbxassetid://18300070885','rbxassetid://18300071124','rbxassetid://18300071342','rbxassetid://18300071571','rbxassetid://18300071719','rbxassetid://18300071905','rbxassetid://18300072135','rbxassetid://18300072297','rbxassetid://18300072500','rbxassetid://18300072694','rbxassetid://18300072942','rbxassetid://18300073249','rbxassetid://18300073449','rbxassetid://18300073654','rbxassetid://18300073831','rbxassetid://18300074100','rbxassetid://18300074381','rbxassetid://18300074708','rbxassetid://18300075078','rbxassetid://18300075466','rbxassetid://18300075720','rbxassetid://18300076000','rbxassetid://18300076198','rbxassetid://18300076380','rbxassetid://18300076569','rbxassetid://18300076756','rbxassetid://18300076968','rbxassetid://18300077201','rbxassetid://18300077433','rbxassetid://18300078411','rbxassetid://18300078643','rbxassetid://18300078870','rbxassetid://18300079032','rbxassetid://18300079171','rbxassetid://18300079360','rbxassetid://18300079574','rbxassetid://18300079739','rbxassetid://18300079897','rbxassetid://18300080098','rbxassetid://18300080258','rbxassetid://18300081182','rbxassetid://18300081370','rbxassetid://18300081526','rbxassetid://18300081769','rbxassetid://18300082111','rbxassetid://18300082264','rbxassetid://18300082443','rbxassetid://18300082668','rbxassetid://18300082892','rbxassetid://18300083289','rbxassetid://18300083549','rbxassetid://18300083783','rbxassetid://18300083999','rbxassetid://18300084209','rbxassetid://18300084421','rbxassetid://18300084609','rbxassetid://18300084891','rbxassetid://18300085170','rbxassetid://18300085359','rbxassetid://18300085542','rbxassetid://18300086179','rbxassetid://18300086563','rbxassetid://18300086750','rbxassetid://18300086973','rbxassetid://18300087147','rbxassetid://18300087371','rbxassetid://18300087710','rbxassetid://18300087931','rbxassetid://18300088118','rbxassetid://18300088292','rbxassetid://18300088593','rbxassetid://18300088865','rbxassetid://18300089071','rbxassetid://18300089261','rbxassetid://18300089426','rbxassetid://18300089679','rbxassetid://18300089846','rbxassetid://18300090041','rbxassetid://18300090244','rbxassetid://18300090433','rbxassetid://18300090610','rbxassetid://18300090787','rbxassetid://18300091118','rbxassetid://18300091264','rbxassetid://18300091503','rbxassetid://18300091849','rbxassetid://18300092103','rbxassetid://18300092324','rbxassetid://18300092535','rbxassetid://18300092814','rbxassetid://18300093005','rbxassetid://18300093137','rbxassetid://18300093571','rbxassetid://18300093888','rbxassetid://18300094077','rbxassetid://18300094259','rbxassetid://18300094479','rbxassetid://18300094743'} +} \ No newline at end of file diff --git a/ExampleSpritesheetSequence.lua b/ExampleSpritesheetSequence.lua new file mode 100644 index 0000000..ada0c69 --- /dev/null +++ b/ExampleSpritesheetSequence.lua @@ -0,0 +1,7 @@ +return { + FrameCount = 103, + FrameSize = Vector2.new(64, 92), + FrameTime = 1/30, + GridSize = Vector2.new(11, 10), + AssetId = 'rbxassetid://18297119321', +} \ No newline at end of file diff --git a/ImageSequence.lua b/ImageSequence.lua new file mode 100644 index 0000000..cc45154 --- /dev/null +++ b/ImageSequence.lua @@ -0,0 +1,149 @@ +--tommy * 2024 (@__tommyy) +local RunService = game:GetService("RunService") +local Players = game:GetService("Players") + +local Sequence = {} + +Sequence.Assets = {} + +local TotalImages = 0 +local ImagesLoaded = 0 + +for _, SpritesheetDefinition in script:GetChildren() do + local PlayerGui = Players.LocalPlayer:WaitForChild("PlayerGui") + local TemporaryLoadingGui = Instance.new("ScreenGui", PlayerGui) + TemporaryLoadingGui.Name = "TemporaryLoader" + + local ReturnedSpritesheetDefinition = require(SpritesheetDefinition) + Sequence.Assets[SpritesheetDefinition.Name] = {} + local SpriteSheetDataContainer = Sequence.Assets[SpritesheetDefinition.Name] + SpriteSheetDataContainer.Definition = ReturnedSpritesheetDefinition + + if ReturnedSpritesheetDefinition.AssetId then + TotalImages += 1 + local NewImageLabel = Instance.new("ImageLabel", TemporaryLoadingGui) + NewImageLabel.Size = UDim2.fromOffset(1, 1) + NewImageLabel.Image = ReturnedSpritesheetDefinition.AssetId + NewImageLabel.BackgroundTransparency = 1 + NewImageLabel.Name = SpritesheetDefinition.Name + SpriteSheetDataContainer.Image = NewImageLabel + NewImageLabel.ImageTransparency = 0 + task.spawn(function() + while not NewImageLabel.IsLoaded do + RunService.RenderStepped:Wait() + end + ImagesLoaded += 1 + NewImageLabel.ImageTransparency = 1 + end) + elseif ReturnedSpritesheetDefinition.AssetIds then + if not SpriteSheetDataContainer.Images then + SpriteSheetDataContainer.Images = {} + end + TotalImages += ReturnedSpritesheetDefinition.FrameCount + for ImageIndex = 1, ReturnedSpritesheetDefinition.FrameCount do + local NewImageLabel = Instance.new("ImageLabel", TemporaryLoadingGui) + NewImageLabel.Size = UDim2.fromOffset(1, 1) + NewImageLabel.Image = ReturnedSpritesheetDefinition.AssetIds[ImageIndex] + NewImageLabel.BackgroundTransparency = 1 + NewImageLabel.Name = `{SpritesheetDefinition.Name}_{ImageIndex}` + SpriteSheetDataContainer.Images[ImageIndex] = NewImageLabel + NewImageLabel.ImageTransparency = 0 + task.spawn(function() + while not NewImageLabel.IsLoaded do + RunService.RenderStepped:Wait() + end + print(`Image {SpritesheetDefinition.Name} #{ImageIndex} loaded`) + ImagesLoaded += 1 + NewImageLabel.ImageTransparency = 1 + end) + end + end +end + +while ImagesLoaded < TotalImages do + RunService.RenderStepped:Wait() +end + +print(`Loaded {ImagesLoaded} images for ImageSequence`) + +function Sequence.PlaySequenceTrueSpritesheet(ImageLabel: ImageLabel, SpritesheetDefinition, DoLoop: boolean) + local FrameCount = SpritesheetDefinition.Definition.FrameCount + local FrameSize = SpritesheetDefinition.Definition.FrameSize + local FrameTime = SpritesheetDefinition.Definition.FrameTime + local GridSize = SpritesheetDefinition.Definition.GridSize + local AssetId = SpritesheetDefinition.Definition.AssetId + + ImageLabel.Image = AssetId + ImageLabel.ImageRectSize = FrameSize + + local LoopThread; LoopThread = coroutine.create(function() + local TimeElapsed = 0 + local ImageIndex = 0 + while coroutine.status(coroutine.running()) ~= "dead" do + TimeElapsed += RunService.RenderStepped:Wait() + if TimeElapsed >= FrameTime then + TimeElapsed -= FrameTime + local OffsetX = FrameSize.X * (ImageIndex % GridSize.X) + local OffsetY = FrameSize.Y * math.floor(ImageIndex / GridSize.X) + ImageLabel.ImageRectOffset = Vector2.new(OffsetX, OffsetY) + ImageIndex += 1 + if ImageIndex == FrameCount - 1 then + if DoLoop then + ImageIndex = 0 + else + break + end + end + end + end + end) + coroutine.resume(LoopThread) + return function() + coroutine.close(LoopThread) + end +end + +function Sequence.PlaySequenceButRobloxIsBad(ImageLabel: ImageLabel, SpritesheetDefinition, DoLoop: boolean) + local FrameCount = SpritesheetDefinition.Definition.FrameCount + local FrameTime = SpritesheetDefinition.Definition.FrameTime + local AssetIds = SpritesheetDefinition.Definition.AssetIds + + ImageLabel.Image = "rbxassetid://0" + ImageLabel.ImageRectSize = Vector2.zero + ImageLabel.ImageRectOffset = Vector2.zero + + local LoopThread; LoopThread = coroutine.create(function() + local TimeElapsed = 0 + local ImageIndex = 1 + while coroutine.status(coroutine.running()) ~= "dead" do + TimeElapsed += RunService.RenderStepped:Wait() + if TimeElapsed >= FrameTime then + TimeElapsed -= FrameTime + local AssetId = AssetIds[ImageIndex] + if AssetId then + ImageLabel.Image = AssetId + end + ImageIndex += 1 + if ImageIndex == FrameCount then + if DoLoop then + ImageIndex = 1 + else + break + end + end + end + end + end) + coroutine.resume(LoopThread) + return function() + coroutine.close(LoopThread) + end +end + +function Sequence.PlaySequence(ImageLabel: ImageLabel, SpritesheetDefinition, DoLoop: boolean) + return (SpritesheetDefinition.Definition.AssetId and + Sequence.PlaySequenceTrueSpritesheet or + Sequence.PlaySequenceButRobloxIsBad)(ImageLabel, SpritesheetDefinition, DoLoop) +end + +return Sequence \ No newline at end of file