Qt实现贪吃蛇游戏

Stella981
• 阅读 688

效果如下:

Qt实现贪吃蛇游戏

由于是个人为了学习而实现的,隐藏图片比较粗糙,有兴趣的可以自己优化,仅作学习参考。

游戏比较简单主要包括绘制墙壁、食物、蛇、网格, 以及一些逻辑运算组成。

源码地址:https://gitee.com/lingluonianhua/Snake.git

核心代码如下:

#include "snakelogic.h"
#include <QPixmap>

SnakeLogic::SnakeLogic(QPoint left,QPoint right,int unit,QObject *parent) :
    QObject(parent),m_pLeftTop(left),m_pRight(right),m_iUnitage(unit),
    m_icoortable(NULL),m_lSnakeList(NULL)

{
    InitParam();
    memset(m_pFoodArr,0,sizeof(m_pFoodArr));
    QPoint rect = m_pRight - m_pLeftTop;
    m_iNumX = rect.x()/m_iUnitage;
    m_iNumY = rect.y()/m_iUnitage;
    m_icoortable = new int*[m_iNumY ];
    for(int i = 0; i < m_iNumY ; i++)
    {
        m_icoortable[i] = new int[m_iNumX ];
    }
    InitMap();
}
void SnakeLogic::start()
{
    try
    {
        if(m_lSnakeList != NULL)
        {
            this->CleanSnake();
            delete m_lSnakeList;
        }
        m_lSnakeList = new QList<QPoint>;
        this->InitParam();
        this->InitSnake();
        this->CreateFood();
        this->m_bIsStart = true;
    }
    catch(...)
    {

    }
}
void SnakeLogic::CleanSnake()
{
    QList<QPoint>::const_iterator item = m_lSnakeList->begin();
    while(item != m_lSnakeList->end())
    {
        m_lSnakeList->pop_front();
        item++;
    }
}
void SnakeLogic::InitParam()
{
    m_pCurDir =  QPoint(1,0);
    m_bListRev = false;
    m_iFoodNum = 0;
    m_iScore = 0;
    m_iLevel = 0;
    m_bIsPause = false;
    m_bIsStart = false;
    m_bIsGameOver = false;
}
void SnakeLogic::InitSnake()
{
    if(!m_lSnakeList)
        return ;
    while(!m_lSnakeList->isEmpty())
    {
        m_lSnakeList->pop_back();
    }
    QPoint one(4,2);
    QPoint two(3,2);
    QPoint three(2,2);
    m_lSnakeList->push_back(one);
    m_lSnakeList->push_back(two);
    m_lSnakeList->push_back(three);
}
void SnakeLogic::InitMap()
{
    for(int i = 0;i < m_iNumY ; i++)
    {
        for(int j = 0; j < m_iNumX ; j++)
        {
            if(i == 0 || j == 0 || i == m_iNumY - 1  || j == m_iNumX - 1 )
            {
                m_icoortable[i][j] = 1;
            }
            else
            {
                m_icoortable[i][j] = 0;
            }
        }
    }
}
void SnakeLogic::Paint(QPainter *p)
{
    try
    {
        this->PaintGridding(p);
        this->PaintWall(p);
        this->PaintSnake(p);
        this->PaintFood(p);
    }
    catch(...)
    {

    }
}

