Qt版贪吃蛇游戏
转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907
最近在学习Qt,用了一个多月的时间掌握了Qt中最基本的知识,也完成了《Qt版音乐播放器》、《Qt版贪吃蛇游戏》、《Qt版双人俄罗斯方块》以及《Qt版科学计算器》等,之前在VC下写过这些程序,所以在Qt下只是改变了显示等语句,我写过《C++版贪吃蛇游戏》、《VC版贪吃蛇游戏》,当时将与显示等无关的东西封装起来,在Qt下直接用,只改变了显示等语句。
以下是Windows 7下运行截图:
以下是Ubuntu下运行截图:
我在Windows下编写好之后,将源码在Ubuntu下重新编译运行,就可以在Ubuntu下运行,这也充分体现出Qt一次编写,到处运行的优势。
关于贪吃蛇游戏的设计原理就不讲了,具体可以参考我的博客《C++版贪吃蛇游戏》、《VC版贪吃蛇游戏》。
下面主要说一下Qt与VC不同的东西。
先看头文件中变量以及槽的定义:
class Snake : public QMainWindow { Q_OBJECT public: explicit Snake(QWidget *parent = 0); ~Snake(); private slots: void gameStart(); void onPause(); void superSpeed(); void fastSpeed(); void midSpeed(); void slowSpeed(); void verySlowSpeed(); private: Ui::Snake *ui; int image[20][20]; //游戏面板,即小蛇活动范围 int FoodX; //事物出现的X坐标 int FoodY; //事物出现的Y坐标 int snakeX; //记录小蛇的头部X坐标 int snakeY; //记录小蛇的头部Y坐标 int head; //小蛇头部下标 int tail; //小蛇尾部下标 int snake[2][20000]; //记录小蛇所有身体的坐标 int node; //小蛇的节数 int direction; //小蛇头部的方向 int i,j; int gamespeed; //速度 int score; //记录分数 bool IsPause; //暂停 bool p; int GameOver; //使游戏结束的变量 int level; //设置等级 int length; //为了设置等级而与node一样记录设的长度 int timerID; ///////////// void ReInit(); int DrawSnake(); //记录小蛇每次移动后头部及身体的下一坐标 void Automove(); //使小蛇自动移动 int Gameover(); //判断游戏是否结束 int Generatefood(); //产生食物 void shiftLeft(); //控制左移 void shiftRight(); //控制右移 void shiftDown(); //控制下移 void shiftUp(); //控制上移 protected: void keyPressEvent(QKeyEvent *event); void timerEvent(QTimerEvent *event); void paintEvent(QPaintEvent *event); };
void keyPressEvent(QKeyEvent *event); void timerEvent(QTimerEvent *event); void paintEvent(QPaintEvent *event);三个槽的实现是Qt的方式。
转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907
具体代码如下:
///////////////////////////////////////////// void Snake::keyPressEvent(QKeyEvent *event) { if(direction == 2 || direction == 8) { if(event->key() == Qt::Key_Right) shiftRight(); else if(event->key() == Qt::Key_Left) shiftLeft(); else if(event->key() == Qt::Key_0) onPause(); } else if(direction == 4 || direction == 6) { if(event->key() == Qt::Key_Up) shiftUp(); else if(event->key() == Qt::Key_Down) shiftDown(); else if(event->key() == Qt::Key_0) onPause(); } } void Snake::timerEvent(QTimerEvent *event) { if(event->timerId() == timerID) { if(!GameOver) { if(!IsPause) Automove(); // 小蛇自动移动 Gameover(); //判断游戏是否结束 if(GameOver==1) { killTimer(timerID); if(level>8) if(QMessageBox::question(this,tr("提示"),tr("你一定是骨灰级玩家!小弟佩服!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes) { ReInit(); gameStart(); } else close(); else if(level>5) if(QMessageBox::question(this,tr("提示"),tr("你一定是高手!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes) { ReInit(); gameStart(); } else close(); else if(QMessageBox::question(this,tr("提示"),tr("继续努力!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes) { ReInit(); gameStart(); } else close(); } DrawSnake(); //判断是否吃食物 } this->repaint(); } } void Snake::paintEvent(QPaintEvent *event) { QPainter painter(this); int nSize = 20; int offset = 1; QImage img; img.load(":/images/border.png"); QBrush brushborder(img); painter.setBrush(brushborder); QRect bottomrec(0,nSize*22+offset,nSize*22,nSize); painter.fillRect(bottomrec,brushborder); QRect toprec(0,20+offset,nSize*22,nSize); painter.fillRect(toprec,brushborder); QRect leftrec(0,20+offset,nSize,nSize*21); painter.fillRect(leftrec,brushborder); QRect rightrec(nSize*21,20+offset,nSize,nSize*21); painter.fillRect(rightrec,brushborder); QRect rect(20,40+offset,nSize*20,nSize*20); QImage imageBack; imageBack.load(":/images/grass.png"); QBrush brushBack(imageBack); painter.setBrush(brushBack); painter.drawRect(rect); QRect rc; QBrush brush(QColor(255,0,0)); painter.setBrush(brush); QString Level = "Level:"; Level += QString::number(level); ui->label_Level->setText(Level); QString Score = "Score:"; Score += QString::number(score); ui->label_Score->setText(Score); for(i=0;i<20;i++) { for(j=0;j<20;j++) { rc = QRect(j*nSize+20,i*nSize+40+offset,nSize,nSize); if(image[i][j]!=0) { if(image[i][j]==3) { QImage img; img.load(":/images/body.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } else if(image[i][j] == 1) { if(direction==2) { QImage img; img.load(":/images/headdown.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } else if(direction == 4) { QImage img; img.load(":/images/headleft.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } else if(direction == 6) { QImage img; img.load(":/images/headright.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } else { QImage img; img.load(":/images/headup.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } } else if(image[i][j] == 2) { QImage img; img.load(":/images/apple.png"); QBrush brush(img); painter.setBrush(brush); painter.fillRect(rc,brush); } } } } } //////////////////////////////////////////////////////////////////////
///////////////////////////////////////// connect(ui->action_startGame, SIGNAL(triggered()), this, SLOT(gameStart())); connect(ui->action_pause, SIGNAL(triggered()) ,this, SLOT(onPause())); connect(ui->action_quit, SIGNAL(triggered()), this, SLOT(close())); connect(ui->action_veryFast, SIGNAL(triggered()), this, SLOT(superSpeed())); connect(ui->action_fast, SIGNAL(triggered()), this, SLOT(fastSpeed())); connect(ui->action_mid, SIGNAL(triggered()), this, SLOT(midSpeed())); connect(ui->action_slow, SIGNAL(triggered()), this, SLOT(slowSpeed())); connect(ui->action_verySlow, SIGNAL(triggered()), this, SLOT(verySlowSpeed()));
//产生食物 int Snake::Generatefood() { qsrand(QTime::currentTime().msec()); //以时间为种子生成随机序列 do{ FoodX=qrand()%20; //食物输出的X坐标 FoodY=qrand()%20; //食物输出的Y坐标 }while(image[FoodX][FoodY]!=0); //产生的食物坐标限定在游戏面板内,且食物坐标不与小蛇身体坐标重合 image[FoodX][FoodY]=2; return image[FoodX][FoodY]; }
原文:http://blog.csdn.net/u012027907/article/details/43970135