-
Notifications
You must be signed in to change notification settings - Fork 1
/
animatedimage.lua
126 lines (100 loc) · 3.31 KB
/
animatedimage.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import "CoreLibs/animation"
local graphics <const> = playdate.graphics
local animation <const> = playdate.graphics.animation
AnimatedImage = {}
-- image_table_path should be an image table or a path to an image table.
-- options is a table of initial settings:
-- delay: time in milliseconds to wait before moving to next frame. (default: 100ms)
-- paused: start in a paused state. (default: false)
-- loop: loop the animation. (default: false)
-- step: number of frames to step. (default: 1)
-- sequence: an array of frame numbers in order to be used in the animation e.g. `{1, 1, 3, 5, 2}`. (default: all of the frames from the specified image table)
function AnimatedImage.new(image_table_path, options)
options = options or {}
local image_table = image_table_path
if type(image_table_path) == "string" then
image_table = graphics.imagetable.new(image_table_path)
end
if image_table == nil then
print("ANIMATEDIMAGE: INVALID IMAGE USED", image_table_path)
return nil
end
-- Build sequence image table, if specified.
if options.sequence ~= nil then
local sequence_image_table = graphics.imagetable.new(#options.sequence)
for i, v in ipairs(options.sequence) do
sequence_image_table:setImage(i, image_table:getImage(v))
end
image_table = sequence_image_table
end
local animation_loop = animation.loop.new(options.delay or 100, image_table, options.loop and true or false)
animation_loop.paused = options.paused and true or false
animation_loop.startFrame = options.first or 1
animation_loop.endFrame = options.last or image_table:getLength()
animation_loop.step = options.step or 1
local animated_image = {}
setmetatable(animated_image, AnimatedImage)
animated_image.image_table = image_table
animated_image.loop = animation_loop
return animated_image
end
function AnimatedImage:reset()
self.loop.frame = self.loop.startFrame
end
function AnimatedImage:setDelay(delay)
self.loop.delay = delay
end
function AnimatedImage:getDelay()
return self.loop.delay
end
function AnimatedImage:setShouldLoop(should_loop)
self.loop.shouldLoop = should_loop
end
function AnimatedImage:getShouldLoop()
return self.loop.shouldLoop
end
function AnimatedImage:setStep(frame_count)
self.loop.step = frame_count
end
function AnimatedImage:getStep()
return self.loop.step
end
function AnimatedImage:setPaused(paused)
self.loop.paused = paused
end
function AnimatedImage:getPaused()
return self.loop.paused
end
function AnimatedImage:setFrame(frame)
self.loop.frame = frame
end
function AnimatedImage:getFrame()
return self.loop.frame
end
function AnimatedImage:setFirstFrame(frame)
self.loop.startFrame = frame
end
function AnimatedImage:setLastFrame(frame)
self.loop.endFrame = frame
end
function AnimatedImage:isComplete()
return not self.loop:isValid()
end
function AnimatedImage:getImage()
return self.image_table:getImage(self.loop.frame)
end
AnimatedImage.__index = function(animated_image, key)
local proxy_value = rawget(AnimatedImage, key)
if proxy_value then
return proxy_value
end
proxy_value = animated_image.image_table:getImage(animated_image.loop.frame)[key]
if type(proxy_value) == "function" then
rawset(animated_image, key, function(ai, ...)
local img = ai.image_table:getImage(ai.loop.frame)
return img[key](img, ...)
end)
return animated_image[key]
end
return proxy_value
end