1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
46 #include "pixmapitem.h"
47 #include "graphicsscene.h"
48 #include "animationmanager.h"
49 #include "custompropertyanimation.h"
50 #include "qanimationstate.h"
53 #include <QtCore/QPropertyAnimation>
54 #include <QtCore/QStateMachine>
55 #include <QtCore/QHistoryState>
56 #include <QtCore/QFinalState>
57 #include <QtCore/QState>
58 #include <QtCore/QSequentialAnimationGroup>
60 static QAbstractAnimation
*setupDestroyAnimation(Boat
*boat
)
62 QSequentialAnimationGroup
*group
= new QSequentialAnimationGroup(boat
);
63 #if QT_VERSION >=0x040500
64 PixmapItem
*step1
= new PixmapItem(QString("explosion/boat/step1"),GraphicsScene::Big
, boat
);
66 PixmapItem
*step2
= new PixmapItem(QString("explosion/boat/step2"),GraphicsScene::Big
, boat
);
68 PixmapItem
*step3
= new PixmapItem(QString("explosion/boat/step3"),GraphicsScene::Big
, boat
);
70 PixmapItem
*step4
= new PixmapItem(QString("explosion/boat/step4"),GraphicsScene::Big
, boat
);
76 CustomPropertyAnimation
*anim1
= new CustomPropertyAnimation(boat
);
77 anim1
->setMemberFunctions((QGraphicsItem
*)step1
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
78 anim1
->setDuration(100);
79 anim1
->setEndValue(1);
80 CustomPropertyAnimation
*anim2
= new CustomPropertyAnimation(boat
);
81 anim2
->setMemberFunctions((QGraphicsItem
*)step2
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
82 anim2
->setDuration(100);
83 anim2
->setEndValue(1);
84 CustomPropertyAnimation
*anim3
= new CustomPropertyAnimation(boat
);
85 anim3
->setMemberFunctions((QGraphicsItem
*)step3
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
86 anim3
->setDuration(100);
87 anim3
->setEndValue(1);
88 CustomPropertyAnimation
*anim4
= new CustomPropertyAnimation(boat
);
89 anim4
->setMemberFunctions((QGraphicsItem
*)step4
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
90 anim4
->setDuration(100);
91 anim4
->setEndValue(1);
92 CustomPropertyAnimation
*anim5
= new CustomPropertyAnimation(boat
);
93 anim5
->setMemberFunctions((QGraphicsItem
*)step1
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
94 anim5
->setDuration(100);
95 anim5
->setEndValue(0);
96 CustomPropertyAnimation
*anim6
= new CustomPropertyAnimation(boat
);
97 anim6
->setMemberFunctions((QGraphicsItem
*)step2
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
98 anim6
->setDuration(100);
99 anim6
->setEndValue(0);
100 CustomPropertyAnimation
*anim7
= new CustomPropertyAnimation(boat
);
101 anim7
->setMemberFunctions((QGraphicsItem
*)step3
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
102 anim7
->setDuration(100);
103 anim7
->setEndValue(0);
104 CustomPropertyAnimation
*anim8
= new CustomPropertyAnimation(boat
);
105 anim8
->setMemberFunctions((QGraphicsItem
*)step4
, &QGraphicsItem::opacity
, &QGraphicsItem::setOpacity
);
106 anim8
->setDuration(100);
107 anim8
->setEndValue(0);
108 group
->addAnimation(anim1
);
109 group
->addAnimation(anim2
);
110 group
->addAnimation(anim3
);
111 group
->addAnimation(anim4
);
112 group
->addAnimation(anim5
);
113 group
->addAnimation(anim6
);
114 group
->addAnimation(anim7
);
115 group
->addAnimation(anim8
);
117 // work around for a bug where we don't transition if the duration is zero.
118 QtPauseAnimation
*anim
= new QtPauseAnimation(group
);
119 anim
->setDuration(1);
120 group
->addAnimation(anim
);
122 AnimationManager::self()->registerAnimation(group
);
128 Boat::Boat(QGraphicsItem
* parent
, Qt::WindowFlags wFlags
)
129 : QGraphicsWidget(parent
,wFlags
), speed(0), bombsAlreadyLaunched(0), direction(Boat::None
), movementAnimation(0)
131 pixmapItem
= new PixmapItem(QString("boat"),GraphicsScene::Big
, this);
133 setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
134 setFlags(QGraphicsItem::ItemIsMovable
| QGraphicsItem::ItemIsFocusable
);
135 resize(pixmapItem
->boundingRect().size());
137 //The movement animation used to animate the boat
138 movementAnimation
= new QPropertyAnimation(this, "pos");
140 //The movement animation used to animate the boat
141 destroyAnimation
= setupDestroyAnimation(this);
143 //We setup the state machien of the boat
144 machine
= new QStateMachine(this);
145 QState
*moving
= new QState(machine
);
146 StopState
*stopState
= new StopState(this, moving
);
147 machine
->setInitialState(moving
);
148 moving
->setInitialState(stopState
);
149 MoveStateRight
*moveStateRight
= new MoveStateRight(this, moving
);
150 MoveStateLeft
*moveStateLeft
= new MoveStateLeft(this, moving
);
151 LaunchStateRight
*launchStateRight
= new LaunchStateRight(this, machine
);
152 LaunchStateLeft
*launchStateLeft
= new LaunchStateLeft(this, machine
);
154 //then setup the transitions for the rightMove state
155 KeyStopTransition
*leftStopRight
= new KeyStopTransition(this, QEvent::KeyPress
, Qt::Key_Left
);
156 leftStopRight
->setTargetState(stopState
);
157 KeyMoveTransition
*leftMoveRight
= new KeyMoveTransition(this, QEvent::KeyPress
, Qt::Key_Left
);
158 leftMoveRight
->setTargetState(moveStateRight
);
159 KeyMoveTransition
*rightMoveRight
= new KeyMoveTransition(this, QEvent::KeyPress
, Qt::Key_Right
);
160 rightMoveRight
->setTargetState(moveStateRight
);
161 KeyMoveTransition
*rightMoveStop
= new KeyMoveTransition(this, QEvent::KeyPress
, Qt::Key_Right
);
162 rightMoveStop
->setTargetState(moveStateRight
);
164 //then setup the transitions for the leftMove state
165 KeyStopTransition
*rightStopLeft
= new KeyStopTransition(this, QEvent::KeyPress
, Qt::Key_Right
);
166 rightStopLeft
->setTargetState(stopState
);
167 KeyMoveTransition
*rightMoveLeft
= new KeyMoveTransition(this, QEvent::KeyPress
, Qt::Key_Right
);
168 rightMoveLeft
->setTargetState(moveStateLeft
);
169 KeyMoveTransition
*leftMoveLeft
= new KeyMoveTransition(this, QEvent::KeyPress
,Qt::Key_Left
);
170 leftMoveLeft
->setTargetState(moveStateLeft
);
171 KeyMoveTransition
*leftMoveStop
= new KeyMoveTransition(this, QEvent::KeyPress
,Qt::Key_Left
);
172 leftMoveStop
->setTargetState(moveStateLeft
);
174 //We set up the right move state
175 moveStateRight
->addTransition(leftStopRight
);
176 moveStateRight
->addTransition(leftMoveRight
);
177 moveStateRight
->addTransition(rightMoveRight
);
178 stopState
->addTransition(rightMoveStop
);
180 //We set up the left move state
181 moveStateLeft
->addTransition(rightStopLeft
);
182 moveStateLeft
->addTransition(leftMoveLeft
);
183 moveStateLeft
->addTransition(rightMoveLeft
);
184 stopState
->addTransition(leftMoveStop
);
186 //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state
187 moveStateLeft
->addTransition(movementAnimation
, SIGNAL(finished()), stopState
);
188 moveStateRight
->addTransition(movementAnimation
, SIGNAL(finished()), stopState
);
190 //We set up the keys for dropping bombs
191 KeyLaunchTransition
*upFireLeft
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Up
);
192 upFireLeft
->setTargetState(launchStateRight
);
193 KeyLaunchTransition
*upFireRight
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Up
);
194 upFireRight
->setTargetState(launchStateRight
);
195 KeyLaunchTransition
*upFireStop
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Up
);
196 upFireStop
->setTargetState(launchStateRight
);
197 KeyLaunchTransition
*downFireLeft
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Down
);
198 downFireLeft
->setTargetState(launchStateLeft
);
199 KeyLaunchTransition
*downFireRight
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Down
);
200 downFireRight
->setTargetState(launchStateLeft
);
201 KeyLaunchTransition
*downFireMove
= new KeyLaunchTransition(this, QEvent::KeyPress
, Qt::Key_Down
);
202 downFireMove
->setTargetState(launchStateLeft
);
204 //We set up transitions for fire up
205 moveStateRight
->addTransition(upFireRight
);
206 moveStateLeft
->addTransition(upFireLeft
);
207 stopState
->addTransition(upFireStop
);
209 //We set up transitions for fire down
210 moveStateRight
->addTransition(downFireRight
);
211 moveStateLeft
->addTransition(downFireLeft
);
212 stopState
->addTransition(downFireMove
);
214 //Finally the launch state should come back to its original state
215 QHistoryState
*historyState
= new QHistoryState(moving
);
216 launchStateLeft
->addTransition(historyState
);
217 launchStateRight
->addTransition(historyState
);
219 QFinalState
*final
= new QFinalState(machine
);
221 //This state play the destroyed animation
222 QAnimationState
*destroyedState
= new QAnimationState(machine
);
223 destroyedState
->setAnimation(destroyAnimation
);
225 //Play a nice animation when the boat is destroyed
226 moving
->addTransition(this, SIGNAL(boatDestroyed()),destroyedState
);
228 //Transition to final state when the destroyed animation is finished
229 destroyedState
->addTransition(destroyedState
, SIGNAL(animationFinished()), final
);
231 //The machine has finished to be executed, then the boat is dead
232 connect(machine
,SIGNAL(finished()),this, SIGNAL(boatExecutionFinished()));
238 //We register animations
239 AnimationManager::self()->registerAnimation(movementAnimation
);
240 AnimationManager::self()->registerAnimation(destroyAnimation
);
246 movementAnimation
->stop();
250 void Boat::updateBoatMovement()
252 if (speed
== 0 || direction
== Boat::None
) {
253 movementAnimation
->stop();
257 movementAnimation
->stop();
258 movementAnimation
->setStartValue(pos());
260 if (direction
== Boat::Left
) {
261 movementAnimation
->setEndValue(QPointF(0,y()));
262 movementAnimation
->setDuration(x()/speed
*15);
264 else /*if (direction == Boat::Right)*/ {
265 movementAnimation
->setEndValue(QPointF(scene()->width()-size().width(),y()));
266 movementAnimation
->setDuration((scene()->width()-size().width()-x())/speed
*15);
268 movementAnimation
->start();
273 movementAnimation
->stop();
274 emit
boatDestroyed();
277 int Boat::bombsLaunched() const
279 return bombsAlreadyLaunched
;
282 void Boat::setBombsLaunched(int number
)
284 if (number
> MAX_BOMB
) {
285 qWarning("Boat::setBombsLaunched : It impossible to launch that number of bombs");
288 bombsAlreadyLaunched
= number
;
291 int Boat::currentSpeed() const
296 void Boat::setCurrentSpeed(int speed
)
298 if (speed
> 3 || speed
< 0) {
299 qWarning("Boat::setCurrentSpeed: The boat can't run on that speed");
305 enum Boat::Movement
Boat::currentDirection() const
310 void Boat::setCurrentDirection(Movement direction
)
312 this->direction
= direction
;
315 int Boat::type() const