File indexing completed on 2024-09-15 03:43:54
0001 /* 0002 This file is part of the KDE games kwin4 program 0003 SPDX-FileCopyrightText: 2006 Martin Heni <kde@heni-online.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "piecesprite.h" 0009 0010 // own 0011 #include "kfourinline_debug.h" 0012 // Std 0013 #include <cmath> 0014 0015 PieceSprite::PieceSprite(const QString &id, ThemeManager *theme, int no, QGraphicsScene *canvas) 0016 : Themeable(id, theme) 0017 , PixmapSprite(no, canvas) 0018 { 0019 mMovementState = Idle; 0020 mNotify = new SpriteNotify(this); 0021 if (theme) 0022 theme->updateTheme(this); 0023 } 0024 0025 // Destructor 0026 PieceSprite::~PieceSprite() 0027 { 0028 delete mNotify; 0029 } 0030 0031 // Standard theme change function to redraw the item 0032 void PieceSprite::changeTheme() 0033 { 0034 PixmapSprite::changeTheme(); 0035 } 0036 0037 // Start a linear movement 0038 void PieceSprite::startLinear(QPointF start, QPointF end, double velocity) 0039 { 0040 mStart = start; 0041 mEnd = end; 0042 QPointF p = mEnd - mStart; 0043 double dist = sqrt(p.x() * p.x() + p.y() * p.y()); 0044 if (dist > 0.0) 0045 mDuration = dist / velocity * 1000.0; // Duration in [ms] 0046 else 0047 mDuration = 0.0; 0048 0049 mMovementState = LinearMove; 0050 mTime.restart(); 0051 setPos(mStart.x() * getScale(), mStart.y() * getScale()); 0052 show(); 0053 } 0054 0055 // Start linear movement from current position 0056 void PieceSprite::startLinear(QPointF end, double velocity) 0057 { 0058 mStart = QPointF(x() / getScale(), y() / getScale()); 0059 mEnd = end; 0060 QPointF p = mEnd - mStart; 0061 double dist = sqrt(p.x() * p.x() + p.y() * p.y()); 0062 if (dist > 0.0) 0063 mDuration = dist / velocity * 1000.0; // Duration in [ms] 0064 else 0065 mDuration = 0.0; 0066 mMovementState = LinearMove; 0067 mTime.restart(); 0068 show(); 0069 } 0070 0071 // CanvasItem advance method 0072 void PieceSprite::advance(int phase) 0073 { 0074 // Advance time and frame animation etc 0075 PixmapSprite::advance(phase); 0076 0077 // Ignore phase 0 (collisions) 0078 if (phase == 0) { 0079 return; 0080 } 0081 0082 // Current scaling 0083 double scale = this->getScale(); 0084 0085 // Handle linear movement 0086 if (mMovementState == LinearMove) { 0087 // Movement over? 0088 if (mTime.elapsed() >= mDuration) { 0089 mMovementState = Idle; 0090 0091 setPos(mEnd.x() * scale, mEnd.y() * scale); 0092 // Use notifier to emit signal 0093 mNotify->emitSignal(0); 0094 } else { 0095 // Continue moving 0096 double t = mTime.elapsed() / mDuration; 0097 qreal x = mStart.x() + t * (mEnd.x() - mStart.x()); 0098 qreal y = mStart.y() + t * (mEnd.y() - mStart.y()); 0099 setPos(x * scale, y * scale); 0100 } 0101 } 0102 }