Changeset View
Changeset View
Standalone View
Standalone View
wall.cpp
Show All 10 Lines | |||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Library General Public License for more details. | 12 | * Library General Public License for more details. | ||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | 14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the Free | 15 | * License along with this program; if not, write to the Free | ||
16 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | 17 | */ | ||
18 | 18 | | |||
19 | #include "wall.h" | | |||
20 | | ||||
21 | #include <cmath> | | |||
22 | | ||||
23 | | ||||
24 | #include <QPainter> | 19 | #include <QPainter> | ||
25 | #include <QStandardPaths> | 20 | #include <QStandardPaths> | ||
26 | 21 | | |||
27 | #include "board.h" | 22 | #include "board.h" | ||
28 | #include "renderer.h" | 23 | #include "renderer.h" | ||
29 | #include "settings.h" | 24 | #include "settings.h" | ||
25 | #include "wall.h" | ||||
26 | | ||||
27 | #include <cmath> | ||||
30 | 28 | | |||
31 | QSize KBounceWall::s_tileSize; | 29 | QSize KBounceWall::s_tileSize; | ||
32 | KBounceRenderer * KBounceWall::m_renderer = NULL; | 30 | KBounceRenderer * KBounceWall::m_renderer = NULL; | ||
33 | KBounceWall::Sprites * KBounceWall::s_sprites = NULL; | 31 | KBounceWall::Sprites * KBounceWall::s_sprites = NULL; | ||
34 | 32 | | |||
35 | 33 | /** | |||
34 | * KBounceWall class | ||||
35 | * | ||||
36 | * Constructor to set game wall configurations | ||||
37 | * @param dir wall direction | ||||
38 | * @param renderer object renderer | ||||
39 | * @param board game board | ||||
40 | * @see wall.h | ||||
41 | */ | ||||
36 | KBounceWall::KBounceWall( Direction dir, KBounceRenderer* renderer, KBounceBoard* board ) | 42 | KBounceWall::KBounceWall(Direction dir, KBounceRenderer* renderer, KBounceBoard* board) | ||
37 | : KGameRenderedItem( renderer,QLatin1String(""),board ) | 43 | : KGameRenderedItem( renderer,QLatin1String(""),board ) | ||
38 | , m_board( board ) | 44 | , m_board( board ) // Set game board | ||
39 | , m_dir( dir ) | 45 | , m_dir( dir ) // Set game direction | ||
40 | , m_soundWallstart( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/wallstart.wav") ) ) | 46 | , m_soundWallstart( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/wallstart.wav") )) // Set wall start sound asset | ||
41 | , m_soundReflect( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/reflect.wav") ) ) | 47 | , m_soundReflect( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/reflect.wav") )) // Set wall reflect sound asset | ||
42 | { | 48 | { | ||
43 | // The wall velocity would initialised on every new level. | 49 | // The wall velocity would initialised on every new level. | ||
44 | m_wallVelocity = 0.0; | 50 | m_wallVelocity = 0.0; | ||
45 | 51 | | |||
46 | if (!s_sprites) { | 52 | // Set sprite | ||
53 | if (!s_sprites) | ||||
47 | s_sprites = new Sprites; | 54 | s_sprites = new Sprites; | ||
48 | } | | |||
49 | 55 | | |||
50 | if (!m_renderer) { | 56 | // Set renderer | ||
57 | if (!m_renderer) | ||||
51 | m_renderer = renderer; | 58 | m_renderer = renderer; | ||
52 | } | 59 | } | ||
53 | } | | |||
54 | 60 | | |||
61 | /** | ||||
62 | * KBounceWall destructor | ||||
63 | * @see wall.h | ||||
64 | */ | ||||
55 | KBounceWall::~KBounceWall() | 65 | KBounceWall::~KBounceWall() | ||
56 | { | 66 | { | ||
57 | } | 67 | } | ||
58 | 68 | | |||
69 | /** | ||||
70 | * Changes object's state when collisions have been detected | ||||
71 | * Called once per frame before advance() and update() | ||||
72 | * @param collision hitters list | ||||
73 | * @see wall.h | ||||
74 | */ | ||||
59 | void KBounceWall::collide( KBounceCollision collision ) | 75 | void KBounceWall::collide(KBounceCollision collision) | ||
60 | { | 76 | { | ||
61 | if ( !isVisible() ) | 77 | if (!isVisible()) | ||
62 | return; | 78 | return; | ||
63 | 79 | | |||
64 | foreach( const KBounceHit &hit, collision ) { | 80 | foreach(const KBounceHit &hit, collision) { | ||
65 | switch (hit.type) { | 81 | switch (hit.type) { | ||
66 | case ALL: | 82 | case ALL: | ||
67 | break; | 83 | break; | ||
84 | | ||||
68 | case TILE: | 85 | case TILE: | ||
69 | finish(); | 86 | finish(); | ||
70 | break; | 87 | break; | ||
88 | | ||||
71 | case BALL: | 89 | case BALL: | ||
72 | if (safeEdgeHit(hit.boundingRect)) { | 90 | if (safeEdgeHit(hit.boundingRect)) { | ||
73 | KBounceVector normal = hit.normal; | 91 | KBounceVector normal = hit.normal; | ||
74 | if (qAbs(normal.x) < qAbs(normal.y)) { // vertical | 92 | | ||
75 | if (m_dir == Up || m_dir == Down) { | 93 | if (qAbs(normal.x) < qAbs(normal.y)) { | ||
94 | // vertical | ||||
95 | if (m_dir == Up || m_dir == Down) | ||||
76 | finish( true, m_dir ); | 96 | finish(true, m_dir); | ||
77 | } | 97 | } | ||
78 | } | 98 | else // horizontal | ||
79 | else if (m_dir == Left || m_dir == Right) { | 99 | if (m_dir == Left || m_dir == Right) | ||
80 | finish( true, m_dir ); | 100 | finish(true, m_dir); | ||
81 | } | 101 | } | ||
82 | } else { | 102 | else | ||
103 | { | ||||
83 | emit died(); | 104 | emit died(); | ||
84 | hide(); | 105 | hide(); | ||
85 | } | 106 | } | ||
86 | break; | 107 | break; | ||
108 | | ||||
87 | case WALL: | 109 | case WALL: | ||
88 | if (safeEdgeHit(hit.boundingRect)) { | 110 | if (safeEdgeHit(hit.boundingRect)) | ||
89 | finish(); | 111 | finish(); | ||
90 | } | | |||
91 | break; | 112 | break; | ||
92 | } | 113 | } | ||
93 | } | 114 | } | ||
94 | } | 115 | } | ||
95 | 116 | | |||
96 | 117 | /** | |||
118 | * Performs various movement and state calculations non-related | ||||
119 | * to collision responses. Also updates m_boundingRect and | ||||
120 | * m_nextBoundingRect. This method is called once per frame | ||||
121 | * after collide() and before update() | ||||
122 | * @see wall.h | ||||
123 | */ | ||||
97 | void KBounceWall::goForward() | 124 | void KBounceWall::goForward() | ||
98 | { | 125 | { | ||
99 | if (!isVisible()) { | 126 | if (!isVisible()) | ||
100 | return; | 127 | return; | ||
101 | } | | |||
102 | 128 | | |||
103 | switch( m_dir ) { | 129 | switch(m_dir) { | ||
104 | case Up: | 130 | case Up: | ||
105 | m_boundingRect.setTop( m_boundingRect.top() - m_wallVelocity ); | 131 | m_boundingRect.setTop( m_boundingRect.top() - m_wallVelocity ); | ||
106 | m_nextBoundingRect.setTop( m_boundingRect.top() - m_wallVelocity ); | 132 | m_nextBoundingRect.setTop( m_boundingRect.top() - m_wallVelocity ); | ||
107 | break; | 133 | break; | ||
134 | | ||||
108 | case Left: | 135 | case Left: | ||
109 | m_boundingRect.setLeft( m_boundingRect.left() - m_wallVelocity ); | 136 | m_boundingRect.setLeft( m_boundingRect.left() - m_wallVelocity ); | ||
110 | m_nextBoundingRect.setLeft( m_boundingRect.left() - m_wallVelocity ); | 137 | m_nextBoundingRect.setLeft( m_boundingRect.left() - m_wallVelocity ); | ||
111 | break; | 138 | break; | ||
139 | | ||||
112 | case Down: | 140 | case Down: | ||
113 | m_boundingRect.setBottom( m_boundingRect.bottom() + m_wallVelocity ); | 141 | m_boundingRect.setBottom( m_boundingRect.bottom() + m_wallVelocity ); | ||
114 | m_nextBoundingRect.setBottom( m_boundingRect.bottom() + m_wallVelocity ); | 142 | m_nextBoundingRect.setBottom( m_boundingRect.bottom() + m_wallVelocity ); | ||
115 | break; | 143 | break; | ||
144 | | ||||
116 | case Right: | 145 | case Right: | ||
117 | m_boundingRect.setRight( m_boundingRect.right() + m_wallVelocity ); | 146 | m_boundingRect.setRight( m_boundingRect.right() + m_wallVelocity ); | ||
118 | m_nextBoundingRect.setRight( m_boundingRect.right() + m_wallVelocity ); | 147 | m_nextBoundingRect.setRight( m_boundingRect.right() + m_wallVelocity ); | ||
119 | break; | 148 | break; | ||
120 | } | 149 | } | ||
121 | } | 150 | } | ||
122 | 151 | | |||
152 | /** | ||||
153 | * Updates object's pixmap and position on screen | ||||
154 | * Called once per frame after update() | ||||
155 | * @see wall.h | ||||
156 | */ | ||||
123 | void KBounceWall::update() | 157 | void KBounceWall::update() | ||
124 | { | 158 | { | ||
125 | if (!isVisible()) | 159 | if (!isVisible()) | ||
126 | return; | 160 | return; | ||
127 | 161 | | |||
128 | int boundingRectWidth = static_cast<int>(std::ceil(m_boundingRect.width() * s_tileSize.width())); | 162 | int boundingRectWidth = static_cast<int>(std::ceil(m_boundingRect.width() * s_tileSize.width())); | ||
129 | int boundingRectHeight = static_cast<int>(std::ceil(m_boundingRect.height() * s_tileSize.height())); | 163 | int boundingRectHeight = static_cast<int>(std::ceil(m_boundingRect.height() * s_tileSize.height())); | ||
130 | 164 | | |||
131 | if (!(boundingRectWidth && boundingRectHeight)) | 165 | if (!(boundingRectWidth && boundingRectHeight)) | ||
132 | return; | 166 | return; | ||
133 | 167 | | |||
134 | int tileWidth = s_tileSize.width(); | 168 | int tileWidth = s_tileSize.width(); | ||
135 | int tileHeight = s_tileSize.height(); | 169 | int tileHeight = s_tileSize.height(); | ||
136 | 170 | | |||
137 | QSize pixSize; | 171 | QSize pixSize; | ||
138 | if (m_dir == Left || m_dir == Right) { | 172 | if (m_dir == Left || m_dir == Right) | ||
139 | pixSize = QSize(boundingRectWidth + 64 - (boundingRectWidth%64), boundingRectHeight); | 173 | pixSize = QSize(boundingRectWidth + 64 - (boundingRectWidth%64), boundingRectHeight); | ||
140 | } else { | 174 | else | ||
141 | pixSize = QSize(boundingRectWidth, boundingRectHeight + 64 - (boundingRectHeight%64)); | 175 | pixSize = QSize(boundingRectWidth, boundingRectHeight + 64 - (boundingRectHeight%64)); | ||
142 | } | | |||
143 | 176 | | |||
144 | QPixmap px; | 177 | QPixmap px; | ||
145 | if (pixmap().width() < pixSize.width() || pixmap().height() < pixSize.height()) { | 178 | | ||
179 | if (pixmap().width() < pixSize.width() || pixmap().height() < pixSize.height()) | ||||
146 | px = QPixmap(pixSize); | 180 | px = QPixmap(pixSize); | ||
147 | } else { | 181 | else | ||
148 | px = pixmap(); // already ARGB | 182 | px = pixmap(); // already ARGB | ||
149 | } | 183 | | ||
150 | px.fill(Qt::transparent); | 184 | px.fill(Qt::transparent); | ||
151 | 185 | | |||
152 | QPainter p(&px); | 186 | QPainter p(&px); | ||
153 | 187 | | |||
154 | QPointF offset = m_board->mapPosition(m_boundingRect.topLeft()); | 188 | QPointF offset = m_board->mapPosition(m_boundingRect.topLeft()); | ||
155 | 189 | | |||
190 | int split; | ||||
156 | switch ( m_dir ) { | 191 | switch (m_dir) { | ||
157 | case Up: { | 192 | case Up: | ||
158 | const int split = qMin(tileHeight, boundingRectHeight); | 193 | split = qMin(tileHeight, boundingRectHeight); | ||
159 | p.drawPixmap(0, 0, s_sprites->wallEndUp, 0, 0, tileWidth, split); | 194 | p.drawPixmap(0, 0, s_sprites->wallEndUp, 0, 0, tileWidth, split); | ||
160 | p.drawTiledPixmap(0, split, tileWidth, boundingRectHeight - split, s_sprites->wallV, 0, offset.y()); | 195 | p.drawTiledPixmap(0, split, tileWidth, boundingRectHeight - split, s_sprites->wallV, 0, offset.y()); | ||
161 | break; | 196 | break; | ||
162 | } | 197 | | ||
163 | case Right: { | 198 | case Right: | ||
164 | const int split = qMin(tileWidth, boundingRectWidth); | 199 | split = qMin(tileWidth, boundingRectWidth); | ||
165 | p.drawPixmap(boundingRectWidth - tileWidth, 0, split, tileHeight, s_sprites->wallEndRight); | 200 | p.drawPixmap(boundingRectWidth - tileWidth, 0, split, tileHeight, s_sprites->wallEndRight); | ||
166 | p.drawTiledPixmap(0, 0, boundingRectWidth - split, tileHeight, s_sprites->wallH); | 201 | p.drawTiledPixmap(0, 0, boundingRectWidth - split, tileHeight, s_sprites->wallH); | ||
167 | break; | 202 | break; | ||
168 | } | 203 | | ||
169 | case Down: { | 204 | case Down: | ||
170 | const int split = qMin(tileHeight, boundingRectHeight); | 205 | split = qMin(tileHeight, boundingRectHeight); | ||
171 | p.drawPixmap(0, boundingRectHeight - tileHeight, tileWidth, split, s_sprites->wallEndDown); | 206 | p.drawPixmap(0, boundingRectHeight - tileHeight, tileWidth, split, s_sprites->wallEndDown); | ||
172 | p.drawTiledPixmap(0, 0, tileWidth, boundingRectHeight - split, s_sprites->wallV); | 207 | p.drawTiledPixmap(0, 0, tileWidth, boundingRectHeight - split, s_sprites->wallV); | ||
173 | break; | 208 | break; | ||
174 | } | 209 | | ||
175 | case Left: | 210 | case Left: | ||
176 | const int split = qMin(boundingRectWidth, tileWidth); | 211 | split = qMin(boundingRectWidth, tileWidth); | ||
177 | p.drawPixmap(0, 0, split, tileHeight, s_sprites->wallEndLeft); | 212 | p.drawPixmap(0, 0, split, tileHeight, s_sprites->wallEndLeft); | ||
178 | p.drawTiledPixmap(split, 0, boundingRectWidth - split, tileHeight, s_sprites->wallH, offset.x()); | 213 | p.drawTiledPixmap(split, 0, boundingRectWidth - split, tileHeight, s_sprites->wallH, offset.x()); | ||
214 | break; | ||||
179 | } | 215 | } | ||
216 | | ||||
180 | setPos(offset); | 217 | setPos(offset); | ||
181 | p.end(); | 218 | p.end(); | ||
182 | setPixmap(px); | 219 | setPixmap(px); | ||
183 | } | 220 | } | ||
184 | 221 | | |||
222 | /** | ||||
223 | * Load all sprites for top, down, left and right walls as well as for | ||||
224 | * the vertical and horizontal semi transparent bars drawn before a wall is | ||||
225 | * built. | ||||
226 | * @see wall.h | ||||
227 | */ | ||||
185 | void KBounceWall::loadSprites() { | 228 | void KBounceWall::loadSprites() { | ||
186 | s_sprites->wallEndLeft = m_renderer->spritePixmap(QStringLiteral("wallEndLeft"), s_tileSize); | 229 | s_sprites->wallEndLeft = m_renderer->spritePixmap(QStringLiteral("wallEndLeft"), s_tileSize); | ||
187 | s_sprites->wallEndUp = m_renderer->spritePixmap(QStringLiteral("wallEndUp"), s_tileSize); | 230 | s_sprites->wallEndUp = m_renderer->spritePixmap(QStringLiteral("wallEndUp"), s_tileSize); | ||
188 | s_sprites->wallEndRight = m_renderer->spritePixmap(QStringLiteral("wallEndRight"), s_tileSize); | 231 | s_sprites->wallEndRight = m_renderer->spritePixmap(QStringLiteral("wallEndRight"), s_tileSize); | ||
189 | s_sprites->wallEndDown = m_renderer->spritePixmap(QStringLiteral("wallEndDown"), s_tileSize); | 232 | s_sprites->wallEndDown = m_renderer->spritePixmap(QStringLiteral("wallEndDown"), s_tileSize); | ||
190 | 233 | | |||
191 | s_sprites->wallH = m_renderer->spritePixmap(QStringLiteral("wallH"), QSize(32 * s_tileSize.width(), s_tileSize.height())); | 234 | s_sprites->wallH = m_renderer->spritePixmap(QStringLiteral("wallH"), QSize(32 * s_tileSize.width(), s_tileSize.height())); | ||
192 | s_sprites->wallV = m_renderer->spritePixmap(QStringLiteral("wallV"), QSize(s_tileSize.width(), 18*s_tileSize.height())); | 235 | s_sprites->wallV = m_renderer->spritePixmap(QStringLiteral("wallV"), QSize(s_tileSize.width(), 18*s_tileSize.height())); | ||
193 | } | 236 | } | ||
194 | 237 | | |||
238 | | ||||
239 | /** | ||||
240 | * Changes on-screen dimensions of the wall. | ||||
241 | * Calculations are based on tile size, that is the on-screen | ||||
242 | * size of board's tile | ||||
243 | * @see wall.h | ||||
244 | */ | ||||
195 | void KBounceWall::resize( const QSize& tileSize ) | 245 | void KBounceWall::resize( const QSize& tileSize ) | ||
196 | { | 246 | { | ||
197 | if ( tileSize != s_tileSize ) { | 247 | if (tileSize != s_tileSize) | ||
248 | { | ||||
198 | s_tileSize = tileSize; | 249 | s_tileSize = tileSize; | ||
199 | loadSprites(); | 250 | loadSprites(); | ||
200 | update(); | 251 | update(); | ||
201 | } | 252 | } | ||
202 | } | 253 | } | ||
203 | 254 | | |||
255 | /** | ||||
256 | * Starts building wall beginning from tile specified by x and y | ||||
257 | * The direction has been specified in constructor | ||||
258 | * @see wall.h | ||||
259 | */ | ||||
204 | void KBounceWall::build( int x, int y ) | 260 | void KBounceWall::build(int x, int y) | ||
205 | { | 261 | { | ||
206 | if (isVisible()) | 262 | if (isVisible()) | ||
207 | return; | 263 | return; | ||
208 | 264 | | |||
209 | if ( m_dir == Up || m_dir == Down ) { | 265 | if ( m_dir == Up || m_dir == Down ) { | ||
210 | m_boundingRect.setTop( y ); | 266 | m_boundingRect.setTop(y); | ||
211 | 267 | | |||
212 | if (m_dir == Down) { | 268 | if (m_dir == Down) | ||
213 | m_boundingRect.setBottom(y + 1); | 269 | m_boundingRect.setBottom(y + 1); | ||
214 | } else { | 270 | else | ||
215 | m_boundingRect.setBottom( y ); | 271 | m_boundingRect.setBottom(y); | ||
216 | } | | |||
217 | 272 | | |||
218 | m_boundingRect.setLeft( x ); | 273 | m_boundingRect.setLeft(x); | ||
219 | m_boundingRect.setRight( x + 1 ); | 274 | m_boundingRect.setRight(x + 1); | ||
220 | } | 275 | } | ||
221 | else if ( m_dir == Left || m_dir == Right ) { | 276 | else if ( m_dir == Left || m_dir == Right ) | ||
277 | { | ||||
222 | m_boundingRect.setTop( y ); | 278 | m_boundingRect.setTop(y); | ||
223 | m_boundingRect.setBottom( y + 1 ); | 279 | m_boundingRect.setBottom(y + 1); | ||
224 | m_boundingRect.setLeft( x ); | 280 | m_boundingRect.setLeft(x); | ||
225 | 281 | | |||
226 | if (m_dir == Right) { | 282 | if (m_dir == Right) | ||
227 | m_boundingRect.setRight(x + 1); | 283 | m_boundingRect.setRight(x + 1); | ||
228 | } else { | 284 | else | ||
229 | m_boundingRect.setRight( x ); | 285 | m_boundingRect.setRight(x); | ||
230 | } | 286 | } | ||
231 | } | | |||
232 | 287 | | |||
233 | 288 | | |||
234 | m_nextBoundingRect = m_boundingRect; | 289 | m_nextBoundingRect = m_boundingRect; | ||
235 | 290 | | |||
236 | setPixmap(QPixmap()); | 291 | setPixmap(QPixmap()); | ||
237 | 292 | | |||
238 | setPos(m_board->mapPosition(QPointF( x, y ))); | 293 | setPos(m_board->mapPosition(QPointF( x, y ))); | ||
239 | show(); | 294 | show(); | ||
240 | 295 | | |||
241 | if ( KBounceSettings::playSounds() ) | 296 | if ( KBounceSettings::playSounds() ) | ||
242 | m_soundWallstart.start(); | 297 | m_soundWallstart.start(); | ||
243 | } | 298 | } | ||
244 | 299 | | |||
300 | /** | ||||
301 | * Returns the bounding rect that is expected for wall to | ||||
302 | * have in next frame. Collision in KBounceBoard are based on | ||||
303 | * the result of this method | ||||
304 | * @see wall.h | ||||
305 | */ | ||||
245 | QRectF KBounceWall::nextBoundingRect() const | 306 | QRectF KBounceWall::nextBoundingRect() const | ||
246 | { | 307 | { | ||
247 | return m_nextBoundingRect; | 308 | return m_nextBoundingRect; | ||
248 | } | 309 | } | ||
249 | 310 | | |||
311 | /** | ||||
312 | * Returns true if rect2 intersects the edge at the end of wall | ||||
313 | * e.g for wall extending in direction Up this will be the upper | ||||
314 | * edge. | ||||
315 | * @see wall.h | ||||
316 | */ | ||||
250 | bool KBounceWall::safeEdgeHit( const QRectF& rect2 ) const | 317 | bool KBounceWall::safeEdgeHit( const QRectF& rect2 ) const | ||
251 | { | 318 | { | ||
252 | bool safeEdgeHit = false; | 319 | bool safeEdgeHit = false; | ||
253 | 320 | | |||
254 | QPointF p1, p2, p3; | 321 | QPointF p1, p2, p3; | ||
255 | switch ( m_dir ) | 322 | switch (m_dir) | ||
256 | { | 323 | { | ||
257 | case Up: | 324 | case Up: | ||
258 | p1 = m_nextBoundingRect.topLeft(); | 325 | p1 = m_nextBoundingRect.topLeft(); | ||
259 | p2 = m_nextBoundingRect.topRight(); | 326 | p2 = m_nextBoundingRect.topRight(); | ||
260 | break; | 327 | break; | ||
328 | | ||||
261 | case Right: | 329 | case Right: | ||
262 | p1 = m_nextBoundingRect.topRight(); | 330 | p1 = m_nextBoundingRect.topRight(); | ||
263 | p2 = m_nextBoundingRect.bottomRight(); | 331 | p2 = m_nextBoundingRect.bottomRight(); | ||
264 | break; | 332 | break; | ||
333 | | ||||
265 | case Down: | 334 | case Down: | ||
266 | p1 = m_nextBoundingRect.bottomRight(); | 335 | p1 = m_nextBoundingRect.bottomRight(); | ||
267 | p2 = m_nextBoundingRect.bottomLeft(); | 336 | p2 = m_nextBoundingRect.bottomLeft(); | ||
268 | break; | 337 | break; | ||
338 | | ||||
269 | case Left: | 339 | case Left: | ||
270 | p1 = m_nextBoundingRect.bottomLeft(); | 340 | p1 = m_nextBoundingRect.bottomLeft(); | ||
271 | p2 = m_nextBoundingRect.topLeft(); | 341 | p2 = m_nextBoundingRect.topLeft(); | ||
272 | break; | 342 | break; | ||
343 | | ||||
273 | default: | 344 | default: | ||
274 | Q_ASSERT(false); | 345 | Q_ASSERT(false); | ||
275 | break; | 346 | break; | ||
276 | } | 347 | } | ||
277 | p3.setX( ( p1.x() + p2.x() ) / 2.0 ); | 348 | p3.setX( ( p1.x() + p2.x() ) / 2.0 ); | ||
278 | p3.setY( ( p1.y() + p2.y() ) / 2.0 ); | 349 | p3.setY( ( p1.y() + p2.y() ) / 2.0 ); | ||
279 | 350 | | |||
280 | if ( rect2.contains( p1 ) ) | 351 | if ( rect2.contains( p1 ) ) | ||
281 | safeEdgeHit = true; | 352 | safeEdgeHit = true; | ||
282 | else if ( rect2.contains( p2 ) ) | 353 | else if ( rect2.contains( p2 ) ) | ||
283 | safeEdgeHit = true; | 354 | safeEdgeHit = true; | ||
284 | else if ( rect2.contains( p3 ) ) | 355 | else if ( rect2.contains( p3 ) ) | ||
285 | safeEdgeHit = true; | 356 | safeEdgeHit = true; | ||
286 | 357 | | |||
287 | return safeEdgeHit; | 358 | return safeEdgeHit; | ||
288 | } | 359 | } | ||
289 | 360 | | |||
361 | /** | ||||
362 | * Helper function replacing emiting long finished signal | ||||
363 | * It also hides the wall and plays corresponding sound | ||||
364 | * If ¶m shorten is true the wall will be one unit in | ||||
365 | * direction ¶m dir shorter than normal | ||||
366 | * @see wall.h | ||||
367 | */ | ||||
290 | void KBounceWall::finish( bool shorten, Direction dir ) | 368 | void KBounceWall::finish(bool shorten, Direction dir) | ||
291 | { | 369 | { | ||
292 | int left = static_cast<int>( m_boundingRect.left() ); | 370 | int left = static_cast<int>( m_boundingRect.left() ); | ||
293 | int top = static_cast<int>( m_boundingRect.top() ); | 371 | int top = static_cast<int>( m_boundingRect.top() ); | ||
294 | int right = static_cast<int>( m_boundingRect.right() ); | 372 | int right = static_cast<int>( m_boundingRect.right() ); | ||
295 | int bottom = static_cast<int>( m_boundingRect.bottom() ); | 373 | int bottom = static_cast<int>( m_boundingRect.bottom() ); | ||
296 | 374 | | |||
297 | if ( shorten ) { | 375 | if (shorten) | ||
298 | switch ( dir ) | 376 | switch (dir) | ||
299 | { | 377 | { | ||
300 | case Left: left++; break; | 378 | case Left: left++; break; | ||
301 | case Up: top++; break; | 379 | case Up: top++; break; | ||
302 | case Right: right--; break; | 380 | case Right: right--; break; | ||
303 | case Down: bottom--; break; | 381 | case Down: bottom--; break; | ||
304 | } | 382 | } | ||
305 | } | | |||
306 | 383 | | |||
307 | emit finished( left, top, right, bottom ); | 384 | emit finished( left, top, right, bottom ); | ||
308 | hide(); | 385 | hide(); | ||
309 | 386 | | |||
310 | if (KBounceSettings::playSounds()) | 387 | if (KBounceSettings::playSounds()) | ||
311 | m_soundReflect.start(); | 388 | m_soundReflect.start(); | ||
312 | } | 389 | } | ||
313 | 390 | | |||
391 | /** | ||||
392 | * Set the wall velocity for wall filling speed. | ||||
393 | * @param velocity new wall velocity | ||||
394 | * @see wall.h | ||||
395 | */ | ||||
314 | void KBounceWall::setWallVelocity(qreal velocity) | 396 | void KBounceWall::setWallVelocity(qreal velocity) | ||
315 | { | 397 | { | ||
316 | m_wallVelocity = velocity; | 398 | m_wallVelocity = velocity; | ||
317 | } | 399 | } | ||
318 | 400 | | |||
319 | 401 | | |||
320 | 402 | | |||
321 | 403 | |