Commit 9aee11ae authored by Dmitry Suzdalev's avatar Dmitry Suzdalev
Browse files

Ball moves are now animated.

Still no pathfinding - balls move along straight lines.

svn path=/trunk/KDE/kdegames/klines/; revision=615766
parent 906769b8
......@@ -15,7 +15,8 @@ set(klines_SRCS
main.cpp
scene.cpp
renderer.cpp
ballitem.cpp)
ballitem.cpp
animator.cpp)
kde4_automoc(${klines_SRCS})
......
......@@ -50,6 +50,10 @@ public:
* Interrupts current animation
*/
void stopAnimation();
// enable use of qgraphicsitem_cast
enum { Type = UserType + 1 };
virtual int type() const { return Type; }
signals:
/**
* Emitted when animation finishes.
......
......@@ -23,7 +23,19 @@
#ifndef COMMON_DEFINES_H
#define COMMON_DEFINES_H
#include <QList>
enum BallAnimationType { SelectedAnimation, BornAnimation, BurnAnimation };
enum BallColor { Blue=0, Brown, Cyan, Green, Red, Violet, Yellow, NumColors };
struct FieldPos
{
int x;
int y;
FieldPos( int _x=-1, int _y=-1) : x(_x), y(_y) { }
bool isValid() const { return (x != -1 && y != -1); }
};
typedef QList<FieldPos> FieldPath;
#endif
......@@ -27,6 +27,7 @@
#include "scene.h"
#include "ballitem.h"
#include "animator.h"
#include "renderer.h"
KLinesView::KLinesView( KLinesScene* scene, QWidget* parent )
......@@ -46,6 +47,8 @@ KLinesScene::KLinesScene( QObject* parent )
: QGraphicsScene(parent), m_numBalls(0)
{
m_renderer = new KLinesRenderer;
m_animator = new KLinesAnimator(this);
connect( m_animator, SIGNAL(moveFinished()), SLOT(moveAnimFinished() ) );
for(int x=0; x<FIELD_SIZE; ++x)
for(int y=0; y<FIELD_SIZE; ++y)
......@@ -57,6 +60,7 @@ KLinesScene::KLinesScene( QObject* parent )
KLinesScene::~KLinesScene()
{
delete m_renderer;
delete m_animator;
}
void KLinesScene::resizeScene(int width,int height)
......@@ -70,24 +74,22 @@ void KLinesScene::nextThreeBalls()
placeRandomBall();
placeRandomBall();
placeRandomBall();
kDebug() << "=======" << endl;
}
void KLinesScene::placeRandomBall()
{
// FIXME dimsuz: in old klines ball positon had score and levels of
// difficulty were implemented around it. Check this out and consider implementing
// as current pos finding isn't very good - theorectically it can search forever :).
// @see linesboard.cpp: placeBall()
int posx = -1, posy = -1;
// let's find random free cell
do
{
// FIXME dimsuz: debug temp
if( posx != -1 )
kDebug() << "pos x:" << posx << " y:" << posy << " isn't free!" << endl;
posx = m_randomSeq.getLong(FIELD_SIZE);
posy = m_randomSeq.getLong(FIELD_SIZE);
kDebug() << "trying x:" << posx << " y:" << posy << endl;
} while( m_field[posx][posy] != 0 );
kDebug() << "found x:" << posx << " y:" << posy << endl;
// random color
BallColor c = static_cast<BallColor>(m_randomSeq.getLong(static_cast<int>(NumColors)));
......@@ -117,21 +119,37 @@ void KLinesScene::mousePressEvent( QGraphicsSceneMouseEvent* ev )
if( m_selPos.isValid() && m_field[fpos.x][fpos.y] == 0 )
{
// FIXME dimsuz: check if we have a valid path to desired point
// FIXME dimsuz: start animating move, rather than placing immediately
BallItem *selectedBall = m_field[m_selPos.x][m_selPos.y];
selectedBall->stopAnimation();
selectedBall->setPos( fieldToPix(fpos) );
m_field[m_selPos.x][m_selPos.y] = 0; // no more ball here
m_field[fpos.x][fpos.y] = selectedBall;
// start move animation
FieldPath p;
p.append(m_selPos);
p.append(fpos);
m_selPos.x = m_selPos.y = -1; // invalidate position
nextThreeBalls();
m_animator->startMoveAnimation(p);
}
}
}
void KLinesScene::moveAnimFinished()
{
// m_field[m_selPos.x][m_selPos.y] still holds the ball pointer
// but animation placed it to new location.
// But it updated only pixel position, not the field one
// So let's do it here
BallItem *movedBall = m_field[m_selPos.x][m_selPos.y];
// movedBall has new pixel position - let's find out corresponding field pos
FieldPos newpos = pixToField(movedBall->pos());
m_field[m_selPos.x][m_selPos.y] = 0; // no more ball here
m_field[newpos.x][newpos.y] = movedBall;
m_selPos.x = m_selPos.y = -1; // invalidate position
nextThreeBalls();
}
void KLinesScene::drawBackground(QPainter *p, const QRectF&)
{
kDebug() << k_funcinfo << endl;
......@@ -140,3 +158,5 @@ void KLinesScene::drawBackground(QPainter *p, const QRectF&)
for(int y=0; y<32*FIELD_SIZE;y+=32)
p->drawPixmap( x, y, m_renderer->backgroundTilePixmap() );
}
#include "scene.moc"
......@@ -32,10 +32,12 @@
static const int FIELD_SIZE=9;
class KLinesRenderer;
class KLinesAnimator;
class BallItem;
class KLinesScene : public QGraphicsScene
{
Q_OBJECT
public:
KLinesScene( QObject *parent );
~KLinesScene();
......@@ -45,29 +47,31 @@ public:
* Brings in next three balls to scene
*/
void nextThreeBalls();
private:
struct FieldPos
{
int x;
int y;
FieldPos( int _x=-1, int _y=-1) : x(_x), y(_y) { }
bool isValid() const { return (x != -1 && y != -1); }
};
/**
* Creates a ball of random color and places it in random free cell
* Returns ballitem in field position pos or 0 if there
* is no item there
*/
void placeRandomBall();
BallItem* ballAt( const FieldPos& pos ) { return m_field[pos.x][pos.y]; }
/**
* Field coords to pixel coords
*/
inline QPointF fieldToPix(const FieldPos& fpos) const {
return QPointF( fpos.x*32+2, fpos.y*32+2 );
}
/**
* Pixel coords to field coords
*/
inline FieldPos pixToField( const QPointF& p ) const {
return FieldPos(static_cast<int>(p.x()/32), static_cast<int>(p.y()/32)); }
private slots:
void moveAnimFinished();
private:
/**
* Creates a ball of random color and places it in random free cell
*/
void placeRandomBall();
virtual void drawBackground( QPainter*, const QRectF& );
virtual void mousePressEvent( QGraphicsSceneMouseEvent* );
......@@ -78,6 +82,7 @@ private:
*/
BallItem* m_field[FIELD_SIZE][FIELD_SIZE];
KLinesRenderer* m_renderer;
KLinesAnimator* m_animator;
KRandomSequence m_randomSeq;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment