Found at: http://publish.ez.no/article/articleprint/2/ |
Creating games with QCanvas |
The Qt class QCanvas features optimized 2D graphics with game related functions, such as sprites and collision detection. This article describes how to use this in a small game.
|
| You've got the whole world in your hands... |
|
| A close-up of the planet and stars |
BounceWidget::BounceWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
// Create and setup canvas and view
Canvas = new QCanvas( this, "Canvas" );
Canvas->setBackgroundColor( Qt::black );
Canvas->setBackgroundPixmap( QPixmap( "stars.png" ) );
Canvas->setAdvancePeriod( 10 );
Canvas->resize( 500, 500 );
CanvasView = new BounceCanvasView( Canvas, this, "CanvasView" );
// setup the quit button
QuitButton = new QPushButton( "&Quit", this, "QuitButton" );
connect( QuitButton, SIGNAL( clicked() ), qApp, SLOT( quit() ) );
// setup the layout manager
QVBoxLayout *vlay = new QVBoxLayout( this );
vlay->setResizeMode( QLayout::Fixed );
vlay->addWidget( CanvasView );
vlay->addWidget( QuitButton );
// add a planet to our scenery
Ball *sphere = new Ball( new QCanvasPixmapArray( "earth.png" ), Canvas );
sphere->move( 100, 150 );
sphere->setXVelocity( 2 );
sphere->setYVelocity( 4 );
sphere->show();
}
|
void BounceCanvasView::contentsMouseReleaseEvent( QMouseEvent* )
{
if ( Moving ) // if we are holding the ball
{
Timer->stop(); // stop the timer
if ( MousePosQueue.count() ) // if we have recorded mouse positions...
{
// ...then calculate average velocity
int count = MousePosQueue.count();
QPoint velocity( 0, 0 );
QPoint pos;
QPoint prevPos = *MousePosQueue.head();
while ( MousePosQueue.count() )
{
pos = *MousePosQueue.dequeue();
velocity += pos - prevPos;
prevPos = pos;
}
// set the balls new velocity
Moving->setXVelocity( velocity.x() / count );
Moving->setYVelocity( velocity.y() / count );
}
else // if we haven't recorded anything (fast click)
{
// set zero velocity (we drop the ball)
Moving->setXVelocity( 0 );
Moving->setYVelocity( 0 );
}
Moving->setZ( 1 );
canvas()->setAdvancePeriod( 10 ); // restart the animation
Moving = 0; // clear the pointer, we are no longer holding the ball
}
}
|
void Ball::advance( int phase )
{
if ( phase == 0 ) // stuff to be done before we move
{
// apply resistance to slow down the ball
setXVelocity( xVelocity() * Air_resistance );
setYVelocity( yVelocity() * Air_resistance );
// apply gravity
setYVelocity( yVelocity() + Mass );
// right border hit check
if ( !canvas()->onCanvas( x() + width()/2 + xVelocity(), 1 ) )
{
MoveX = false;
move( canvas()->width() - width()/2, y() );
setXVelocity( xVelocity() * -1 * Bump_resistance );
}
// left border hit check
else if ( !canvas()->onCanvas( x() - width()/2 + xVelocity(), 1 ) )
{
MoveX = false;
move( 0 + width()/2, y() );
setXVelocity( xVelocity() * -1 * Bump_resistance );
}
// lower border hit check
if ( !canvas()->onCanvas( 1, y() + height()/2 + yVelocity() ) )
{
MoveY = false;
move( x(), canvas()->height() - height()/2 );
setYVelocity( yVelocity() * -1 * Bump_resistance );
}
// upper border hit check
else if ( !canvas()->onCanvas( 1, y() - height()/2 + yVelocity() ) )
{
MoveY = false;
move( x(), 0 + height()/2 );
setYVelocity( yVelocity() * -1 * Bump_resistance );
}
}
else // time to move
{
if ( MoveX && MoveY )
move( x() + xVelocity(), y() + yVelocity() );
else if ( MoveX )
move( x() + xVelocity(), y() );
else if ( MoveY )
move( x(), y() + yVelocity() );
MoveX = MoveY = true;
}
}
|
int main( int argc, char **argv )
{
QApplication a( argc, argv );
BounceWidget bw( 0, "BounceWidget" );
a.setMainWidget( &bw );
bw.setCaption( "Astrophysics for beginners!" );
bw.show();
return a.exec();
}
|
tar -zxf bounce.tar.gz cd bounce tmake -o Makefile bounce.pro make ./bounce |
Attached files: