Qt实现贪吃蛇游戏

有些话、适合烂在心里 提交于 2020-12-23 15:26:30

效果如下:

输入图片说明

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

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

源码地址: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;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!