Qt打砖块游戏
来源:互联网 发布:初学者学编程看什么书 编辑:程序博客网 时间:2024/06/11 17:09
概述
程序由自定义的 5 个类构成:
• Ball 类代表小球,包含小球所在矩形于窗格 (frame) 中的位置,另外,小球还包含变量来表示小球的颜色、运动速度等属性。
• Brick 类代表砖块,砖块同样包含尺寸、方位、颜色这些信息。
• Paddle 类代表划浆,划浆包含移动步长、方位、颜色这些信息。
• Game 类代表游戏窗格,用来直接控制小球的运行,划浆的移动,及砖块的绘制。
• GameWindow 类代表程序的主窗口,通过菜单和工具栏的动作来间接控制游戏的运行与停止、小球的运行速度等。
小球 Ball
ball.h
#ifndef _BALL_H_#define _BALL_H_#include <QRect>#include <QColor>class Ball{public: Ball( qreal, qreal, qreal, QColor = Qt::green ); ~Ball(); void move(); QRectF rect() const; void setShape( const QRectF & ); void setColor( const QColor & ); void setDirX( qreal ); void setDirY( qreal ); void setSpeed( qreal ); QRectF getShape() const; QColor getColor() const; qreal getDirX() const; qreal getDirY() const; qreal getSpeed() const; private: QRectF *shape; QColor color; qreal dirX; qreal dirY; qreal speed;};#endif
shape 用来指向包含小球位置和尺寸信息的 QRectF 对象,这里使用 QRectF 而不是 QRect,
是因为 QRectF 中使用 qreal 变量来保存矩形的位置和尺寸信息,而QRect 使用 int 类型变量来保
存信息,因此,使用 QRectF 能跟精确地保存小球的位置和尺寸信息,尤其是当对程序窗口进行缩放
时,这种效果更明显,其中,qreal 类型相当于 double 类型。
color 变量用来包含小球的颜色。此外,使用 qreal 类型dirX 和 dirY 变量来分别表示小球在水
平方向和垂直方向的运动方向。setShape 函数用来对 shape 变量进行新的设置,而 getShape 函
数用来返回QRectF 对象,包含 shape 变量的副本。当窗口需要进行绘制时,这时窗口就需要使用
getShape 函数来得知小球的大小和方位,这样才能正确绘制小球。
setDirX 和 setDirY 函数用来设置小球的移动方向,特别时当小球与窗口边缘、划浆、砖块进行
碰撞时,就需要改变小球的移动方向。
ball.cpp
#include "ball.h"Ball::Ball( qreal x, qreal y, qreal radius, QColor ballColor ){ dirX = 1.0; dirY = -1.0; speed = 1.0; shape = new QRectF( x, y, radius, radius ); color = ballColor;}Ball::~Ball(){ delete shape;}void Ball::setShape( const QRectF &newShape ){ shape->setRect( newShape.left(), newShape.top(), newShape.width(), newShape.height() );}void Ball::setColor( const QColor &newColor ){ color = newColor;}void Ball::setDirX( qreal newDirX ){ dirX = newDirX;}void Ball::setDirY( qreal newDirY ){ dirY = newDirY;}QRectF Ball::getShape() const{ return QRectF( shape->left(), shape->top(), shape->width(), shape->height() );}QColor Ball::getColor() const{ return color;}qreal Ball::getDirX() const{ return dirX;}qreal Ball::getDirY() const{ return dirY;}void Ball::move(){ shape->setLeft( shape->left() + dirX ); shape->setRight( shape->right() + dirX ); shape->setTop( shape->top() + dirY ); shape->setBottom( shape->bottom() + dirY );}void Ball::setSpeed( qreal newSpeed ){ speed = newSpeed; setDirX( speed ); setDirY( -speed );}qreal Ball::getSpeed() const{ return speed;}
setSpeed 函数用来设置小球的移动速度,move 函数则用来使小球移动,需要注意的是,调用 QRectF
函数的 setLeft 函数设置小球的左边缘时,小球的宽度也会随着改变,
为防止小球的尺寸发生改变,需要使用 setRight 函数进行同样的设置,这样才能保持小球的宽度不变。
砖块 Brick
brick.h
#ifndef _BRICK_H_#define _BRICK_H_#include <QRect>#include <QColor>class Brick{public: Brick( qreal, qreal, qreal, qreal, QColor = Qt::red ); ~Brick(); void setShape( const QRectF & ); void setColor( const QColor & ); QRectF getShape() const; QColor getColor() const; private: QRectF *shape; QColor color;};#endif
brick.cpp
#include "brick.h"Brick::Brick( qreal x, qreal y, qreal width, qreal height, QColor brickColor ){ shape = new QRectF( x, y, width, height ); color = brickColor;}Brick::~Brick(){ delete shape;}void Brick::setShape( const QRectF &newShape ){ shape->setRect( newShape.left(), newShape.top(), newShape.width(), newShape.height() );}QRectF Brick::getShape() const{ return QRectF( shape->left(), shape->top(), shape->width(), shape->height() );}void Brick::setColor( const QColor &newColor ){ color = newColor;}QColor Brick::getColor() const{ return color;}划浆 Paddle
paddle.h
#ifndef _PADDLE_H_#define _PADDLE_H_#include <QRect>#include <QColor> class Paddle{public: Paddle( qreal, qreal, qreal, qreal, QColor = Qt::blue ); ~Paddle(); QRectF getShape() const; QColor getColor() const; qreal getLeft() const; qreal getRight() const; qreal getStep() const; void setShape( const QRectF & ); void setColor( const QColor & ); void setLeft( qreal ); void setRight( qreal ); void setStep( qreal ); void moveLeft(); void moveRight(); private: QRectF *shape; QColor color; qreal step;};#endif
与 Ball 不同的是,Paddle 中含有 setStep 函数,用来设置划浆移动的步长,
特别是当程序的窗口进行缩放时,划浆每次移动的距离也应相应地发生改变。
#include "paddle.h"#include <QColor>#include <QPoint>Paddle::Paddle( qreal x, qreal y, qreal width, qreal height, QColor paddleColor ){ shape = new QRectF( x, y, width, height ); color = paddleColor; step = 10.0;}Paddle::~Paddle(){ delete shape;}void Paddle::setColor( const QColor &newColor ){ color = newColor;}QColor Paddle::getColor() const{ return color;}void Paddle::setShape( const QRectF &newShape ){ shape->setRect( newShape.left(), newShape.top(), newShape.width(), newShape.height() );}QRectF Paddle::getShape() const{ return QRectF( shape->left(), shape->top(), shape->width(), shape->height() );}void Paddle::moveLeft(){ shape->setLeft( shape->left() - step ); shape->setRight( shape->right() - step );}void Paddle::moveRight(){ shape->setLeft( shape->left() + step ); shape->setRight( shape->right() + step );}void Paddle::setLeft( qreal left ){ shape->setLeft( left );}void Paddle::setRight( qreal right ){ shape->setRight( right );}qreal Paddle::getLeft() const{ return shape->left();}qreal Paddle::getRight() const{ return shape->right();}void Paddle::setStep( qreal newStep ){ step = newStep;}qreal Paddle::getStep() const{ return step;}moveLeft 和 moveRight 函数来提供了控制划浆移动的接口,每次移动的距离由
移动步长变量 step 来控制。
Game 游戏窗格
game.h
#ifndef _GAME_H_#define _GAME_H_#include "ball.h"#include "paddle.h"#include "brick.h"#include <QWidget> class QTimer;class Game : public QWidget { Q_OBJECTpublic: Game( QWidget * = 0 ); ~Game(); void setBallSpeed( qreal ); void setBricksNumbers( int , int );void setPaddleStep( qreal );signals: void finished(); void scoreChanged( int ); public slots: void moveBall(); void changeColor(); void movePaddleLeft(); void movePaddleRight(); void startGame(); void stopGame(); protected: void paintEvent( QPaintEvent * ); void resizeEvent( QResizeEvent * ); private: void createBricks(); void createPaddle(); void createBall(); QRectF adjustShape( QRectF, qreal, qreal ); QColor randomColor(); int randomInt( int ); Ball *ball; Paddle *paddle; QList< Brick * > bricks; QTimer *timer; int rows; int columns; int score; bool isWin; bool isFailure; double frameWidth; double frameHeight;};#endifgame.cpp
#include "game.h"#include <QPainter>#include <QTimer>#include <QDebug>#include <cstdlib>#include <ctime>Game::Game( QWidget *parent ) :QWidget( parent ){ isWin = false; isFailure = false; frameWidth = 800; frameHeight = 500; score = 0; rows = 5; columns = 10; createBricks(); createPaddle(); createBall(); timer = new QTimer( this ); timer->setInterval( 10 ); connect( timer, SIGNAL( timeout() ), this, SLOT( moveBall() ) ); changeColor();}bool 类型变量 isWin 和 isFailure 用来记录程序程序结束时的胜利或失败的
情况。frameWidth 和 frameHeight 用来保存每一时刻的窗格的大小,注意,初始化
值宽度 800 和高度 500 并不代表窗格的实际大小,这里只是提供了一个理想的值,
因为小球、划浆、砖块的大小的设定都需要窗格的大小来设定。
构造函数中调用 createBrick()、createPaddle()、createBall() 函数,用
来对砖块、划浆、和小球进行初始化。之后,设定定时器,每个 10 毫秒将调用一次
moveBall 函数。
最后,调用 changeColor 函数用来改变小球、砖块、划浆的颜色,函数 random-
Color 将返回一个随机颜色。
void Game::changeColor(){ srand( (int) time( NULL ) ); foreach( Brick *brick, bricks )brick->setColor( randomColor() ); ball->setColor( randomColor() ); paddle->setColor( randomColor() );}QColor Game::randomColor(){ return QColor( randomInt( 255 ), randomInt( 255 ), randomInt( 255 ) );}int Game::randomInt( int high ){ double d = (double)rand() / ( (double)RAND_MAX + 1 ); int k = (int) (d * ( high + 1 )); return k;}调用 randomInt( 255 ) 语句,将得到一个 0 至 255 的随机颜色,因此,
randomColor 函数能够产生随机颜色。
void Game::createBricks(){ qreal gap = 5.0; qreal brickWidth = frameWidth / ( columns + 1 ) - gap; qreal brickHeight = frameHeight / 4 / ( rows + 1 ) - gap; for( int r = 0; r < rows; ++r )for( int c = 0; c < columns; ++c ){ Brick *brick = new Brick( brickWidth / 2 + c * ( brickWidth + gap ), brickHeight / 2 + r * ( brickHeight + gap ), brickWidth, brickHeight ); bricks.append( brick );}}void Game::createPaddle(){ qreal paddleWidth = frameWidth / 10; qreal paddleHeight = paddleWidth / 5; paddle = new Paddle( frameWidth / 2 - paddleWidth / 2 , frameHeight - paddleHeight * 2, paddleWidth, paddleHeight );}void Game::createBall(){ qreal ballSide = paddle->getShape().height(); ball = new Ball( frameWidth / 2 - ballSide / 2, paddle->getShape().top() - ballSide, ballSide );}createBricks 中的变量 gap 表示砖块之间的距离,只有这个变量是不随着窗口
的缩放而改变的。可以注意到,砖块、划浆、小球的大小都是根据预设的窗格的大小来
确定的。其中,用 QList< Brick * > 类型的变量 bricks 来保存 Brick 对象,总
共有 5 行 10 列即 50 个 Brick 对象。在 createBall 函数中,将小球的直径设定
成划浆的高度。
void Game::resizeEvent( QResizeEvent * ){ qreal scaleWidth = rect().width() / frameWidth; qreal scaleHeight = rect().height() / frameHeight; foreach( Brick *brick, bricks ) {QRectF shape = brick->getShape();brick->setShape( adjustShape( shape, scaleWidth, scaleHeight ) ); } QRectF ballShape = ball->getShape(); ball->setShape( adjustShape( ballShape, scaleWidth, scaleHeight ) ); ball->setSpeed( ball->getSpeed() * scaleWidth ); QRectF paddleShape = paddle->getShape(); paddle->setShape( adjustShape( paddleShape, scaleWidth, scaleHeight ) ); paddle->setStep( paddle->getStep() * scaleWidth ); frameWidth = rect().width(); frameHeight = rect().height();}QRectF Game::adjustShape( QRectF shape, qreal scaleWidth, qreal scaleHeight ){ QRectF newShape( shape.left() * scaleWidth, shape.top() * scaleHeight, shape.width() * scaleWidth, shape.height() * scaleHeight ); return newShape;}当窗格大小发生变化时,程序将会调用 resizeEvent 函数,这时 rect().width()
和 rect().height() 将会分别返回当前窗格的宽度和高度,因此,scaleWidth 变量
表示宽度的缩放因子,而 scaleHeight 表示高度的缩放因子,adjustShape 函数能
根据这些缩放因子对其接受的参数 shape 进行相应的缩放,并返回一个经缩放之后的
新矩形。
当窗口发生变化时,也应相应地增大或缩小小球的移动速度和划浆的水平移动距
离,由于划浆的移动步长窗格水平宽度相关,小球的移动速度又与划浆的移动步长相
关,因此,这里使用 scaleWidth 作为缩放因子。
最后,需要将当前窗格的高度和宽度进行保存。
Game::~Game(){ delete ball; delete paddle; while( !bricks.isEmpty() )delete bricks.takeFirst();}
析构函数用来删除变量,QList 的 takeFirst 函数能将第一个对象指针从进行
QList 中移除并返回这个指针,因此,可以通过 delete 一个 Brick 指针来删除一
个 Brick 对象。
void Game::paintEvent( QPaintEvent * ){ QPainter painter( this ); if( isWin || isFailure ) {QFont font( "Courier", 20, QFont::DemiBold );QFontMetrics fm( font );painter.setFont( font );painter.translate( QPoint( width() / 2, height() / 2 ) );if( isWin ){ int textWidth = fm.width( "You are winner!" ); painter.setPen( Qt::blue ); painter.drawText( -textWidth / 2, 0, tr( "You are the winner!" ) );}else{ int textWidth = fm.width( "You are loser!" ); painter.setPen( Qt::red ); painter.drawText( -textWidth / 2, 0, tr( "You are the loser!" ) );}timer->stop();emit finished();return; } painter.setPen( Qt::NoPen ); painter.setBrush( ball->getColor() ); painter.drawEllipse( ball->getShape() ); painter.fillRect( paddle->getShape(), paddle->getColor() ); foreach( Brick *brick, bricks )painter.fillRect( brick->getShape(), brick->getColor() );}
paintEvent 函数由程序自动调用,用来对窗格进行绘制。每次绘制之前,都需要
对 isWin 和 isFailure 变量进行确认,当二者之一为 true 时,说明程序运行结
束,这时,将在窗格中绘制相应的文本,再将定时器暂停,发送一个 finished 信号,
并调用 return 语句进行返回。当游戏在进行时,则需要对窗格进行绘制,这时,调
用 painter.setPen( Qt::NoPen ); 语句能设置在绘制时使用画刷而不使用画笔。
void Game::movePaddleLeft(){ if( paddle->getLeft() > rect().left() ) {paddle->moveLeft();update(); }}void Game::movePaddleRight(){ if( paddle->getRight() < rect().right() ) {paddle->moveRight();update(); }}void Game::startGame(){ timer->start();}void Game::stopGame(){ timer->stop();}
以上 4 个槽函数为 Game 提供了外部接口,用来为其它 widget 提供控制划浆移
动、开始游戏、停止游戏的接口。例如,当 Game 对象作为 QMainWindow 的中央部
件时,通过连接相应的信号和槽,就能通过键盘按键或程序菜单来控制游戏的暂停和开
始,或控制划浆的左右移动。
void Game::moveBall(){ ball->move(); QRectF ballShape = ball->getShape(); QRectF paddleShape = paddle->getShape(); qreal ballLeft = ballShape.left(); qreal ballRight = ballShape.right(); qreal ballBottom = ballShape.bottom(); qreal ballTop = ballShape.top(); qreal ballCenterX = ( ballShape.left() + ballShape.right() ) / 2; qreal paddleCenterX = ( paddleShape.left() + paddleShape.right() ) / 2; if( ballLeft < rect().left() || ballRight > rect().right() )ball->setDirX( -ball->getDirX() ); if( ballBottom >= paddleShape.top() ) { if( paddleShape.intersects( ballShape ) ) { if( ballCenterX < paddleCenterX ) ball->setDirX( -ball->getDirX() ); ball->setDirY( -ball->getDirY() ); } else { isFailure = true; update(); return; } } if( ballTop < rect().top() )ball->setDirY( -ball->getDirY() ); else {for( int i = 0; i < bricks.size(); ++i ){ Brick *brick = bricks.at( i ); QRectF brickShape = brick->getShape(); if( brickShape.intersects( ball->getShape() ) ) {ball->setDirY( -ball->getDirY() );Brick *temp = bricks.takeAt( i );delete temp;score += 100;emit scoreChanged( score ); }}if( bricks.size() == 0 )isWin = true; } update();}
moveBall() 槽函数在定时器的作用下,每隔固定时间都会被调用。ballLeft 和
ballRight 局部变量用来保存小球左右两侧的横坐标,当小球撞击到窗格的左右两边
时,设置其水平运动方向与原来相反,以此来实现小球反弹。
当小球的底部到达划浆的顶部所在的水平线时,需要判断小球与划浆是否有重合部
分来判断其是否发生撞击。调用 QRectF 的 intersectd 函数来判断两个 QRect 对
象是否发生重合,若有重合部分,则返回 true。
bool intersects ( const QRectF & rectangle ) const
当小球与划浆没有撞击时,则表示游戏失败,设置 isFailure 变量为 true。其
次,需要判断小球顶部是否与砖块或窗格进行撞击。最后,当砖块的数目为 0 时,则
说明游戏取胜。
void Game::setBallSpeed( qreal speed ){ ball->setSpeed( speed );}void Game::setPaddleStep( qreal step ){paddle->setStep( step );}
GameWindow 游戏主窗口
gamewindow.h
#ifndef _GAMEWINDOW_H_#define _GAMEWINDOW_H_#include "game.h" #include <QMainWindow> class QAction;class QKeyEvent;class QLabel;class GameWindow : public QMainWindow{ Q_OBJECTpublic: GameWindow(); public slots: void on_changeColor(); void on_newGame(); void on_startGame(); void on_stopGame(); void on_about(); void on_finished(); void on_gameOne(); void on_gameTwo(); void on_gameThree(); void on_changeScore( int ); protected: void keyPressEvent( QKeyEvent * ); private: void createMenu(); void createToolBar(); void updateActions(); void createNewGame( int ); QAction *newGame; QAction *aboutAction; QAction *startGame; QAction *stopGame; QAction *exitGame; QAction *changeColor; QAction *gameOne; QAction *gameTwo; QAction *gameThree; QLabel *gameLabel; QLabel *scoreLabel; Game *game; bool isRunning;};#endifgamewindow.cpp
#include "gamewindow.h"#include <QAction>#include <QMenuBar>#include <QToolBar>#include <QMessageBox>#include <QKeyEvent>#include <QLabel>GameWindow::GameWindow(){ isRunning = false; game = new Game( this ); setCentralWidget( game ); createMenu(); createToolBar(); connect( game, SIGNAL( finished() ), this, SLOT( on_finished() ) ); connect( game, SIGNAL( scoreChanged( int ) ), this, SLOT( on_changeScore( int ) ) ); resize( 600, 480 ); setWindowTitle( tr( "The Game" ) );}void GameWindow::createMenu(){ newGame = new QAction( QIcon( ":/images/newgame.png" ), tr( "New Game" ), this ); exitGame = new QAction( QIcon( ":/images/exit.png" ), tr( "Exit" ), this ); startGame = new QAction( QIcon( ":/images/start.png" ), tr( "Start" ), this ); stopGame = new QAction( QIcon( ":/images/stop.png" ), tr( "Stop" ), this ); changeColor = new QAction( QIcon( ":/images/changecolor.png" ), tr( "Change Color" ), this ); aboutAction = new QAction( QIcon( ":/images/about.png" ), tr( "about" ), this ); gameOne = new QAction( QIcon( ":/images/game.png" ), tr( "Game One" ), this ); gameTwo = new QAction( QIcon( ":/images/game.png" ), tr( "Game Two" ), this ); gameThree = new QAction( QIcon( ":/images/game.png" ), tr( "Game Three" ), this ); QMenu *optionMenu = menuBar()->addMenu( tr( "Option" ) ); QMenu *controlMenu = menuBar()->addMenu( tr( "Control" ) ); QMenu *setMenu = menuBar()->addMenu( tr( "Set" ) ); QMenu *gameMenu = menuBar()->addMenu( tr( "Game" ) ); QMenu *helpMenu = menuBar()->addMenu( tr( "Help" ) ); optionMenu->addAction( newGame ); optionMenu->addAction( exitGame ); controlMenu->addAction( startGame ); controlMenu->addAction( stopGame ); setMenu->addAction( changeColor ); gameMenu->addAction( gameOne ); gameMenu->addAction( gameTwo ); gameMenu->addAction( gameThree ); helpMenu->addAction( aboutAction ); connect( startGame, SIGNAL( triggered() ), this, SLOT( on_startGame() ) ); connect( exitGame, SIGNAL( triggered() ), this, SLOT( close() ) ); connect( changeColor, SIGNAL( triggered() ), this, SLOT( on_changeColor() ) ); connect( stopGame, SIGNAL( triggered() ), this, SLOT( on_stopGame() ) ); connect( newGame, SIGNAL( triggered() ), this, SLOT( on_newGame() ) ); connect( aboutAction, SIGNAL( triggered() ), this, SLOT( on_about() ) ); connect( gameOne, SIGNAL( triggered() ), this, SLOT( on_gameOne() ) ); connect( gameTwo, SIGNAL( triggered() ), this, SLOT( on_gameTwo() ) ); connect( gameThree, SIGNAL( triggered() ), this, SLOT( on_gameThree() ) ); updateActions();}void GameWindow::createToolBar(){ QToolBar *controlToolBar = addToolBar( tr( "Control" ) ); controlToolBar->addAction( newGame ); controlToolBar->addAction( startGame ); controlToolBar->addAction( stopGame ); controlToolBar->addAction( changeColor ); controlToolBar->addSeparator(); gameLabel = new QLabel( tr( "<h3><font color=blue>Game One</font></h3>" ), this ); scoreLabel = new QLabel( tr( "<h3><font color=green>Score: 0</font></h3>" ), this ); controlToolBar->addWidget( gameLabel ); controlToolBar->addSeparator(); controlToolBar->addWidget( scoreLabel );}createMenu 和 createToolBar 函数用来创建菜单以及工具栏,并将创建的动作
与相应的槽相连接。
void GameWindow::on_finished(){ stopGame->setEnabled( false ); startGame->setEnabled( false ); changeColor->setEnabled( false );}void GameWindow::on_changeScore( int score ){ scoreLabel->setText( tr( "<h3><font color=blue>Score: %1</font></h3>" ).arg( score ) );}当游戏结束时,Game 对象将会发出 finished 信号,在 on_finished() 槽中,
将相应的动作设置为不可用。
void GameWindow::on_newGame(){ createNewGame( 1 );}void GameWindow::createNewGame( int gameNum ){ if( gameNum == 1 )gameLabel->setText( tr( "<h3><font color=blue>Game One</font></h3>" ) ); else if( gameNum == 2 )gameLabel->setText( tr( "<h3><font color=blue>Game Two</font></h3>" ) ); else if( gameNum == 3 )gameLabel->setText( tr( "<h3><font color=blue>Game Three</font></h3>" ) ); on_changeScore( 0 ); game->deleteLater(); game = new Game( this ); setCentralWidget( game ); game->setBallSpeed( gameNum ); game->setPaddleStep( gameNum * 10.0 ); connect( game, SIGNAL( finished() ), this, SLOT( on_finished() ) ); connect( game, SIGNAL( scoreChanged( int ) ), this, SLOT( on_changeScore( int ) ) ); isRunning = false; changeColor->setEnabled( true ); updateActions(); }
void GameWindow::on_gameTwo(){ createNewGame( 2 );}void GameWindow::on_gameThree(){ createNewGame( 3 );}在 createNewGame 函数中,将原先 game 所指向的对象删除,并创建新的 Game
对象,需要注意的是,创建了新的 Game 对象,则表示由原先 game 所指向对象建立的
信号和槽的关系将失效,因此,需要重新连接相应的信号和槽。调用 createNewGame
函数时,传入的参数能用来设置小球的速度,以此来增加游戏的难度。
void GameWindow::on_about(){ QMessageBox::about( this, tr( "About" ), tr( "This is a small game developed by SenLin." ) );}void GameWindow::updateActions(){ startGame->setEnabled( !isRunning ); stopGame->setEnabled( isRunning );}void GameWindow::on_startGame(){ game->startGame(); isRunning = true; updateActions();}void GameWindow::on_stopGame(){ game->stopGame(); isRunning = false; updateActions();}
on_startGame 和 on_stopGame 函数用来设置游戏的启动和暂停。
void GameWindow::keyPressEvent( QKeyEvent *event ){ switch( event->key() ) { case Qt::Key_Left: game->movePaddleLeft(); break; case Qt::Key_Right: game->movePaddleRight(); break; }}main.cpp
#include "gamewindow.h"#include <QApplication>#include <QTranslator>int main(int argc, char **argv ){ QApplication app( argc, argv ); QTranslator translator; translator.load( ":language/game_zh_CN.qm" ); app.installTranslator( &translator ); GameWindow window; window.show(); return app.exec(); }在 main 函数中,载入 game_zh_CN.qm 文件,载入这个文件能将程序翻译成为中文,
需要注意的是,为程序载入 qm 文件,需要在 winow.show() 语句之前进行。
resource.qrc
<!DOCTYPE RCC><RCC version="1.0"><qresource><file>images/about.png</file><file>images/changecolor.png</file><file>images/exit.png</file><file>images/newgame.png</file><file>images/start.png</file><file>images/stop.png</file> <file>images/game.png</file> <file>language/game_zh_CN.qm</file></qresource></RCC>将程序使用的按键图标放在 images 文件夹中,将.qm 文件放在 language 文件夹
中,另外,在.pro 文件中加入:
RESOURCES += resource.qrc
为游戏制作图标,选择 ico 格式的图表,将其命名为 game.ico 文件。新建文件
game.rc, 写入以下内容:
IDI_ICON1 ICON DISCARDABLE ”game.ico”
并且需要在.pro 文件中加入:
RC_FILE += game.rc
- Qt打砖块游戏
- 打砖块游戏源码
- android 打砖块游戏
- js打砖块游戏
- 打砖块游戏 version 0.2
- java打砖块游戏初稿
- Python+pyGame 打砖块游戏
- 一个打砖块游戏算法
- Silverlight版本的打砖块游戏
- JavaFX打砖块游戏开发 第一课
- JavaFX打砖块游戏开发 第二课
- JavaFX打砖块游戏开发 第三课
- HTML5-CANVAS做的打砖块游戏
- Js版游戏打砖块源代码详细
- Android游戏:弹弹球(打砖块)
- Java编写打砖块 经典游戏设计
- pygame写的打砖块游戏
- 基于Unity3D的打砖块游戏开发
- C++[算法]用数组模拟约瑟夫问题,即 N个人围成一圈,顺时针每数到给定K值的人出列,直到剩下最后一个人,求出圈人的序号顺序
- ios强制横屏
- C语言连接MySQL数据库
- win7下iis配置
- Android学习之绘图入门
- Qt打砖块游戏
- zookeeper 权限控制
- 虚拟机 网络类型 网络模式 桥接 NAT host-only
- 堆
- JPA与Hibernate的优缺点
- 设置浮点数精度 setprecision
- 阿里云服务器centos下安装配置svn服务器
- 使用super身份对有权限的节点进行操作
- QT实现(4)