Commit 906769b8 authored by Dmitry Suzdalev's avatar Dmitry Suzdalev
Browse files

Reworked balls.jpg to make animation implementation easier.

Balls can be moved to new location. No path finding yet.

svn path=/trunk/KDE/kdegames/klines/; revision=615729
parent aff7d4be
......@@ -29,13 +29,14 @@ BallItem::BallItem( QGraphicsScene* parent, const KLinesRenderer* renderer )
: QGraphicsPixmapItem( 0, parent ), m_renderer(renderer)
{
m_color = NumColors; // = uninitialized
m_timeLine.setCurveShape( QTimeLine::LinearCurve );
connect(&m_timeLine, SIGNAL(frameChanged(int)), SLOT(animFrameChanged(int)) );
}
void BallItem::setColor( BallColor c )
{
m_color = c;
setPixmap( m_renderer->ballPixmap(c) );
//setPixmap( m_renderer->ballPixmap(c) );
}
void BallItem::startAnimation( BallAnimationType type )
......@@ -46,27 +47,28 @@ void BallItem::startAnimation( BallAnimationType type )
case SelectedAnimation:
m_timeLine.setDuration(400);
m_timeLine.setLoopCount(0);
m_timeLine.setCurveShape( QTimeLine::LinearCurve );
// in a balls.jpg we have 9 effective frames
// of raising the ball up. lowing down frames are the
// same 9 frames only played in opposite direction.
// So I setup timeline for 0-18 frame range and in animFrameChanged()
// i'll make sure that after frame number will go past 9 it
// will be recalculated to be 8,7,6,...,0 etc
m_timeLine.setFrameRange(0, 9*2);
m_timeLine.setFrameRange(0, m_renderer->numAnimationFrames(SelectedAnimation)-1);
// starting by going lower
m_timeLine.setCurrentTime( m_timeLine.duration()/2 );
break;
case BornAnimation:
m_timeLine.setDuration(200);
m_timeLine.setLoopCount(1);
m_timeLine.setFrameRange(0, (m_renderer->numAnimationFrames(BornAnimation)-1));
break;
}
m_timeLine.start();
}
void BallItem::stopAnimation()
{
m_timeLine.stop();
// type dependant actions:
switch(m_curAnim)
{
case BornAnimation:
case SelectedAnimation:
m_timeLine.stop();
setPixmap( m_renderer->ballPixmap(m_color) );
break;
}
......@@ -74,16 +76,7 @@ void BallItem::stopAnimation()
void BallItem::animFrameChanged(int frame)
{
switch(m_curAnim)
{
case SelectedAnimation:
// if frame > 9, make it go in opposite direction
// See also comment in startAnimation()
if(frame > 9)
frame = frame - (frame-9)*2;
setPixmap(m_renderer->animationFrame( m_color, m_curAnim, frame ));
break;
}
setPixmap(m_renderer->animationFrame( m_color, m_curAnim, frame ));
}
#include "ballitem.moc"
balls.jpg

72.2 KB | W: | H:

balls.jpg

46.8 KB | W: | H:

balls.jpg
balls.jpg
balls.jpg
balls.jpg
  • 2-up
  • Swipe
  • Onion skin
......@@ -37,7 +37,7 @@ QPixmap KLinesRenderer::ballPixmap(BallColor color) const
// Switching to svg will make this fixmes obsolete
// col, row, width, height - hardcoded. balls.jpg has such a format.
return m_ballsPix.copy( 9*30, static_cast<int>(color)*30, 30, 30 );
return m_ballsPix.copy( 7*30, static_cast<int>(color)*30, 30, 30 );
}
QPixmap KLinesRenderer::animationFrame( BallColor color, BallAnimationType type, int frameNo ) const
......@@ -48,6 +48,8 @@ QPixmap KLinesRenderer::animationFrame( BallColor color, BallAnimationType type,
switch(type)
{
case BornAnimation:
return m_ballsPix.copy( 13*30 + frameNo*30, static_cast<int>(color)*30, 30, 30 );
case SelectedAnimation:
return m_ballsPix.copy( frameNo*30, static_cast<int>(color)*30, 30, 30 );
default:
......
......@@ -34,6 +34,20 @@ public:
QPixmap ballPixmap( BallColor c ) const;
QPixmap animationFrame( BallColor c, BallAnimationType t, int frameNo ) const;
QPixmap backgroundTilePixmap() const;
inline int numAnimationFrames(BallAnimationType t) const
{
switch(t)
{
case SelectedAnimation:
return 13;
case BornAnimation:
return 5;
case BurnAnimation:
return 4;
}
return 0;
}
private:
QPixmap m_ballsPix; // to be removed when SVG comes to us
QPixmap m_fieldPix; // to be removed when SVG comes to us
......
......@@ -43,7 +43,7 @@ void KLinesView::resizeEvent( QResizeEvent* ev )
// =============== KLinesScene =======================
KLinesScene::KLinesScene( QObject* parent )
: QGraphicsScene(parent), m_selectedBall(0), m_numBalls(0)
: QGraphicsScene(parent), m_numBalls(0)
{
m_renderer = new KLinesRenderer;
......@@ -93,25 +93,42 @@ void KLinesScene::placeRandomBall()
BallItem* newBall = new BallItem( this, m_renderer );
newBall->setColor(c);
newBall->setPos( fieldToPix(posx,posy) );
newBall->setPos( fieldToPix( FieldPos(posx,posy) ) );
m_field[posx][posy] = newBall;
//newBall->startAnimation( BornAnimation );
newBall->startAnimation( BornAnimation );
m_numBalls++;
}
void KLinesScene::mousePressEvent( QGraphicsSceneMouseEvent* ev )
{
int fx = pixToFieldX(ev->scenePos());
int fy = pixToFieldY(ev->scenePos());
FieldPos fpos = pixToField(ev->scenePos());
if( m_field[fx][fy] )
if( m_field[fpos.x][fpos.y] ) // ball was selected
{
if( m_selectedBall )
m_selectedBall->stopAnimation();
if( m_selPos.isValid() )
m_field[m_selPos.x][m_selPos.y]->stopAnimation();
m_field[fx][fy]->startAnimation( SelectedAnimation );
m_selectedBall = m_field[fx][fy];
m_field[fpos.x][fpos.y]->startAnimation( SelectedAnimation );
m_selPos = fpos;
}
else // move selected ball to new location
{
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;
m_selPos.x = m_selPos.y = -1; // invalidate position
nextThreeBalls();
}
}
}
......
......@@ -45,6 +45,15 @@ 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
*/
......@@ -53,12 +62,12 @@ public:
/**
* Field coords to pixel coords
*/
inline QPointF fieldToPix(int fieldX, int fieldY) const {
return QPointF( fieldX*32+2, fieldY*32+2 );
inline QPointF fieldToPix(const FieldPos& fpos) const {
return QPointF( fpos.x*32+2, fpos.y*32+2 );
}
inline int pixToFieldX( const QPointF& p ) const { return static_cast<int>(p.x()/32); }
inline int pixToFieldY( const QPointF& p ) const { return static_cast<int>(p.y()/32); }
private:
inline FieldPos pixToField( const QPointF& p ) const {
return FieldPos(static_cast<int>(p.x()/32), static_cast<int>(p.y()/32)); }
virtual void drawBackground( QPainter*, const QRectF& );
virtual void mousePressEvent( QGraphicsSceneMouseEvent* );
......@@ -69,11 +78,13 @@ private:
*/
BallItem* m_field[FIELD_SIZE][FIELD_SIZE];
KLinesRenderer* m_renderer;
KRandomSequence m_randomSeq;
/**
* Currently selected ball (0 if none)
* Position of selected ball (-1,-1) if none
*/
BallItem *m_selectedBall;
FieldPos m_selPos;
/**
* Number of balls currently in field
*/
......
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