File indexing completed on 2023-10-01 08:02:05
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Thomas Gallinari <tg8187@yahoo.fr> 0003 SPDX-FileCopyrightText: 2007-2008 Nathalie Liesse <nathalie.liesse@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kapmanitem.h" 0009 #include "ghost.h" 0010 #include "settings.h" 0011 0012 #include <KgDifficulty> 0013 #include <QGraphicsScene> 0014 0015 const int KapmanItem::NB_FRAMES = 32; 0016 const int KapmanItem::ANIM_LOW_SPEED = 500; 0017 const int KapmanItem::ANIM_MEDIUM_SPEED = 400; 0018 const int KapmanItem::ANIM_HIGH_SPEED = 300; 0019 0020 KapmanItem::KapmanItem(Kapman *p_model) 0021 : CharacterItem(p_model) 0022 { 0023 connect(p_model, &Kapman::directionChanged, this, &KapmanItem::updateDirection); 0024 connect(p_model, &Kapman::gameUpdated, this, &KapmanItem::manageCollision); 0025 connect(p_model, &Kapman::stopped, this, &KapmanItem::stopAnim); 0026 0027 // A timeLine for the Kapman animation 0028 m_animationTimer = new QTimeLine(); 0029 m_animationTimer->setEasingCurve(QEasingCurve::SineCurve); 0030 m_animationTimer->setLoopCount(0); 0031 m_animationTimer->setFrameRange(0, NB_FRAMES - 1); 0032 // Animation speed 0033 switch ((int)Kg::difficultyLevel()) { 0034 case KgDifficultyLevel::Easy: 0035 m_animationTimer->setDuration(KapmanItem::ANIM_LOW_SPEED); 0036 break; 0037 case KgDifficultyLevel::Medium: 0038 m_animationTimer->setDuration(KapmanItem::ANIM_MEDIUM_SPEED); 0039 break; 0040 case KgDifficultyLevel::Hard: 0041 m_animationTimer->setDuration(KapmanItem::ANIM_HIGH_SPEED); 0042 break; 0043 } 0044 connect(m_animationTimer, &QTimeLine::frameChanged, this, &KapmanItem::setFrame); 0045 0046 // Define the timer which sets the blinking frequency 0047 m_blinkTimer = new QTimer(this); 0048 m_blinkTimer->setInterval(400); 0049 connect(m_blinkTimer, &QTimer::timeout, this, &KapmanItem::blink); 0050 } 0051 0052 KapmanItem::~KapmanItem() 0053 { 0054 delete m_animationTimer; 0055 } 0056 0057 void KapmanItem::updateDirection() 0058 { 0059 QTransform transform; 0060 int angle = 0; 0061 auto model = (Kapman *)getModel(); 0062 0063 // Compute the angle 0064 if (model->getXSpeed() > 0) { 0065 angle = 0; 0066 } else if (model->getXSpeed() < 0) { 0067 angle = 180; // The default image is right oriented 0068 } 0069 if (model->getYSpeed() > 0) { 0070 angle = 90; 0071 } else if (model->getYSpeed() < 0) { 0072 angle = -90; 0073 } 0074 0075 if (m_rotationFlag == 0) { 0076 angle = 0; 0077 } 0078 // Rotate the item 0079 transform.translate(boundingRect().width() / 2, boundingRect().height() / 2); 0080 transform.rotate(angle); 0081 transform.translate(-boundingRect().width() / 2, -boundingRect().height() / 2); 0082 setTransform(transform); 0083 } 0084 0085 void KapmanItem::manageCollision() 0086 { 0087 QList<QGraphicsItem *> collidingList = collidingItems(); 0088 0089 // The signal is emitted only if the list contains more than 1 items (to exclude the case 0090 // when the kapman only collides with the maze) 0091 if (collidingList.size() > 1) { 0092 for (int i = 0; i < collidingList.size(); ++i) { 0093 // The maze and the points labels have a negative zValue which allows to exclude them from the treatment of collisions 0094 if (collidingList[i]->zValue() >= 0) { 0095 auto item = dynamic_cast<ElementItem *>(collidingList[i]); 0096 if (item) { 0097 item->getModel()->doActionOnCollision((Kapman *)getModel()); 0098 } 0099 } 0100 } 0101 } 0102 } 0103 0104 void KapmanItem::update(qreal p_x, qreal p_y) 0105 { 0106 ElementItem::update(p_x, p_y); 0107 0108 // If the kapman is moving 0109 if (((Kapman *)getModel())->getXSpeed() != 0 || ((Kapman *)getModel())->getYSpeed() != 0) { 0110 startAnim(); 0111 } 0112 } 0113 0114 void KapmanItem::startAnim() 0115 { 0116 // Start the animation timer if it is not active 0117 if (m_animationTimer->state() != QTimeLine::Running) { 0118 m_animationTimer->start(); 0119 } 0120 } 0121 0122 void KapmanItem::pauseAnim() 0123 { 0124 if (m_animationTimer->state() == QTimeLine::Running) { 0125 m_animationTimer->setPaused(true); 0126 } 0127 } 0128 0129 void KapmanItem::resumeAnim() 0130 { 0131 if (m_animationTimer->state() == QTimeLine::Running) { 0132 m_animationTimer->setPaused(false); 0133 } 0134 } 0135 0136 void KapmanItem::stopAnim() 0137 { 0138 setElementId(QStringLiteral("kapman_0")); 0139 if (m_animationTimer->state() == QTimeLine::Running) { 0140 m_animationTimer->stop(); 0141 } 0142 } 0143 0144 void KapmanItem::setFrame(const int p_frame) 0145 { 0146 setElementId(QStringLiteral("kapman_%1").arg(p_frame)); 0147 } 0148 0149 void KapmanItem::startBlinking() 0150 { 0151 stopAnim(); 0152 setElementId(QStringLiteral("kapman_0")); 0153 CharacterItem::startBlinking(); 0154 } 0155 0156 void KapmanItem::blink() 0157 { 0158 CharacterItem::blink(); 0159 if (m_nbBlinks % 2 == 0) { 0160 setElementId(QStringLiteral("kapman_0")); 0161 } else { 0162 setElementId(QStringLiteral("kapman_blink")); 0163 } 0164 // Make the kapman blink 2 times (4 ticks) 0165 if (m_nbBlinks == 4) { 0166 m_blinkTimer->stop(); 0167 } 0168 } 0169 0170 #include "moc_kapmanitem.cpp"