void SnakeLogic::PaintWall(QPainter *p)      //ǽ
{
    QPixmap img("://res/855.bmp");
    QImage bk("://res/wall.bmp");
    QBrush brsh;
    brsh.setTextureImage(bk);
    p->setOpacity(0.5);
    p->fillRect(m_pLeftTop.x(),m_pLeftTop.y(),m_pRight.x(),m_pRight.y(),brsh);
    p->setOpacity(1.0);
    for(int i = 0;i < m_iNumY ; i++)
    {
        for(int j = 0; j < m_iNumX  ; j++)
        {

            if(m_icoortable[i][j] == 1)
            {
                QPoint beg = GetConvPoint(QPoint(j,i));
                QRect rect(beg,beg + QPoint(m_iUnitage,m_iUnitage));
                p->drawPixmap(rect,img);
            }
        }
    }
}
void SnakeLogic::PaintGridding(QPainter *p)
{
    QColor clr(0,255,100);
    p->setPen(clr);
    for(int i = m_pLeftTop.x(); i <= m_pRight.x() ; i += m_iUnitage)
    {
        p->drawLine(i,m_pLeftTop.y(),i,m_pRight.y());
    }
    for(int i = m_pLeftTop.y(); i <= m_pRight.y() ; i += m_iUnitage)
    {
        p->drawLine(m_pLeftTop.x() ,i,m_pRight.x(),i);
    }
}
void SnakeLogic::PaintSnake(QPainter *p)
{
    if(!m_lSnakeList)
        return;
    QPixmap img("://res/849.bmp");
    QList<QPoint>::const_iterator item = m_lSnakeList->begin();
    QPoint unit(1,1);
    while(item != m_lSnakeList->end())
    {
        QPoint beg = GetConvPoint(*item ) + unit ;
        QRect rect(beg,beg + QPoint(m_iUnitage - 2,m_iUnitage - 2));
        p->drawPixmap(rect,img);
        item++;
    }
}
void SnakeLogic::PaintFood(QPainter *p)
{

    QPixmap img("://res/small.bmp");
    QPoint unit(1,1);
    for(int i = 0; i < m_iFoodNum; i++)
    {
        QPoint beg = GetConvPoint(m_pFoodArr[i]) + unit ;
        QRect rect(beg,beg + QPoint(m_iUnitage - 2,m_iUnitage - 2));
        p->drawPixmap(rect,img);

    }
}
void SnakeLogic::CreateFood()     //ʳ
{
    int i,j;
    while(1)
    {
        while(1)
        {
            i = qrand()%m_iNumX;
            if(i > 0 && i < m_iNumX )
            break;
        }
        while(1)
        {
            j = qrand()%m_iNumY;
            if(j > 0 && j < m_iNumY)
                break;
        }
        if(m_icoortable[j][i] == 0)
        {
            m_icoortable[j][i] = 2;
            break;
        }
    }
    QPoint food(i,j);
    m_pFoodArr[m_iFoodNum++] = food;
}
QPoint SnakeLogic::GetConvPoint(QPoint sourcePos)
{
    return sourcePos * m_iUnitage + m_pLeftTop;
}

void SnakeLogic::Move(QPoint& dir)
{
    if(m_bIsPause || m_bIsGameOver)
        return;
    QPoint tmp(0,0);
    if(dir + m_pCurDir == tmp)
    {
        QPoint newDir;
        if(CheckDirection(newDir))
        {
            m_pCurDir = dir;
        }
        else
        {
            m_pCurDir = newDir;
        }
        m_bListRev = !m_bListRev;
    }
    else
    {
        m_pCurDir = dir;
    }
    Move();

}
void SnakeLogic::Move()
{
    if(m_bIsPause || m_bIsGameOver)
        return;
    if(!m_lSnakeList || m_lSnakeList->isEmpty())
        return;
    int ch = CheckMove();
    if(ch == -1)
    {
        this->m_bIsGameOver = true;
        emit gameOver();
        return ;
    }
    if(ch == 0)
    {
        return;
    }
    if(m_bListRev)
    {
        m_lSnakeList->pop_front();
        QList<QPoint>::const_iterator item = m_lSnakeList->end();
        QPoint newPos = *(item - 1) + m_pCurDir;
        m_lSnakeList->push_back(newPos);
    }
    else
    {
        m_lSnakeList->pop_back();
        QList<QPoint>::const_iterator item = m_lSnakeList->begin();
        QPoint newPos = *item + m_pCurDir;
        m_lSnakeList->push_front(newPos);
    }
}

int SnakeLogic::CheckMove()
{
    QPoint nextPos;
    if(m_bListRev)
    {
        QList<QPoint>::const_iterator item = m_lSnakeList->end();
        nextPos = *(item - 1) + m_pCurDir;
    }
    else
    {
        nextPos = *m_lSnakeList->begin() + m_pCurDir;
    }
    if(m_lSnakeList->contains(nextPos))
        return -1;
    if(CheckFood(nextPos))
    {
        return 0;
    }
    return    CheckRect(nextPos)?1:-1;
}
bool SnakeLogic::CheckRect(QPoint& pos)
{
    if(pos.x() < 1 || pos.y() < 1 || pos.x() >= m_iNumX -1 || pos.y() >= m_iNumY - 1)
        return false;
    if(1 == m_icoortable[pos.y()][pos.x()])
        return false;
    return true;
}
bool SnakeLogic::CheckFood(QPoint& pos)
{
    if(m_icoortable[pos.y()][pos.x()] == 2)
    {
        if(m_bListRev)
        {
            m_lSnakeList->push_back(pos);
        }
        else
        {
            m_lSnakeList->push_front(pos);
        }
        m_iFoodNum--;
        m_icoortable[pos.y()][pos.x()] = 0;
        CreateFood();
        m_iScore += 10;
        emit chageScore(m_iScore);
        emit chageLevel(m_iScore/100);
        return true;
    }
    return false;
}
bool SnakeLogic::CheckDirection(QPoint& redir)
{
    QPoint tmpDir;
    if(m_bListRev)
    {
        //ͷ
        QList<QPoint>::const_iterator item = m_lSnakeList->begin();
        tmpDir = *(item + 1) - *item;
    }
    else
    {
        //β
        QList<QPoint>::const_iterator item = m_lSnakeList->end();
        tmpDir = *(item - 2) - *(item - 1);
    }
    if(tmpDir != m_pCurDir)
    {
        tmpDir.setX(-tmpDir.x());
        tmpDir.setY(-tmpDir.y());
        redir = tmpDir;
        return false;
    }
    return true;
}

// slots:
//void SnakeLogic::start()


void SnakeLogic::pause()
{
    this->m_bIsPause = !m_bIsPause;
}
点赞
收藏
评论区
推荐文章
Jack Jack
3年前
使用Java 语言编写一个贪吃蛇游戏
使用Java语言编写一个贪吃蛇游戏,代码如下:GreedSnake.javapackagejzjsfx;publicclassGreedSnakepublicstaticvoidmain(Stringargs)SnakeModelmodelnewSnakeModel(20,30);SnakeControlc
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
javafx实现贪吃蛇游戏
为了学习JavaFX今天决定做一款贪吃蛇的游戏。源码:http://git.oschina.net/flyfox/GameSnake(http://git.oschina.net/flyfox/GameSnake)已发布到oschina:http://www.oschina.net/p/javafxsnake(http://www.osch
Wesley13 Wesley13
3年前
javafx实现打砖块游戏
今天学习了一下JavaFX游戏部分参考博客:http://blog.csdn.net/ml3947(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.csdn.net%2Fml3947)本人源码地址:http://git.oschina.net/flyfox/Game
Souleigh ✨ Souleigh ✨
3年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Wesley13 Wesley13
3年前
FPS 游戏实现GDI透视
FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视,在透视实现难度上,方框透视是最复杂的一种,本教程将学习方框透视的实现算法,并编写通用辅助实现透视效果。方框透视的原理是通过读取游戏中已知坐标数据,并使用一
Wesley13 Wesley13
3年前
2D游戏作业:贪吃蛇
1.游戏介绍这款游戏通过上下左右键来引导贪吃蛇吃到食物从而贪吃蛇越变越长,当贪吃蛇碰到窗口的四壁是贪吃蛇撞死从而游戏结束。2\.开发工具VisualStudioCode3.部分代码介绍导入模块importpygame,sys,time,randomfromp
Stella981 Stella981
3年前
HTML5+CSS+JS 贪吃蛇demo
我写博客的主要目的就是温习所学的知识,自己以前写的游戏当然不能放过!这款网页版贪吃蛇是大一下册学习网页前端时老师教我们写的,由于那个时候初学网页前端,所以这款游戏是纯原生JavaScript写的,没有使用JQuery。重新看了一遍自己写的代码,大一的我真的太年轻了,一个注释都没有写,幸好这款游戏的逻辑不难,还能看得懂,补了一些注释,对一些细节加深了
Stella981 Stella981
3年前
Alamofire4.x开源代码分析(一)使用方法
!输入图片说明(https://static.oschina.net/uploads/img/201706/28090437_aIT1.png"在这里输入图片标题")本着了解框架的实现思路和学习Swift的目的开启本系列的博客.本系列参考Alamofire(https://www.oschina.net/action/GoToLink?urlh
Wesley13 Wesley13
3年前
H5游戏开发:贪吃蛇
!(https://oscimg.oschina.net/oscnet/fddb24a0205b45c3570ae548d65b445b475.jpg)贪吃蛇的经典玩法有两种:1\.积分闯关2\.一吃到底第一种是笔者小时候在掌上游戏机最先体验到的(不小心暴露了年龄),具体玩法是蛇吃完一定数量的食物后就通关,通关后速度会加快;第二种