Qt版贪吃蛇游戏

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()));

还有一个小细节就是随机函数:qsrand() 用于产生食物的位置:

//产生食物
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

时间: 2024-08-25 17:31:13

Qt版贪吃蛇游戏的相关文章

qtday03 简单版的贪吃蛇游戏

//snakegame.h #ifndef SNAKEGAME_H #define SNAKEGAME_H #include<QList> #include<QtWidgets/QLabel> #include<QtWidgets/QDialog> #include<QKeyEvent> #include<QTimer> /*枚举,表示方向*/ enum Direction{D_UP,D_DOWN,D_LEFT,D_RIGHT}; class S

Java版贪吃蛇小游戏的实现

使用的IDE eclipse JDK版本 1.6 辅助类 Coordinate.java package com.nn.util; /** *坐标点 */ public class Coordinate { public int x; public int y; public Coordinate(int newX, int newY) { x = newX; y = newY; } public boolean equals(Coordinate other) { if (x == other

Java版贪吃蛇(比较完善的版本)

很认真的写的一个java版的贪吃蛇游戏,图形界面,支持菜单操作,键盘监听,可加速,减速,统计得分,设定运动速度,设定游戏背景颜色等!应该没有Bug了,因为全被我修改没了.哈哈. 下面是项目各包及类的层次关系: 游戏的主要运行界面截图如下: 下面是部分代码,详细源码见此链接:http://pan.baidu.com/s/1bnubnzh //Snake类: package com.huowolf.entities; import java.awt.Color; import java.awt.Gr

贪吃蛇游戏

学习C语言也差不多学完了想做一个游戏,而贪吃蛇和俄罗斯方块都是非常经典的游戏,在网上也找到了许多相关的参考资料,便动手做了,这个游戏室控制台版的 游戏流程图 函数模块 函数名 函数功能 CursorPosition 光标定位函数 CreateSnake 蛇初始化函数 ShowWall 显示墙体 UpdateSnake 更新界面上的蛇体.分数.等级.食物 CollisionDetection 判断蛇是否咬到自己 RandFood 随机产生食物 Move 控制方向 程序代码 #include <st

OC版贪吃蛇

昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些,有想看js版的可以看我上一篇随笔 程序中没用到任何素材,效果图如下: github源码地址:https://github.com/masterChunlinHan/snake_OC 下面开始,跟js版一样,为了方便学习,所有代码都写在一个controller中,所以头文件中什么也不用写 #impor

Android快乐贪吃蛇游戏实战项目开发教程-01项目概述

一.项目简介贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏.我已经将做好的案例上传到了应用宝,大家可以下载下来把玩一下.为了和其它的贪吃蛇区别开来,我取名叫“快乐贪吃蛇”.应用宝链接:http://sj.qq.com/myapp/detail.htm?apkName=net.chengyujia.happysnake这里上两张截图先睹为快,哈哈.怎么玩大家应该都知道,不过我还是要多提一下.通过屏幕上的方向键控制蛇的前进方向.蛇每吃到一个食物身体会

easyx图形库做贪吃蛇游戏

编程总是对着一个黑窗口,可以说是非常乏味了,于是喵喵就翻出来了以前用easyx图形库做图形界面的贪吃蛇游戏. 不过大家只是当做提高编程的乐趣来学习吧,想进一步做的话可以学习QT,还有其他的框架. 这是一个easyx图形库的学习教程,建议大家学完再看本文: https://www.easyx.cn/skills/List.aspx?id=7 首先看一下效果图: 实现的功能: 基本的吃食物长大,撞墙死亡,特殊食物,游戏暂停,重开游戏,记分数的功能. 游戏最高分的记录. 游戏关卡的选择. 加了游戏的音

JS贪吃蛇游戏

<!DOCTYPE html><html> <head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <title>JS贪吃蛇游戏</title>    <style>    * {        margin: 0;    

用Java开发贪吃蛇游戏

贪吃蛇游戏的设计步骤: Part 1: 设计游戏图纸 画出900*700的白色窗口 在窗口上添加画布 在画布上添加标题 在画布上添加黑色游戏区 Part 2: 放置静态的蛇:一个头.两个身体 加上开始提示:按空格键开始游戏 让蛇动起来:监听Timer事件,平移数据 实现游戏暂停 实现转向功能 Part 3: 添加食物 吃掉食物 添加死亡条件 实现“重新开始”功能 添加分数和长度 游戏图纸如下: 蛇及游戏框的素材如下:                              Snake主类: 1