You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
312 lines
5.5 KiB
312 lines
5.5 KiB
|
|
/*
|
|
* File name: kpacman.cpp
|
|
* Summary: PacMan animation
|
|
* License: LGPL - See file COPYING.LIB for details.
|
|
* Author: Stefan Hundhammer <sh@suse.de>
|
|
*
|
|
* Updated: 2004-03-29
|
|
*/
|
|
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <tqtimer.h>
|
|
#include <tqpixmap.h>
|
|
#include <kdebug.h>
|
|
|
|
#include "kpacman.h"
|
|
|
|
|
|
KPacManAnimation::KPacManAnimation( TQWidget * widget,
|
|
int size,
|
|
bool randomStart )
|
|
{
|
|
_widget = widget;
|
|
_size = size;
|
|
_randomStart = randomStart;
|
|
_brush = TQBrush( TQt::yellow );
|
|
_pos = 0;
|
|
_speed = 4;
|
|
_interval = 100;
|
|
|
|
_minMouth = 10;
|
|
_maxMouth = 70;
|
|
_mouthInc = ( _maxMouth - _minMouth ) / 3;
|
|
_mouth = _minMouth;
|
|
_pacManRect = TQRect( 0, 0, 0, 0 );
|
|
|
|
restart();
|
|
}
|
|
|
|
|
|
KPacManAnimation::~KPacManAnimation()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
KPacManAnimation::restart()
|
|
{
|
|
_justStarted = true;
|
|
|
|
if ( _randomStart )
|
|
{
|
|
_goingRight = ( rand() > ( RAND_MAX / 2 ) );
|
|
|
|
// Initial _pos is set in animate() since the width (upon which it
|
|
// depends) is still unknown here.
|
|
}
|
|
else
|
|
{
|
|
_goingRight = true;
|
|
_pos = 0;
|
|
}
|
|
|
|
// Care for initial display
|
|
_time = _time.addMSecs( _interval + 1 );
|
|
}
|
|
|
|
|
|
void
|
|
KPacManAnimation::animate( TQPainter * painter,
|
|
TQRect rect )
|
|
{
|
|
if ( _time.elapsed() < _interval )
|
|
return;
|
|
|
|
_time.restart();
|
|
|
|
|
|
// Make PacMan fit into height
|
|
|
|
int size = _size <= rect.height() ? _size : rect.height();
|
|
|
|
if ( rect.width() < size ) // No space to animate in?
|
|
return; // -> forget it!
|
|
|
|
|
|
if ( _justStarted )
|
|
{
|
|
_justStarted = false;
|
|
|
|
if ( _pacManRect.width() > 0 )
|
|
painter->eraseRect( _pacManRect );
|
|
|
|
if ( _randomStart )
|
|
{
|
|
// Set random initial position
|
|
// - this depends on the width which is unknown in the constructor.
|
|
|
|
_pos = (int) ( (rect.width() - size ) * ( (double) rand() / RAND_MAX) );
|
|
}
|
|
}
|
|
else // ! _justStarted
|
|
{
|
|
// Erase last PacMan
|
|
|
|
if ( ! _goingRight )
|
|
_pacManRect.setX( _pacManRect.x() + _pacManRect.width() - _speed );
|
|
|
|
_pacManRect.setWidth( _speed );
|
|
painter->eraseRect( _pacManRect );
|
|
}
|
|
|
|
|
|
if ( _pos + size > rect.width() ) // Right edge reached?
|
|
{
|
|
// Notice: This can also happen when the rectangle is resized - i.e. it
|
|
// really makes sense to do that right here rather than at the end of
|
|
// this function!
|
|
|
|
// Turn left
|
|
|
|
_pos = rect.width() - size;
|
|
_goingRight = false;
|
|
_mouth = _minMouth;
|
|
}
|
|
else if ( _pos < 0 ) // Left edge reached?
|
|
{
|
|
// Turn right
|
|
|
|
_pos = 0;
|
|
_goingRight = true;
|
|
_mouth = _minMouth;
|
|
}
|
|
|
|
|
|
// Draw PacMan (double-buffered)
|
|
|
|
_pacManRect = TQRect( 0, 0, size, size );
|
|
TQPixmap pixmap( size, size );
|
|
pixmap.fill( painter->backgroundColor() );
|
|
TQPainter p( &pixmap, _widget );
|
|
p.setBrush( _brush );
|
|
|
|
if ( _goingRight )
|
|
{
|
|
p.drawPie( _pacManRect,
|
|
_mouth * 16, // arc (1/16 degrees)
|
|
( 360 - 2 * _mouth ) * 16 ); // arc length (1/16 degrees)
|
|
}
|
|
else
|
|
{
|
|
p.drawPie( _pacManRect,
|
|
( 180 + _mouth ) * 16, // arc (1/16 degrees)
|
|
( 360 - 2 * _mouth ) * 16 ); // arc length (1/16 degrees)
|
|
}
|
|
|
|
_pacManRect = TQRect( rect.x() + _pos, // x
|
|
( rect.height() - size ) / 2, // y
|
|
size, size ); // width, height
|
|
|
|
// Transfer pixmap into widget
|
|
|
|
#if 0
|
|
TQPoint offset = painter->worldMatrix().map( _pacManRect.topLeft() );
|
|
// kdDebug() << "bitBlt() to " << offset.x() << ", " << offset.y() << endl;
|
|
bitBlt( _widget, offset, &pixmap );
|
|
#endif
|
|
|
|
painter->drawPixmap( _pacManRect.topLeft(), pixmap );
|
|
|
|
|
|
// Animate mouth for next turn
|
|
|
|
_mouth += _mouthInc;
|
|
|
|
if ( _mouth >= _maxMouth ) // max open reached
|
|
{
|
|
_mouth = _maxMouth;
|
|
_mouthInc = -_mouthInc; // reverse direction
|
|
}
|
|
else if ( _mouth <= _minMouth ) // min open reached
|
|
{
|
|
_mouth = _minMouth;
|
|
_mouthInc = -_mouthInc; // reverse direction
|
|
}
|
|
|
|
|
|
// Advance position for next turn
|
|
|
|
if ( _goingRight )
|
|
_pos += _speed;
|
|
else
|
|
_pos -= _speed;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KPacMan::KPacMan( TQWidget * parent,
|
|
int pacManSize,
|
|
bool randomStart,
|
|
const char * widgetName )
|
|
: TQWidget( parent, widgetName )
|
|
{
|
|
_pacManSize = pacManSize;
|
|
_pacMan = new KPacManAnimation( this, _pacManSize, randomStart );
|
|
_timer = 0;
|
|
_interval = 100; // millisec
|
|
_active = false;
|
|
_painter = new TQPainter( this );
|
|
_margin = 1;
|
|
}
|
|
|
|
|
|
KPacMan::~KPacMan()
|
|
{
|
|
if ( _painter )
|
|
delete _painter;
|
|
|
|
if ( _pacMan )
|
|
delete _pacMan;
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::start()
|
|
{
|
|
if ( ! _timer )
|
|
{
|
|
_timer = new TQTimer( this );
|
|
}
|
|
|
|
_pacMan->restart();
|
|
|
|
if ( _timer )
|
|
{
|
|
_active = true;
|
|
_timer->start( _interval );
|
|
connect( _timer, TQT_SIGNAL( timeout() ),
|
|
this, TQT_SLOT ( animate() ) );
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::stop()
|
|
{
|
|
_active = false;
|
|
|
|
if ( _timer )
|
|
_timer->stop();
|
|
|
|
repaint();
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::animate()
|
|
{
|
|
repaint( false );
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::setInterval( int intervalMilliSec )
|
|
{
|
|
_interval = intervalMilliSec;
|
|
_pacMan->setInterval( _interval );
|
|
|
|
if ( _timer )
|
|
_timer->changeInterval( _interval );
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::paintEvent( TQPaintEvent *ev )
|
|
{
|
|
TQWidget::paintEvent( ev );
|
|
|
|
if ( _active )
|
|
{
|
|
_pacMan->animate( _painter, TQRect( _margin, 0, width() - _margin, height() ) );
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
KPacMan::mouseReleaseEvent ( TQMouseEvent *ev )
|
|
{
|
|
if ( _active )
|
|
{
|
|
if ( _pacMan->lastPacMan().contains( ev->pos() ) )
|
|
stop();
|
|
}
|
|
}
|
|
|
|
|
|
TQSize
|
|
KPacMan::sizeHint() const
|
|
{
|
|
return TQSize( 16 * _pacManSize, // width - admittedly somewhat random
|
|
_pacManSize + 2 * _margin ); // height
|
|
}
|
|
|
|
|
|
|
|
// EOF
|