File indexing completed on 2024-04-28 04:02:16

0001 /*
0002     SPDX-FileCopyrightText: 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
0003     SPDX-FileCopyrightText: 2009 Ian Wadham <iandw.au@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "kgrsprite.h"
0009 #include "kgrrenderer.h"
0010 
0011 #include "kgoldrunner_debug.h"
0012 
0013 KGrSprite::KGrSprite (KGameRenderer * renderer, QString & key,
0014                       const char type, const int tickTime)
0015     :
0016     KGameRenderedItem (renderer, key),
0017 
0018     m_type            (type),
0019     m_tickTime        (tickTime),
0020     m_stationary      (true),   // Animation is OFF at first.
0021     m_x               (0),
0022     m_y               (0),
0023     m_startFrame      (0),
0024     m_nFrames         (1),
0025     m_frameCtr        (0),
0026     m_dx              (0),
0027     m_dy              (0),
0028     m_dt              (0),
0029     m_oldX            (-1),
0030     m_oldY            (-1),
0031     m_oldFrame        (-1),
0032     m_topLeftX        (0),
0033     m_topLeftY        (0),
0034     m_tileSize        (1)
0035 {
0036 }
0037 
0038 KGrSprite::~KGrSprite()
0039 {
0040 }
0041 
0042 void KGrSprite::move (double x, double y, int frame)
0043 {
0044     if (frame != m_oldFrame) {
0045         // Change the animation frame in KGameRenderedItem.
0046         setFrame (frame);
0047         m_oldFrame = frame;
0048     }
0049     if ((x != m_oldX) || (y != m_oldY)) {
0050         // Change the position in scene (and view) coordinates.
0051         setPos (m_topLeftX + (x + 1) * m_tileSize,
0052                 m_topLeftY + (y + 1) * m_tileSize);
0053         m_oldX = x;
0054         m_oldY = y;
0055     }
0056     return;
0057 }
0058 
0059 void KGrSprite::setAnimation (bool repeating, int x, int y, int startFrame,
0060                         int nFrames, int dx, int dy, int dt, int nFrameChanges)
0061 {
0062     m_stationary    = false;    // Animation is ON now.
0063     m_repeating     = repeating;
0064     m_x             = x;
0065     m_y             = y;
0066     m_startFrame    = startFrame;
0067     m_nFrames       = nFrames;
0068     m_frameCtr      = 0;
0069     m_dt            = dt;
0070     m_nFrameChanges = nFrameChanges;
0071 
0072     m_ticks         = ((double) dt / m_tickTime) + 0.5;
0073     m_dx            = (double) dx / m_ticks;
0074     m_dy            = (double) dy / m_ticks;
0075     m_frameTicks    = (double) m_ticks / nFrameChanges;
0076     m_frameChange   = 0.0;
0077     // //qCDebug(KGOLDRUNNER_LOG) << "m_ticks" << m_ticks << "dx,dy,dt" << dx << dy << dt << "m_dx,m_dy" << m_dx << m_dy << "m_frameTicks" << m_frameTicks << "nFrames" << nFrames << "nFrameChanges" << nFrameChanges;
0078 }
0079 
0080 void KGrSprite::animate (bool missed)
0081 {
0082     if (m_stationary) {
0083         return;
0084     }
0085     if (m_frameCtr >= m_nFrames) {
0086         m_frameCtr = 0;
0087         if (! m_repeating) {
0088             m_stationary = true;    // Stop after one set of frames.
0089             return;
0090         }
0091     }
0092     // //qCDebug(KGOLDRUNNER_LOG) << missed << m_frameCtr << "=" << m_x << m_y << "frame" << m_startFrame + m_frameCtr << m_frameChange;
0093 
0094     // If the clock is running slow, skip an animation step.
0095     if (! missed) {
0096         move (m_x, m_y, m_startFrame + m_frameCtr);
0097     }
0098 
0099     // Calculate the next animation step.
0100     m_frameChange = m_frameChange + 1.0;
0101     if (m_frameChange + 0.001 > m_frameTicks) {
0102         m_frameChange = m_frameChange - m_frameTicks;
0103         m_frameCtr++;
0104     }
0105     m_x = m_x + m_dx;
0106     m_y = m_y + m_dy;
0107 }
0108 
0109 void KGrSprite::setCoordinateSystem (int topLeftX, int topLeftY, int tileSize)
0110 {
0111     if (tileSize != m_tileSize) {
0112         setRenderSize (QSize (tileSize, tileSize));
0113     }
0114     m_tileSize = tileSize;
0115     m_topLeftX = topLeftX;
0116     m_topLeftY = topLeftY;
0117 }
0118 
0119 void KGrSprite::changeCoordinateSystem(int topLeftX, int topLeftY, int tileSize)
0120 {
0121     setCoordinateSystem (topLeftX, topLeftY, tileSize);
0122 
0123     double x = m_oldX;
0124     double y = m_oldY;
0125     m_oldX = m_oldY = -1;   // Make it look like a change of position,
0126     move (x, y, m_oldFrame);    // to force a recalculation of view coords.
0127 }