1 /*
2 * tile.h
3 * Copyright 2008-2014, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
4 * Copyright 2009, Edward Hutchins <eah1@yahoo.com>
5 *
6 * This file is part of libtiled.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 * EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #pragma once
31
32 #include "object.h"
33 #include "tiled.h"
34
35 #include <QPixmap>
36 #include <QSharedPointer>
37 #include <QUrl>
38
39 #include <memory>
40
41 namespace Tiled {
42
43 class ObjectGroup;
44 class Tileset;
45
46 /**
47 * A single frame of an animated tile.
48 */
49 struct Frame
50 {
51 bool operator == (const Frame &frame) const
52 {
53 return tileId == frame.tileId &&
54 duration == frame.duration;
55 }
56
57 int tileId;
58 int duration;
59 };
60
61 class TILEDSHARED_EXPORT Tile : public Object
62 {
63 public:
64 Tile(int id, Tileset *tileset);
65 Tile(const QPixmap &image, int id, Tileset *tileset);
66
67 ~Tile();
68
69 int id() const;
70
71 Tileset *tileset() const;
72 QSharedPointer<Tileset> sharedTileset() const;
73
74 const QPixmap &image() const;
75 void setImage(const QPixmap &image);
76
77 const Tile *currentFrameTile() const;
78
79 const QUrl &imageSource() const;
80 void setImageSource(const QUrl &imageSource);
81
82 int width() const;
83 int height() const;
84 QSize size() const;
85
86 QPoint offset() const;
87
88 const QString &type() const;
89 void setType(const QString &type);
90
91 qreal probability() const;
92 void setProbability(qreal probability);
93
94 ObjectGroup *objectGroup() const;
95 void setObjectGroup(std::unique_ptr<ObjectGroup> objectGroup);
96 void swapObjectGroup(std::unique_ptr<ObjectGroup> &objectGroup);
97
98 const QVector<Frame> &frames() const;
99 void setFrames(const QVector<Frame> &frames);
100 bool isAnimated() const;
101 int currentFrameIndex() const;
102 bool resetAnimation();
103 bool advanceAnimation(int ms);
104
105 LoadingStatus imageStatus() const;
106 void setImageStatus(LoadingStatus status);
107
108 Tile *clone(Tileset *tileset) const;
109
110 private:
111 int mId;
112 Tileset *mTileset;
113 QPixmap mImage;
114 QUrl mImageSource;
115 LoadingStatus mImageStatus;
116 QString mType;
117 qreal mProbability;
118 std::unique_ptr<ObjectGroup> mObjectGroup;
119
120 QVector<Frame> mFrames;
121 int mCurrentFrameIndex;
122 int mUnusedTime;
123
124 friend class Tileset; // To allow changing the tile id
125 };
126
127 /**
128 * Returns ID of this tile within its tileset.
129 */
id()130 inline int Tile::id() const
131 {
132 return mId;
133 }
134
135 /**
136 * Returns the tileset that this tile is part of.
137 */
tileset()138 inline Tileset *Tile::tileset() const
139 {
140 return mTileset;
141 }
142
143 /**
144 * Returns the image of this tile.
145 */
image()146 inline const QPixmap &Tile::image() const
147 {
148 return mImage;
149 }
150
151 /**
152 * Sets the image of this tile.
153 */
setImage(const QPixmap & image)154 inline void Tile::setImage(const QPixmap &image)
155 {
156 mImage = image;
157 mImageStatus = image.isNull() ? LoadingError : LoadingReady;
158 }
159
160 /**
161 * Returns the URL of the external image that represents this tile.
162 * When this tile doesn't refer to an external image, an empty URL is
163 * returned.
164 */
imageSource()165 inline const QUrl &Tile::imageSource() const
166 {
167 return mImageSource;
168 }
169
setImageSource(const QUrl & imageSource)170 inline void Tile::setImageSource(const QUrl &imageSource)
171 {
172 mImageSource = imageSource;
173 }
174
175 /**
176 * Returns the width of this tile.
177 */
width()178 inline int Tile::width() const
179 {
180 return mImage.width();
181 }
182
183 /**
184 * Returns the height of this tile.
185 */
height()186 inline int Tile::height() const
187 {
188 return mImage.height();
189 }
190
191 /**
192 * Returns the size of this tile.
193 */
size()194 inline QSize Tile::size() const
195 {
196 return mImage.size();
197 }
198
199 /**
200 * Returns the type of this tile. Tile objects that do not have a type
201 * explicitly set on them are assumed to be of the type returned by this
202 * function.
203 */
type()204 inline const QString &Tile::type() const
205 {
206 return mType;
207 }
208
209 /**
210 * Sets the type of this tile.
211 * \sa type()
212 */
setType(const QString & type)213 inline void Tile::setType(const QString &type)
214 {
215 mType = type;
216 }
217
218 /**
219 * Returns the relative probability of this tile appearing while painting.
220 */
probability()221 inline qreal Tile::probability() const
222 {
223 return mProbability;
224 }
225
226 /**
227 * Set the relative probability of this tile appearing while painting.
228 */
setProbability(qreal probability)229 inline void Tile::setProbability(qreal probability)
230 {
231 mProbability = probability;
232 }
233
234 /**
235 * @return The group of objects associated with this tile. This is generally
236 * expected to be used for editing collision shapes.
237 */
objectGroup()238 inline ObjectGroup *Tile::objectGroup() const
239 {
240 return mObjectGroup.get();
241 }
242
frames()243 inline const QVector<Frame> &Tile::frames() const
244 {
245 return mFrames;
246 }
247
isAnimated()248 inline bool Tile::isAnimated() const
249 {
250 return !mFrames.isEmpty();
251 }
252
currentFrameIndex()253 inline int Tile::currentFrameIndex() const
254 {
255 return mCurrentFrameIndex;
256 }
257
258 /**
259 * Returns the loading status of the image referenced by this tile.
260 */
imageStatus()261 inline LoadingStatus Tile::imageStatus() const
262 {
263 return mImageStatus;
264 }
265
setImageStatus(LoadingStatus status)266 inline void Tile::setImageStatus(LoadingStatus status)
267 {
268 mImageStatus = status;
269 }
270
271 } // namespace Tiled
272
273 Q_DECLARE_METATYPE(Tiled::Tile*)
274