1/*
2 * Copyright (C) 2007 Tomasz Boczkowski <tboczkowski@onet.pl>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free
16 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19
20#include "ball.h"
21
22#include <cmath>
23
24#include <kdebug.h>
25#include <KRandom>
26
27#include "board.h"
28#include "renderer.h"
29
30const int KBounceBall::BALL_ANIM_DELAY = 50;
31const qreal KBounceBall::BALL_RELATIVE_SIZE = 0.8;
32
33KBounceBall::KBounceBall( KBounceRenderer* renderer, KBounceBoard* board )
34: KGameRenderedItem(renderer,"", board ), m_renderer( renderer ), m_board( board ),
35 m_soundDelay( 0 ), m_size( QSize( 16, 16 ) ), m_framesNum( 0 ), m_xPos( 0 ), m_yPos( 0 )
36{
37 setSpriteKey("ball");
38 resetPixmaps();
39 m_nextBoundingRect.setSize( QSizeF( BALL_RELATIVE_SIZE, BALL_RELATIVE_SIZE ) );
40}
41
42
43KBounceBall::~KBounceBall()
44{
45}
46
47void KBounceBall::goForward()
48{
49 if ( m_reflectX )
50 {
51 m_velocity.x = -m_velocity.x;
52 m_reflectX = false;
53 }
54
55 if ( m_reflectY )
56 {
57 kDebug() << "Reflecting ball Y";
58 m_velocity.y = -m_velocity.y;
59 m_reflectY = false;
60 }
61
62 m_xPos += m_velocity.x;
63 m_yPos += m_velocity.y;
64
65 m_nextBoundingRect.moveTo( m_xPos + m_velocity.x, m_yPos + m_velocity.y );
66}
67
68void KBounceBall::collide( const KBounceCollision& collision )
69{
70 foreach ( const KBounceHit &hit, collision )
71 {
72 if ( hit.type == TILE || hit.type == WALL )
73 {
74 if ( hit.normal.x > 0 && m_velocity.x < 0 )
75 m_reflectX = true;
76 if ( hit.normal.x < 0 && m_velocity.x > 0 )
77 m_reflectX = true;
78 if ( hit.normal.y > 0 && m_velocity.y < 0 )
79 m_reflectY = true;
80 if ( hit.normal.y < 0 && m_velocity.y > 0 )
81 m_reflectY = true;
82 }
83 }
84}
85
86void KBounceBall::update()
87{
88 setFrame( frame()+1 );
89 setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
90}
91
92void KBounceBall::resize( const QSize& tileSize )
93{
94 kDebug() << "New size:" << tileSize;
95
96 m_size.setWidth( static_cast<int>( BALL_RELATIVE_SIZE * tileSize.width() ) );
97 m_size.setHeight( static_cast<int> ( BALL_RELATIVE_SIZE * tileSize.height() ) );
98 setRenderSize(m_size);
99 setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
100}
101
102void KBounceBall::resetPixmaps()
103{
104 m_framesNum = frameCount();
105 setFrame( 1 );
106}
107
108void KBounceBall::setRandomFrame()
109{
110 int frame = 1;
111 if ( m_framesNum > 1 )
112 {
113 frame = KRandom::random() % m_framesNum;
114 }
115 setFrame( frame );
116}
117
118QRectF KBounceBall::ballBoundingRect() const
119{
120 return QRectF( m_xPos, m_yPos, BALL_RELATIVE_SIZE, BALL_RELATIVE_SIZE );
121}
122
123QRectF KBounceBall::nextBoundingRect() const
124{
125 return m_nextBoundingRect;
126}
127
128QPointF KBounceBall::relativePos()
129{
130 return QPointF( m_xPos, m_yPos );
131}
132
133void KBounceBall::setRelativePos( qreal x, qreal y )
134{
135 m_xPos = x;
136 m_yPos = y;
137 setPos( m_board->mapPosition( QPointF( m_xPos, m_yPos ) ) );
138}
139
140void KBounceBall::setVelocity( qreal vX, qreal vY )
141{
142 m_velocity.x = vX;
143 m_velocity.y = vY;
144}
145
146KBounceVector KBounceBall::velocity() const
147{
148 return KBounceVector( m_velocity.x, m_velocity.y );
149}
150
151