bzr branch
http://9ix.org/bzr/ld27
1
by Josh C
zoetrope 1.4 |
1 |
-- Class: Animation |
2 |
-- An animation displays a sequence of frames. If you do not specify |
|
3 |
-- a width and height for the sprite, it will size itself so that |
|
4 |
-- it is a square, where each side is as tall as the source image's height. |
|
5 |
-- |
|
6 |
-- |
|
7 |
-- Event: onEndSequence |
|
8 |
-- Called whenever an animation sequence ends. It is passed the name |
|
9 |
-- of the sequence that just ended. |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
10 |
-- |
1
by Josh C
zoetrope 1.4 |
11 |
-- Extends: |
12 |
-- <Sprite> |
|
13 |
||
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
14 |
Animation = Sprite:extend |
15 |
{ |
|
1
by Josh C
zoetrope 1.4 |
16 |
-- Property: paused |
17 |
-- Set this to true to freeze the animation on the current frame. |
|
18 |
paused = false, |
|
19 |
||
20 |
-- Property: sequences |
|
21 |
-- A lookup table of sequences. Each one is stored by name and has |
|
22 |
-- the following properties: |
|
23 |
-- * name - string name for the sequence. |
|
24 |
-- * frames - table of frames to display. The first frame in the sheet is at index 1. |
|
25 |
-- * fps - frames per second. |
|
26 |
-- * loops - does the animation loop? defaults to true |
|
27 |
sequences = {}, |
|
28 |
||
29 |
-- Property: image |
|
30 |
-- A string filename to the image to use as a sprite strip. A sprite |
|
31 |
-- strip can have multiple rows of frames. |
|
32 |
||
33 |
-- Property: currentSequence |
|
34 |
-- A reference to the current animation sequence table. |
|
35 |
||
36 |
-- Property: currentName |
|
37 |
-- The name of the current animation sequence. |
|
38 |
||
39 |
-- Property: currentFrame |
|
40 |
-- The current frame being displayed; starts at 1. |
|
41 |
||
42 |
-- Property: frameIndex |
|
43 |
-- Numeric index of the current frame in the current sequence; starts at 1. |
|
44 |
||
45 |
-- Property: frameTimer |
|
46 |
-- Time left before the animation changes to the next frame in seconds. |
|
47 |
-- Normally you shouldn't need to change this directly. |
|
48 |
||
49 |
-- private property: used to check whether the source image |
|
50 |
-- for our quad is up-to-date |
|
51 |
_set = {}, |
|
52 |
||
53 |
-- private property imageObj: actual Image instance used to draw |
|
54 |
-- this is normally set via the image property, but you may set it directly |
|
55 |
-- so long as you never change that image property afterwards. |
|
56 |
||
57 |
new = function (self, obj) |
|
58 |
obj = obj or {} |
|
59 |
self:extend(obj) |
|
60 |
obj:updateQuad() |
|
61 |
||
62 |
if obj.onNew then obj:onNew() end |
|
63 |
return obj |
|
64 |
end, |
|
65 |
||
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
66 |
-- Method: play |
1
by Josh C
zoetrope 1.4 |
67 |
-- Begins playing an animation in the sprite's library. |
68 |
-- If the animation is already playing, this has no effect. |
|
69 |
-- |
|
70 |
-- Arguments: |
|
71 |
-- name - name of the animation |
|
72 |
-- |
|
73 |
-- Returns: |
|
74 |
-- nothing |
|
75 |
||
76 |
play = function (self, name) |
|
77 |
if self.currentName == name and not self.paused then |
|
78 |
return |
|
79 |
end |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
80 |
|
1
by Josh C
zoetrope 1.4 |
81 |
assert(self.sequences[name], 'no animation sequence named "' .. name .. '"') |
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
82 |
|
1
by Josh C
zoetrope 1.4 |
83 |
self.currentName = name |
84 |
self.currentSequence = self.sequences[name] |
|
85 |
self.frameIndex = 0 |
|
86 |
self.frameTimer = 0 |
|
87 |
self.paused = false |
|
88 |
end, |
|
89 |
||
90 |
-- Method: freeze |
|
91 |
-- Freezes the animation on the specified frame. |
|
92 |
-- |
|
93 |
-- Arguments: |
|
94 |
-- * index - integer frame index relative to the entire sprite sheet, |
|
95 |
-- starts at 1. If omitted, this freezes the current frame. |
|
96 |
-- If there is no current frame, this freezes on the first frame. |
|
97 |
-- |
|
98 |
-- Returns: |
|
99 |
-- nothing |
|
100 |
||
101 |
freeze = function (self, index) |
|
102 |
if self.currentSequence then |
|
103 |
index = index or self.currentSequence[self.frameIndex] |
|
104 |
end |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
105 |
|
1
by Josh C
zoetrope 1.4 |
106 |
index = index or self.currentFrame or 1 |
107 |
||
108 |
if self._set.image ~= self.image then |
|
109 |
self:updateQuad() |
|
110 |
end |
|
111 |
||
112 |
self.currentFrame = index |
|
113 |
self:updateFrame(index) |
|
114 |
self.paused = true |
|
115 |
end, |
|
116 |
||
117 |
-- private method: updateQuad |
|
118 |
-- sets up the sprite's quad property based on the image; |
|
119 |
-- needs to be called whenever the sprite's image property changes. |
|
120 |
-- |
|
121 |
-- Arguments: |
|
122 |
-- none |
|
123 |
-- |
|
124 |
-- Returns: |
|
125 |
-- nothing |
|
126 |
||
127 |
updateQuad = function (self) |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
128 |
if self.image then |
1
by Josh C
zoetrope 1.4 |
129 |
self._imageObj = Cached:image(self.image) |
130 |
if not self.width then self.width = self._imageObj:getHeight() end |
|
131 |
if not self.height then self.height = self.width end |
|
132 |
||
133 |
self._quad = love.graphics.newQuad(0, 0, self.width, self.height, |
|
134 |
self._imageObj:getWidth(), self._imageObj:getHeight()) |
|
135 |
self._imageWidth = self._imageObj:getWidth() |
|
136 |
self._set.image = self.image |
|
137 |
end |
|
138 |
end, |
|
139 |
||
140 |
-- private method: updateFrame |
|
141 |
-- changes the sprite's quad property based on the current frame; |
|
142 |
-- needs to be called whenever the sprite's currentFrame property changes. |
|
143 |
-- |
|
144 |
-- Arguments: |
|
145 |
-- none |
|
146 |
-- |
|
147 |
-- Returns: |
|
148 |
-- nothing |
|
149 |
||
150 |
updateFrame = function (self) |
|
151 |
assert(type(self.currentFrame) == 'number', "current frame is not a number") |
|
152 |
assert(self.image, "asked to set the frame of a nil image") |
|
153 |
||
154 |
if self._set.image ~= self.image then |
|
155 |
self:updateQuad() |
|
156 |
end |
|
157 |
||
158 |
local frameX = (self.currentFrame - 1) * self.width |
|
159 |
local viewportX = frameX % self._imageWidth |
|
160 |
local viewportY = self.height * math.floor(frameX / self._imageWidth) |
|
161 |
self._quad:setViewport(viewportX, viewportY, self.width, self.height) |
|
162 |
end, |
|
163 |
||
164 |
update = function (self, elapsed) |
|
165 |
-- move the animation frame forward |
|
166 |
||
167 |
if self.currentSequence and not self.paused then |
|
168 |
self.frameTimer = self.frameTimer - elapsed |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
169 |
|
1
by Josh C
zoetrope 1.4 |
170 |
if self.frameTimer <= 0 then |
171 |
self.frameIndex = self.frameIndex + 1 |
|
172 |
||
173 |
if self.frameIndex > #self.currentSequence.frames then |
|
174 |
if self.onEndSequence then self:onEndSequence(self.currentName) end |
|
175 |
||
176 |
if self.currentSequence.loops ~= false then |
|
177 |
self.frameIndex = 1 |
|
178 |
else |
|
179 |
self.frameIndex = self.frameIndex - 1 |
|
180 |
self.paused = true |
|
181 |
end |
|
182 |
end |
|
183 |
||
184 |
self.currentFrame = self.currentSequence.frames[self.frameIndex] |
|
185 |
self:updateFrame() |
|
186 |
self.frameTimer = 1 / self.currentSequence.fps |
|
187 |
end |
|
188 |
end |
|
189 |
||
190 |
Sprite.update(self, elapsed) |
|
191 |
end, |
|
192 |
||
193 |
draw = function (self, x, y) |
|
194 |
x = math.floor(x or self.x) |
|
195 |
y = math.floor(y or self.y) |
|
196 |
||
197 |
if STRICT then |
|
198 |
assert(type(x) == 'number', 'visible animation does not have a numeric x property') |
|
199 |
assert(type(y) == 'number', 'visible animation does not have a numeric y property') |
|
200 |
assert(type(self.width) == 'number', 'visible animation does not have a numeric width property') |
|
201 |
assert(type(self.height) == 'number', 'visible animation does not have a numeric height property') |
|
202 |
end |
|
203 |
||
204 |
if not self.visible or not self.image or self.alpha <= 0 then return end |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
205 |
|
1
by Josh C
zoetrope 1.4 |
206 |
-- if our image changed, update the quad |
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
207 |
|
1
by Josh C
zoetrope 1.4 |
208 |
if self._set.image ~= self.image then |
209 |
self:updateQuad() |
|
210 |
end |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
211 |
|
1
by Josh C
zoetrope 1.4 |
212 |
-- set color if needed |
213 |
||
214 |
local colored = self.alpha ~= 1 or self.tint[1] ~= 1 or self.tint[2] ~= 1 or self.tint[3] ~= 1 |
|
215 |
||
216 |
if colored then |
|
217 |
love.graphics.setColor(self.tint[1] * 255, self.tint[2] * 255, self.tint[3] * 255, self.alpha * 255) |
|
218 |
end |
|
219 |
||
220 |
-- draw the quad |
|
221 |
||
222 |
local scaleX = self.scale * self.distort.x |
|
223 |
local scaleY = self.scale * self.distort.y |
|
224 |
||
225 |
if self.flipX then scaleX = scaleX * -1 end |
|
226 |
if self.flipY then scaleY = scaleY * -1 end |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
227 |
|
228 |
local origX = self.origin.x or (self.width / 2) |
|
229 |
local origY = self.origin.y or (self.height / 2) |
|
230 |
||
231 |
love.graphics.draw(self._imageObj, self._quad, x + origX, y + origY, self.rotation, |
|
232 |
scaleX, scaleY, origX, origY) |
|
233 |
||
1
by Josh C
zoetrope 1.4 |
234 |
-- reset color |
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
235 |
|
1
by Josh C
zoetrope 1.4 |
236 |
if colored then |
237 |
love.graphics.setColor(255, 255, 255, 255) |
|
238 |
end |
|
239 |
end, |
|
240 |
||
241 |
__tostring = function (self) |
|
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
242 |
local result = 'Animation (x: ' .. tostring(self.x) .. ', y: ' .. tostring(self.y) .. |
243 |
', w: ' .. tostring(self.width) .. ', h: ' .. tostring(self.height) .. ', ' |
|
1
by Josh C
zoetrope 1.4 |
244 |
|
245 |
if self.currentName then |
|
246 |
result = result .. 'playing ' .. self.currentName .. ', ' |
|
247 |
end |
|
248 |
||
35
by Josh C
cluke009 zoetrope + my spritebatch changes |
249 |
result = result .. ' frame ' .. tostring(self.currentFrame) .. ', ' |
1
by Josh C
zoetrope 1.4 |
250 |
|
251 |
if self.active then |
|
252 |
result = result .. 'active, ' |
|
253 |
else |
|
254 |
result = result .. 'inactive, ' |
|
255 |
end |
|
256 |
||
257 |
if self.visible then |
|
258 |
result = result .. 'visible, ' |
|
259 |
else |
|
260 |
result = result .. 'invisible, ' |
|
261 |
end |
|
262 |
||
263 |
if self.solid then |
|
264 |
result = result .. 'solid' |
|
265 |
else |
|
266 |
result = result .. 'not solid' |
|
267 |
end |
|
268 |
||
269 |
return result .. ')' |
|
270 |
end |
|
271 |
} |