• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

granatier

  • sources
  • kde-4.14
  • kdegames
  • granatier
  • src
playeritem.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2009 Mathias Kraus <k.hias@gmx.de>
3  * Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
4  * Copyright 2007-2008 Nathalie Liesse <nathalie.liesse@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #include "playeritem.h"
22 #include "player.h"
23 #include "bonus.h"
24 #include "bonusitem.h"
25 #include "bomb.h"
26 #include "bombitem.h"
27 #include "bombexplosionitem.h"
28 
29 #include <QTimeLine>
30 
31 #include <KStandardDirs>
32 #include <KGameRenderer>
33 
34 const int PlayerItem::NB_FRAMES = 13;
35 const int PlayerItem::ANIM_SPEED = 240;
36 
37 PlayerItem::PlayerItem(Player* p_model, KGameRenderer* renderer) : CharacterItem(p_model, renderer)
38 {
39  connect(p_model, SIGNAL(directionChanged()), this, SLOT(updateDirection()));
40  connect(p_model, SIGNAL(gameUpdated()), this, SLOT(manageCollision()));
41  connect(p_model, SIGNAL(stopped()), this, SLOT(stopAnim()));
42  connect(p_model, SIGNAL(falling()), this, SLOT(fallingAnimation()));
43  connect(p_model, SIGNAL(resurrected()), this, SLOT(resurrect()));
44 
45  // A timeLine for the Player animation
46  m_animationTimer = new QTimeLine();
47  m_animationTimer->setCurveShape(QTimeLine::LinearCurve);
48  m_animationTimer->setLoopCount(0);
49  m_animationTimer->setFrameRange(0, NB_FRAMES - 1);
50  // Animation speed
51  m_animationTimer->setDuration(PlayerItem::ANIM_SPEED);
52  connect(m_animationTimer, SIGNAL(frameChanged(int)), this, SLOT(setFrame(int)));
53 
54  int width = Granatier::CellSize * 0.9;
55  int height = Granatier::CellSize * 0.9;
56  if(((int) Granatier::CellSize - width) % 2 != 0)
57  {
58  width--;
59  }
60  if(((int) Granatier::CellSize - height) % 2 != 0)
61  {
62  height--;
63  }
64  m_itemSizeSet = QSize(width, height);
65  m_itemSizeReal = m_itemSizeSet;
66 
67  if(m_renderer->spriteExists("player_0"))
68  {
69  setSpriteKey("player_0");
70  }
71 
72  setZValue(250);
73 
74  m_fallingAnimationCounter = 0;
75  m_resurrectionAnimationCounter = 0;
76 }
77 
78 PlayerItem::~PlayerItem()
79 {
80  delete m_animationTimer;
81 }
82 
83 void PlayerItem::resurrect()
84 {
85  int nDirection = dynamic_cast <Player*> (m_model)->direction();
86  setZValue(250);
87  m_fallingAnimationCounter = 0;
88  m_resurrectionAnimationCounter = 10;
89  setRenderSize(m_renderSize);
90  if(m_renderer->spriteExists("player_0"))
91  {
92  setSpriteKey("player_0");
93  }
94 
95  QTransform transform;
96  transform.translate(m_itemSizeSet.width() / 2.0, m_itemSizeSet.height() / 2.0);
97  // get the angle
98  switch(nDirection)
99  {
100  case Granatier::Direction::EAST:
101  transform.rotate(0);
102  break;
103  case Granatier::Direction::SOUTH:
104  transform.rotate(90);
105  break;
106  case Granatier::Direction::NORTH:
107  transform.rotate(-90);
108  break;
109  case Granatier::Direction::WEST:
110  transform.rotate(180);
111  break;
112  default:
113  transform.rotate(0);
114  break;
115  }
116  transform.translate(-m_itemSizeReal.width() / 2.0, -m_itemSizeReal.height() / 2.0);
117  setTransform(transform);
118 
119  startAnim();
120 
121  setVisible(true);
122 }
123 
124 void PlayerItem::updateDirection()
125 {
126  int nDirection = dynamic_cast <Player*> (m_model)->direction();
127 
128  // Rotate the item
129  QTransform transform;
130  transform.translate(m_itemSizeSet.width() / 2.0, m_itemSizeSet.height() / 2.0);
131  // get the angle
132  switch(nDirection)
133  {
134  case Granatier::Direction::EAST:
135  transform.rotate(0);
136  break;
137  case Granatier::Direction::SOUTH:
138  transform.rotate(90);
139  break;
140  case Granatier::Direction::NORTH:
141  transform.rotate(-90);
142  break;
143  case Granatier::Direction::WEST:
144  transform.rotate(180);
145  break;
146  default:
147  transform.rotate(0);
148  break;
149  }
150  transform.translate(-m_itemSizeReal.width() / 2.0, -m_itemSizeReal.height() / 2.0);
151  setTransform(transform);
152 }
153 
154 void PlayerItem::updateGraphics(qreal svgScaleFactor)
155 {
156  updateGraphicsInternal(svgScaleFactor);
157  updateDirection();
158 }
159 
160 void PlayerItem::manageCollision()
161 {
162  QList<QGraphicsItem*> collidingList = collidingItems();
163  BonusItem* bonusItem;
164 
165  // The signal is emitted only if the list contains more than 1 items (to exclude the case
166  // when the player only collides with the arena)
167  if (collidingList.size() > 1)
168  {
169  for (int i = 0; i < collidingList.size(); ++i)
170  {
171  // The arena and the points labels have a negative zValue which allows to exclude them from the treatment of collisions
172  if (collidingList[i]->zValue() >= 300 && collidingList[i]->zValue() < 400)
173  {
174  //((ElementItem*)collidingList[i])->getModel()->doActionOnCollision((Player*)getModel());
175  int nExplosionID;
176  if(collidingList[i]->zValue() == 315)
177  {
178  BombItem* bombItem = dynamic_cast <BombItem*> (collidingList[i]);
179  nExplosionID = dynamic_cast <Bomb*> (bombItem->getModel())->explosionID();
180  }
181  else
182  {
183  nExplosionID = dynamic_cast <BombExplosionItem*> (collidingList[i])->explosionID();
184  }
185 
186  if(dynamic_cast <Player*> (m_model)->shield(nExplosionID) == false)
187  {
188  setDead();
189  dynamic_cast <Player*> (m_model)->die();
190  }
191  }
192  else if (collidingList[i]->zValue() == 100)
193  {
194  bonusItem = dynamic_cast <BonusItem*> (collidingList[i]);
195  if(dynamic_cast <Bonus*> (bonusItem->getModel())->isTaken() == false)
196  {
197  dynamic_cast <Bonus*> (bonusItem->getModel())->setTaken();
198  bonusItem->getModel()->doActionOnCollision(dynamic_cast <Player*> (this->getModel()));
199  emit bonusItemTaken(bonusItem);
200  }
201  }
202  }
203  }
204 }
205 
206 void PlayerItem::update(qreal p_x, qreal p_y)
207 {
208  ElementItem::update(p_x, p_y);
209 
210  // If the player is moving
211  if (((Player*)getModel())->getXSpeed() != 0 || ((Player*)getModel())->getYSpeed() != 0)
212  {
213  startAnim();
214  }
215 }
216 
217 void PlayerItem::startAnim()
218 {
219  // Start the animation timer if it is not active
220  if (m_animationTimer->state() != QTimeLine::Running)
221  {
222  m_animationTimer->start();
223  }
224 }
225 
226 void PlayerItem::pauseAnim()
227 {
228  dynamic_cast <Player*> (m_model)->pause();
229  if (m_animationTimer->state() == QTimeLine::Running)
230  {
231  m_animationTimer->setPaused(true);
232  }
233 }
234 
235 void PlayerItem::resumeAnim()
236 {
237  dynamic_cast <Player*> (m_model)->resume();
238  if (m_animationTimer->state() == QTimeLine::Paused)
239  {
240  m_animationTimer->setPaused(false);
241  }
242 }
243 
244 void PlayerItem::stopAnim()
245 {
246  if(m_renderer->spriteExists("player_0"))
247  {
248  setSpriteKey("player_0");
249  }
250  if (m_animationTimer->state() != QTimeLine::NotRunning && m_resurrectionAnimationCounter == 0)
251  {
252  m_animationTimer->stop();
253  }
254 }
255 
256 void PlayerItem::fallingAnimation()
257 {
258  m_fallingAnimationCounter = 1;
259 }
260 
261 void PlayerItem::setFrame(const int p_frame)
262 {
263  if(m_renderer->spriteExists(QString("player_%1").arg(p_frame)))
264  {
265  setSpriteKey(QString("player_%1").arg(p_frame));
266 
267  if(m_fallingAnimationCounter > 0 || m_resurrectionAnimationCounter > 0)
268  {
269  int angle = 0;
270  int nDirection = dynamic_cast <Player*> (m_model)->direction();
271 
272  // get the angle
273  switch(nDirection)
274  {
275  case Granatier::Direction::EAST:
276  angle = 0;
277  break;
278  case Granatier::Direction::SOUTH:
279  angle = 90;
280  break;
281  case Granatier::Direction::NORTH:
282  angle = -90;
283  break;
284  case Granatier::Direction::WEST:
285  angle = 180;
286  break;
287  default:
288  angle = 0;
289  break;
290  }
291 
292  if(m_fallingAnimationCounter > 0)
293  {
294  // set z-value below the ground
295  setZValue(-2);
296  // shrink the item
297  QTransform transform;
298  transform.translate(m_itemSizeSet.width() / 2.0, m_itemSizeSet.width() / 2.0);
299  transform.rotate(angle);
300  setRenderSize(m_renderSize * (1-m_fallingAnimationCounter*0.02));
301  transform.translate(-m_itemSizeReal.width() * (1-m_fallingAnimationCounter*0.02) / 2.0, -m_itemSizeReal.width() * (1-m_fallingAnimationCounter*0.02) / 2.0);
302  setTransform(transform);
303  m_fallingAnimationCounter++;
304 
305  if(m_fallingAnimationCounter > 50)
306  {
307  setDead();
308  dynamic_cast <Player*> (m_model)->die();
309  setVisible(false);
310  }
311  }
312 
313  if(m_resurrectionAnimationCounter > 0)
314  {
315  qreal resurrectionScale = 1;
316  QTransform transform;
317  transform.translate(m_itemSizeSet.width() / 2.0, m_itemSizeSet.width() / 2.0);
318  transform.rotate(angle);
319  if(m_resurrectionAnimationCounter > 9)
320  {
321  resurrectionScale = 1.1;
322  }
323  else if(m_resurrectionAnimationCounter > 8)
324  {
325  resurrectionScale = 0.9;
326  }
327  else if(m_resurrectionAnimationCounter > 7)
328  {
329  resurrectionScale = 0.6;
330  }
331  else if(m_resurrectionAnimationCounter > 6)
332  {
333  resurrectionScale = 0.7;
334  }
335  else if(m_resurrectionAnimationCounter > 5)
336  {
337  resurrectionScale = 0.85;
338  }
339  else if(m_resurrectionAnimationCounter > 4)
340  {
341  resurrectionScale = 1;
342  }
343  else if(m_resurrectionAnimationCounter > 3)
344  {
345  resurrectionScale = 1.05;
346  }
347  else if(m_resurrectionAnimationCounter > 2)
348  {
349  resurrectionScale = 1.1;
350  }
351  else if(m_resurrectionAnimationCounter > 1)
352  {
353  resurrectionScale = 1.05;
354  }
355  else if(m_resurrectionAnimationCounter > 0)
356  {
357  resurrectionScale = 1;
358  }
359 
360  m_resurrectionAnimationCounter--;
361  if(m_resurrectionAnimationCounter == 0)
362  {
363  resurrectionScale = 1;
364  stopAnim();
365  }
366 
367  setRenderSize(m_renderSize * resurrectionScale);
368  transform.translate(-m_itemSizeReal.width() * resurrectionScale / 2.0, -m_itemSizeReal.width() * resurrectionScale / 2.0);
369  setTransform(transform);
370  }
371  }
372  }
373 }
374 
375 void PlayerItem::setDead()
376 {
377  stopAnim();
378  setZValue(1);
379  if(m_resurrectionAnimationCounter != 0)
380  {
381  QTransform transform;
382  transform.translate(m_itemSizeSet.width() / 2.0, m_itemSizeSet.height() / 2.0);
383  setRenderSize(m_renderSize);
384  transform.translate(-m_itemSizeReal.width() / 2.0, -m_itemSizeReal.height() / 2.0);
385  setTransform(transform);
386  }
387  if(m_renderer->spriteExists("player_death"))
388  {
389  setSpriteKey("player_death");
390  }
391 }
QTransform
QSize::width
int width() const
PlayerItem::pauseAnim
void pauseAnim()
Pauses the PlayerItem animation.
Definition: playeritem.cpp:226
ElementItem::update
virtual void update(qreal p_x, qreal p_y)
Updates the ElementItem coordinates.
Definition: elementitem.cpp:55
bombitem.h
playeritem.h
QTimeLine::setFrameRange
void setFrameRange(int startFrame, int endFrame)
Bonus
This class represents a Bonus for the Player.
Definition: bonus.h:29
PlayerItem::startAnim
void startAnim()
Starts the PlayerItem animation.
Definition: playeritem.cpp:217
BombItem
This class is the graphical representation of a Bomb.
Definition: bombitem.h:31
QTimeLine::setDuration
void setDuration(int duration)
QTimeLine::setPaused
void setPaused(bool paused)
QTimeLine::setLoopCount
void setLoopCount(int count)
bombexplosionitem.h
player.h
PlayerItem::resumeAnim
void resumeAnim()
Resumes the PlayerItem animation.
Definition: playeritem.cpp:235
QList::size
int size() const
ElementItem::getModel
Element * getModel() const
Gets the Element model.
Definition: elementitem.cpp:43
ElementItem::m_itemSizeSet
QSize m_itemSizeSet
Definition: elementitem.h:44
BonusItem
This class is the graphical representation of a Bonus.
Definition: bonusitem.h:30
PlayerItem::~PlayerItem
~PlayerItem()
Deletes the PlayerItem instance.
Definition: playeritem.cpp:78
QTimeLine::setCurveShape
void setCurveShape(CurveShape shape)
PlayerItem::updateDirection
void updateDirection()
Rotates the image function of the Player direction.
Definition: playeritem.cpp:124
CharacterItem
This class is the graphical representation of a Character.
Definition: characteritem.h:30
QTransform::translate
QTransform & translate(qreal dx, qreal dy)
Granatier::CellSize
const qreal CellSize
The Cell size.
Definition: granatierglobals.h:31
bonusitem.h
Granatier::Direction::WEST
Definition: granatierglobals.h:129
ElementItem::m_model
Element * m_model
The instance of Element the ElementItem will represent.
Definition: elementitem.h:40
PlayerItem::PlayerItem
PlayerItem(Player *p_model, KGameRenderer *renderer)
Creates a new PlayerItem instance.
Definition: playeritem.cpp:37
BombExplosionItem
This class is the graphical representation of a Bomb explosion.
Definition: bombexplosionitem.h:33
Bomb
This class describes the common characteristics and behaviour of the bomb item.
Definition: bomb.h:30
Element::doActionOnCollision
virtual void doActionOnCollision(Player *p_player)
Computes an action on a collision with the Player.
Definition: element.cpp:30
ElementItem::updateGraphicsInternal
virtual void updateGraphicsInternal(qreal svgScaleFactor)
Definition: elementitem.cpp:70
QString
QList
bonus.h
Granatier::Direction::NORTH
Definition: granatierglobals.h:126
QSize
QTransform::rotate
QTransform & rotate(qreal angle, Qt::Axis axis)
CharacterItem::m_renderer
KGameRenderer * m_renderer
Shared renderer for the player frames.
Definition: characteritem.h:36
PlayerItem::stopAnim
void stopAnim()
Stops the PlayerItem animation.
Definition: playeritem.cpp:244
PlayerItem::setFrame
void setFrame(const int p_frame)
Sets the given frame to the PlayerItem.
Definition: playeritem.cpp:261
PlayerItem::manageCollision
void manageCollision()
Manages the collisions with any Element.
Definition: playeritem.cpp:160
PlayerItem::resurrect
void resurrect()
resurrects the playeritem
Definition: playeritem.cpp:83
PlayerItem::updateGraphics
void updateGraphics(qreal svgScaleFactor)
Definition: playeritem.cpp:154
PlayerItem::update
void update(qreal p_x, qreal p_y)
Updates the PlayerItem coordinates.
Definition: playeritem.cpp:206
QSize::height
int height() const
QTimeLine::stop
void stop()
PlayerItem::fallingAnimation
void fallingAnimation()
the animation when falling in a hole
Definition: playeritem.cpp:256
QTimeLine
Granatier::Direction::EAST
Definition: granatierglobals.h:128
ElementItem::m_renderSize
QSize m_renderSize
Definition: elementitem.h:42
PlayerItem::bonusItemTaken
void bonusItemTaken(BonusItem *bonusItem)
PlayerItem::setDead
void setDead()
Implements the CharacterItem method.
Definition: playeritem.cpp:375
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
ElementItem::m_itemSizeReal
QSize m_itemSizeReal
Definition: elementitem.h:45
Player
This class represents the main character of the game.
Definition: player.h:33
bomb.h
QTimeLine::start
void start()
QTimeLine::state
State state() const
Granatier::Direction::SOUTH
Definition: granatierglobals.h:127
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

granatier

Skip menu "granatier"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal