效果如下:

由于是个人为了学习而实现的,隐藏图片比较粗糙,有兴趣的可以自己优化,仅作学习参考。
游戏比较简单主要包括绘制墙壁、食物、蛇、网格, 以及一些逻辑运算组成。
源码地址:https://gitee.com/lingluonianhua/Snake.git
核心代码如下:
1#include "snakelogic.h" 2#include <QPixmap> 3 4SnakeLogic::SnakeLogic(QPoint left,QPoint right,int unit,QObject *parent) : 5 QObject(parent),m_pLeftTop(left),m_pRight(right),m_iUnitage(unit), 6 m_icoortable(NULL),m_lSnakeList(NULL) 7 8{ 9 InitParam(); 10 memset(m_pFoodArr,0,sizeof(m_pFoodArr)); 11 QPoint rect = m_pRight - m_pLeftTop; 12 m_iNumX = rect.x()/m_iUnitage; 13 m_iNumY = rect.y()/m_iUnitage; 14 m_icoortable = new int*[m_iNumY ]; 15 for(int i = 0; i < m_iNumY ; i++) 16 { 17 m_icoortable[i] = new int[m_iNumX ]; 18 } 19 InitMap(); 20} 21void SnakeLogic::start() 22{ 23 try 24 { 25 if(m_lSnakeList != NULL) 26 { 27 this->CleanSnake(); 28 delete m_lSnakeList; 29 } 30 m_lSnakeList = new QList<QPoint>; 31 this->InitParam(); 32 this->InitSnake(); 33 this->CreateFood(); 34 this->m_bIsStart = true; 35 } 36 catch(...) 37 { 38 39 } 40} 41void SnakeLogic::CleanSnake() 42{ 43 QList<QPoint>::const_iterator item = m_lSnakeList->begin(); 44 while(item != m_lSnakeList->end()) 45 { 46 m_lSnakeList->pop_front(); 47 item++; 48 } 49} 50void SnakeLogic::InitParam() 51{ 52 m_pCurDir = QPoint(1,0); 53 m_bListRev = false; 54 m_iFoodNum = 0; 55 m_iScore = 0; 56 m_iLevel = 0; 57 m_bIsPause = false; 58 m_bIsStart = false; 59 m_bIsGameOver = false; 60} 61void SnakeLogic::InitSnake() 62{ 63 if(!m_lSnakeList) 64 return ; 65 while(!m_lSnakeList->isEmpty()) 66 { 67 m_lSnakeList->pop_back(); 68 } 69 QPoint one(4,2); 70 QPoint two(3,2); 71 QPoint three(2,2); 72 m_lSnakeList->push_back(one); 73 m_lSnakeList->push_back(two); 74 m_lSnakeList->push_back(three); 75} 76void SnakeLogic::InitMap() 77{ 78 for(int i = 0;i < m_iNumY ; i++) 79 { 80 for(int j = 0; j < m_iNumX ; j++) 81 { 82 if(i == 0 || j == 0 || i == m_iNumY - 1 || j == m_iNumX - 1 ) 83 { 84 m_icoortable[i][j] = 1; 85 } 86 else 87 { 88 m_icoortable[i][j] = 0; 89 } 90 } 91 } 92} 93void SnakeLogic::Paint(QPainter *p) 94{ 95 try 96 { 97 this->PaintGridding(p); 98 this->PaintWall(p); 99 this->PaintSnake(p); 100 this->PaintFood(p); 101 } 102 catch(...) 103 { 104 105 } 106} 107 108void SnakeLogic::PaintWall(QPainter *p) //ǽ 109{ 110 QPixmap img("://res/855.bmp"); 111 QImage bk("://res/wall.bmp"); 112 QBrush brsh; 113 brsh.setTextureImage(bk); 114 p->setOpacity(0.5); 115 p->fillRect(m_pLeftTop.x(),m_pLeftTop.y(),m_pRight.x(),m_pRight.y(),brsh); 116 p->setOpacity(1.0); 117 for(int i = 0;i < m_iNumY ; i++) 118 { 119 for(int j = 0; j < m_iNumX ; j++) 120 { 121 122 if(m_icoortable[i][j] == 1) 123 { 124 QPoint beg = GetConvPoint(QPoint(j,i)); 125 QRect rect(beg,beg + QPoint(m_iUnitage,m_iUnitage)); 126 p->drawPixmap(rect,img); 127 } 128 } 129 } 130} 131void SnakeLogic::PaintGridding(QPainter *p) 132{ 133 QColor clr(0,255,100); 134 p->setPen(clr); 135 for(int i = m_pLeftTop.x(); i <= m_pRight.x() ; i += m_iUnitage) 136 { 137 p->drawLine(i,m_pLeftTop.y(),i,m_pRight.y()); 138 } 139 for(int i = m_pLeftTop.y(); i <= m_pRight.y() ; i += m_iUnitage) 140 { 141 p->drawLine(m_pLeftTop.x() ,i,m_pRight.x(),i); 142 } 143} 144void SnakeLogic::PaintSnake(QPainter *p) 145{ 146 if(!m_lSnakeList) 147 return; 148 QPixmap img("://res/849.bmp"); 149 QList<QPoint>::const_iterator item = m_lSnakeList->begin(); 150 QPoint unit(1,1); 151 while(item != m_lSnakeList->end()) 152 { 153 QPoint beg = GetConvPoint(*item ) + unit ; 154 QRect rect(beg,beg + QPoint(m_iUnitage - 2,m_iUnitage - 2)); 155 p->drawPixmap(rect,img); 156 item++; 157 } 158} 159void SnakeLogic::PaintFood(QPainter *p) 160{ 161 162 QPixmap img("://res/small.bmp"); 163 QPoint unit(1,1); 164 for(int i = 0; i < m_iFoodNum; i++) 165 { 166 QPoint beg = GetConvPoint(m_pFoodArr[i]) + unit ; 167 QRect rect(beg,beg + QPoint(m_iUnitage - 2,m_iUnitage - 2)); 168 p->drawPixmap(rect,img); 169 170 } 171} 172void SnakeLogic::CreateFood() //ʳ 173{ 174 int i,j; 175 while(1) 176 { 177 while(1) 178 { 179 i = qrand()%m_iNumX; 180 if(i > 0 && i < m_iNumX ) 181 break; 182 } 183 while(1) 184 { 185 j = qrand()%m_iNumY; 186 if(j > 0 && j < m_iNumY) 187 break; 188 } 189 if(m_icoortable[j][i] == 0) 190 { 191 m_icoortable[j][i] = 2; 192 break; 193 } 194 } 195 QPoint food(i,j); 196 m_pFoodArr[m_iFoodNum++] = food; 197} 198QPoint SnakeLogic::GetConvPoint(QPoint sourcePos) 199{ 200 return sourcePos * m_iUnitage + m_pLeftTop; 201} 202 203void SnakeLogic::Move(QPoint& dir) 204{ 205 if(m_bIsPause || m_bIsGameOver) 206 return; 207 QPoint tmp(0,0); 208 if(dir + m_pCurDir == tmp) 209 { 210 QPoint newDir; 211 if(CheckDirection(newDir)) 212 { 213 m_pCurDir = dir; 214 } 215 else 216 { 217 m_pCurDir = newDir; 218 } 219 m_bListRev = !m_bListRev; 220 } 221 else 222 { 223 m_pCurDir = dir; 224 } 225 Move(); 226 227} 228void SnakeLogic::Move() 229{ 230 if(m_bIsPause || m_bIsGameOver) 231 return; 232 if(!m_lSnakeList || m_lSnakeList->isEmpty()) 233 return; 234 int ch = CheckMove(); 235 if(ch == -1) 236 { 237 this->m_bIsGameOver = true; 238 emit gameOver(); 239 return ; 240 } 241 if(ch == 0) 242 { 243 return; 244 } 245 if(m_bListRev) 246 { 247 m_lSnakeList->pop_front(); 248 QList<QPoint>::const_iterator item = m_lSnakeList->end(); 249 QPoint newPos = *(item - 1) + m_pCurDir; 250 m_lSnakeList->push_back(newPos); 251 } 252 else 253 { 254 m_lSnakeList->pop_back(); 255 QList<QPoint>::const_iterator item = m_lSnakeList->begin(); 256 QPoint newPos = *item + m_pCurDir; 257 m_lSnakeList->push_front(newPos); 258 } 259} 260 261int SnakeLogic::CheckMove() 262{ 263 QPoint nextPos; 264 if(m_bListRev) 265 { 266 QList<QPoint>::const_iterator item = m_lSnakeList->end(); 267 nextPos = *(item - 1) + m_pCurDir; 268 } 269 else 270 { 271 nextPos = *m_lSnakeList->begin() + m_pCurDir; 272 } 273 if(m_lSnakeList->contains(nextPos)) 274 return -1; 275 if(CheckFood(nextPos)) 276 { 277 return 0; 278 } 279 return CheckRect(nextPos)?1:-1; 280} 281bool SnakeLogic::CheckRect(QPoint& pos) 282{ 283 if(pos.x() < 1 || pos.y() < 1 || pos.x() >= m_iNumX -1 || pos.y() >= m_iNumY - 1) 284 return false; 285 if(1 == m_icoortable[pos.y()][pos.x()]) 286 return false; 287 return true; 288} 289bool SnakeLogic::CheckFood(QPoint& pos) 290{ 291 if(m_icoortable[pos.y()][pos.x()] == 2) 292 { 293 if(m_bListRev) 294 { 295 m_lSnakeList->push_back(pos); 296 } 297 else 298 { 299 m_lSnakeList->push_front(pos); 300 } 301 m_iFoodNum--; 302 m_icoortable[pos.y()][pos.x()] = 0; 303 CreateFood(); 304 m_iScore += 10; 305 emit chageScore(m_iScore); 306 emit chageLevel(m_iScore/100); 307 return true; 308 } 309 return false; 310} 311bool SnakeLogic::CheckDirection(QPoint& redir) 312{ 313 QPoint tmpDir; 314 if(m_bListRev) 315 { 316 //ͷ 317 QList<QPoint>::const_iterator item = m_lSnakeList->begin(); 318 tmpDir = *(item + 1) - *item; 319 } 320 else 321 { 322 //β 323 QList<QPoint>::const_iterator item = m_lSnakeList->end(); 324 tmpDir = *(item - 2) - *(item - 1); 325 } 326 if(tmpDir != m_pCurDir) 327 { 328 tmpDir.setX(-tmpDir.x()); 329 tmpDir.setY(-tmpDir.y()); 330 redir = tmpDir; 331 return false; 332 } 333 return true; 334} 335 336// slots: 337//void SnakeLogic::start() 338 339 340void SnakeLogic::pause() 341{ 342 this->m_bIsPause = !m_bIsPause; 343}