]>
Dogcows Code - chaz/yoink/blob - src/Animation.cc
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
15 #include <Moof/Error.hh>
16 #include <Moof/Manager.hh>
17 #include <Moof/Log.hh>
18 #include <Moof/Script.hh>
20 #include "Animation.hh"
24 * The collection of nested animation classes. The animation
25 * implementation consists of an Impl class which is allocated and
26 * initialized with the interface object. This class contains the specific
27 * fields which are required to run a single instance of an animation. The
28 * sequence data is loaded in a different class which can be shared amongst
29 * multiple animation implementation instances.
37 * Contains "global" animation data for the various animations which
38 * get loaded. This is a mippleton, so it will be shared amongst any
39 * animation which wants to use these loaded sequences.
42 class Data
: public Mf::Manager
<Data
>
47 * A frame of an animation sequence. A frame is merely an index
48 * which presumably represents a "slide" or tile which should be
49 * displayed, and the duration that is how long the slide will be
57 unsigned mIndex
; ///< Frame index.
58 Mf::Scalar mDuration
; ///< Frame duration.
61 * Construction is initialization. The frame data is loaded
62 * from a frame map which is probably loaded within an
66 Frame(const Mf::Script::Slot
& table
) :
70 table
.get(mIndex
, "index");
71 table
.get(mDuration
, "duration");
77 * A sequence is just a few attributes and a list of frames in the
78 * order that they should be played.
85 std::vector
<Frame
> mFrames
; ///< List of frames.
86 Mf::Scalar mDelay
; ///< Scale frame durations.
87 bool mLoop
; ///< Does the sequence repeat?
88 std::string mNext
; ///< Next sequence name.
91 * Construction is initialization. The constructor loads
92 * sequence data from the sequence map, presumably loaded from
93 * an animation file. The rest of the loading takes place in
94 * the frame's constructor which loads each individual frame.
97 Sequence(const Mf::Script::Slot
& table
) :
101 table
.get(mDelay
, "delay");
102 table
.get(mLoop
, "loop");
103 table
.get(mNext
, "next");
105 // TODO - sequence class/type not yet implemented
107 Mf::Script::Slot frameTable
= table
.pushField("frames");
108 if (frameTable
.isTable())
110 int max
= frameTable
.length();
111 for (int index
= 1; index
<= max
; ++index
)
113 Mf::Script::Slot top
= frameTable
.pushField(index
);
117 mFrames
.push_back(Frame(top
));
121 Mf::logWarning
<< "invalid frame at index "
122 << index
<< std::endl
;
132 * Starts loading a file with animation data. Such a file is
133 * formatted as a map of named sequences. The sequence
134 * constructor loads each individual sequence.
137 void init(const std::string
& name
)
140 std::string
path(name
);
142 if (!Animation::getPath(path
))
144 Mf::Error(Mf::Error::RESOURCE_NOT_FOUND
).raise();
147 script
.importBaseLibrary();
148 importLogFunctions(script
);
149 importAnimationBindings(script
);
151 if (script
.doFile(path
) != Mf::Script::SUCCESS
)
159 int defineSequence(Mf::Script
& script
)
161 Mf::Script::Slot name
= script
[1].requireString();
162 Mf::Script::Slot table
= script
[2].requireTable();
167 mSequences
.insert(std::make_pair(nameStr
, Sequence(table
)));
173 void importAnimationBindings(Mf::Script
& script
)
175 script
.importFunction("DefineSequence",
176 boost::bind(&Data::defineSequence
,
179 script
.globals().setField("ATTACK", 1);
180 script
.globals().setField("CHARGE", 2);
181 script
.globals().setField("FLY", 3);
182 script
.globals().setField("HIT", 4);
183 script
.globals().setField("JUMP", 5);
184 script
.globals().setField("RUN", 6);
185 script
.globals().setField("STAND", 7);
189 std::map
<std::string
,Sequence
> mSequences
; ///< List of sequences.
194 * Construction is intialization.
197 Impl(const std::string
& name
) :
198 mData(Data::getInstance(name
)),
207 * Sets up the animation classes to "play" a named sequence. If
208 * another sequence was active, it will be replaced. Future updates
209 * will progress the new sequence.
212 void startSequence(const std::string
& name
)
214 std::map
<std::string
,Data::Sequence
>::iterator it
;
216 it
= mData
->mSequences
.find(name
);
218 if (it
!= mData
->mSequences
.end())
220 mCurrentSequence
= &(*it
).second
;
222 mFrameIndex
= mCurrentSequence
->mFrames
[0].mIndex
;
224 mFrameDuration
= mCurrentSequence
->mDelay
*
225 mCurrentSequence
->mFrames
[0].mDuration
;
230 * Updates or progresses the animation sequence. If the time interval
231 * surpasses the duration of the current frame, a new frame becomes the
232 * current frame. If the last frame of a sequence expires, the active
233 * sequence will switch automatically to the designated "next"
234 * sequence, or if none is specified but the sequence is set to loop,
235 * the first frame of the sequence will become the current frame, and
236 * the animation essentially starts over again.
239 void update(Mf::Scalar t
, Mf::Scalar dt
)
241 if (!mCurrentSequence
) return;
245 if (mTimeAccum
>= mFrameDuration
)
247 if (++mFrameCounter
>= mCurrentSequence
->mFrames
.size())
249 if (!mCurrentSequence
->mNext
.empty())
251 startSequence(mCurrentSequence
->mNext
);
253 else if (mCurrentSequence
->mLoop
)
260 mCurrentSequence
= 0;
264 mFrameIndex
= mCurrentSequence
->mFrames
[mFrameCounter
].mIndex
;
265 mTimeAccum
= mFrameDuration
- mTimeAccum
;
266 mFrameDuration
= mCurrentSequence
->mDelay
*
267 mCurrentSequence
->mFrames
[mFrameCounter
].mDuration
;
271 boost::shared_ptr
<Data
> mData
; ///< Internal data.
273 Data::Sequence
* mCurrentSequence
; ///< Active sequence.
274 unsigned mFrameCounter
; ///< Current frame.
275 unsigned mFrameIndex
; ///< Index of current frame.
276 Mf::Scalar mTimeAccum
; ///< Time accumulation.
277 Mf::Scalar mFrameDuration
; ///< Scaled frame duration.
281 Animation::Animation(const std::string
& name
) :
283 mImpl(new Animation::Impl(name
)) {}
286 void Animation::startSequence(const std::string
& name
)
289 mImpl
->startSequence(name
);
292 void Animation::update(Mf::Scalar t
, Mf::Scalar dt
)
295 mImpl
->update(t
, dt
);
300 * Gets the index for the current frame. This is presumably called by some
301 * drawing code which will draw the correct current frame.
304 unsigned Animation::getFrame() const
306 return mImpl
->mFrameIndex
;
311 * Specialized search location for animation files. They can be found in
312 * the "animations" subdirectory of any of the search directories.
315 bool Animation::getPath(std::string
& name
)
317 return Mf::Resource::getPath(name
, "animations/", "lua");
This page took 0.054172 seconds and 4 git commands to generate.