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 函数,用来设置划浆移动的步长,
特别是当程序的窗口进行缩放时,划浆每次移动的距离也应相应地发生改变。

paddle.cpp

#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;};#endif 
game.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;};#endif 
gamewindow.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











1 0
原创粉丝点击