File indexing completed on 2024-12-08 03:45:56

0001 /*
0002     SPDX-FileCopyrightText: 2007 Tomasz Boczkowski <tboczkowski@onet.pl>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "ball.h"
0008 
0009 #include <cmath>
0010 
0011 #include <QRandomGenerator>
0012 
0013 #include "board.h"
0014 #include "renderer.h"
0015 #include "debug.h"
0016 
0017 const int KBounceBall::BALL_ANIM_DELAY = 50;
0018 const qreal KBounceBall::BALL_RELATIVE_SIZE = 0.8;
0019 
0020 KBounceBall::KBounceBall( KBounceRenderer* renderer, KBounceBoard* board )
0021     : KGameRenderedItem(renderer,QLatin1String(""), board ), m_renderer( renderer ), m_board( board ),
0022     m_soundDelay( 0 ), m_size( QSize( 16, 16 ) ), m_framesNum( 0 ), m_xPos( 0 ), m_yPos( 0 ) 
0023 {
0024     setSpriteKey(QStringLiteral("ball"));
0025     resetPixmaps();
0026     m_nextBoundingRect.setSize( QSizeF( BALL_RELATIVE_SIZE, BALL_RELATIVE_SIZE ) );
0027 }
0028 
0029 
0030 KBounceBall::~KBounceBall()
0031 {
0032 }
0033 
0034 void KBounceBall::goForward()
0035 {
0036     if ( m_reflectX )
0037     {
0038         m_velocity.x = -m_velocity.x;
0039         m_reflectX = false;
0040     }
0041 
0042     if ( m_reflectY )
0043     {
0044         qCDebug(KBOUNCE_LOG) << "Reflecting ball Y";
0045         m_velocity.y = -m_velocity.y;
0046         m_reflectY = false;
0047     }
0048 
0049     m_xPos += m_velocity.x;
0050     m_yPos += m_velocity.y;
0051 
0052     m_nextBoundingRect.moveTo( m_xPos + m_velocity.x, m_yPos + m_velocity.y );
0053 }
0054 
0055 void KBounceBall::collide( const KBounceCollision& collision )
0056 {
0057     for (const KBounceHit &hit : collision) {
0058         if ( hit.type == TILE || hit.type == WALL )
0059         {
0060             if ( hit.normal.x > 0 && m_velocity.x < 0 )
0061                 m_reflectX = true;
0062             if ( hit.normal.x < 0 && m_velocity.x > 0 )
0063                 m_reflectX = true;
0064             if ( hit.normal.y > 0 && m_velocity.y < 0 )
0065                 m_reflectY = true;
0066             if ( hit.normal.y < 0 && m_velocity.y > 0 )
0067                 m_reflectY = true;
0068         }
0069     }
0070 }
0071 
0072 void KBounceBall::update()
0073 {
0074     setFrame( frame()+1 );
0075     setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
0076 }
0077 
0078 void KBounceBall::resize( const QSize& tileSize )
0079 {
0080     qCDebug(KBOUNCE_LOG) << "New size:" << tileSize;
0081 
0082     m_size.setWidth( static_cast<int>( BALL_RELATIVE_SIZE * tileSize.width() ) );
0083     m_size.setHeight( static_cast<int> ( BALL_RELATIVE_SIZE * tileSize.height() ) );
0084     setRenderSize(m_size);
0085     setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
0086 }
0087 
0088 void KBounceBall::resetPixmaps()
0089 {
0090     m_framesNum = frameCount();
0091     setFrame( 1 );
0092 }
0093 
0094 void KBounceBall::setRandomFrame()
0095 {
0096     int frame = 1;
0097     if ( m_framesNum > 1 )
0098     {
0099         frame = QRandomGenerator::global()->bounded(m_framesNum);
0100     }
0101     setFrame( frame );
0102 }
0103 
0104 QRectF KBounceBall::ballBoundingRect() const
0105 {
0106     return QRectF( m_xPos, m_yPos, BALL_RELATIVE_SIZE, BALL_RELATIVE_SIZE );
0107 }
0108 
0109 QRectF KBounceBall::nextBoundingRect() const
0110 {
0111     return m_nextBoundingRect;
0112 }
0113 
0114 QPointF KBounceBall::relativePos()
0115 {
0116     return QPointF( m_xPos, m_yPos );
0117 }
0118 
0119 void KBounceBall::setRelativePos( qreal x, qreal y )
0120 {
0121     m_xPos = x;
0122     m_yPos = y;
0123     setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
0124 }
0125 
0126 void KBounceBall::setVelocity( qreal vX, qreal vY )
0127 {
0128     m_velocity.x = vX;
0129     m_velocity.y = vY;
0130 }
0131 
0132 KBounceVector KBounceBall::velocity() const
0133 {
0134     return KBounceVector( m_velocity.x, m_velocity.y );
0135 }
0136