QT贪吃蛇
由于课程需要,写一个贪吃蛇。我跟着老师的步伐,一步一步写。
界面做的很丑,基本是拖几个label,窗口也没怎么修饰,只是简单的实现了小蛇吃蛋变大,得分,以及计时的功能。
蛇和蛋以及蛇的运动和吃蛋,都是在"meadow.h"
这个类里面实现
代码里面,将界面全部用小方块填充,然后隐藏。一切操作都是在label上操作,小蛇也是用label显示,蛋也是用label显示,只是小蛇用了5个label显示最初的模样,而蛋只用一个label。
M,N是一个常量,表示我们活动区域需要的长和宽
#define M 35
#define N 24
void Meadow::initGame(){
int s = 36;
for(int x = 0; x < M; x++){
for(int y = 0; y < N; y++){
QLabel *label = new QLabel(this);
int x0 = x * s;
int y0 = y * s;
label->setGeometry(x0, y0, s - 2, s - 2);
label->setStyleSheet("background:#e88; border-radius:8px;");
label->hide();
labels[x][y] = label;
}
}
}
接下来是画边框,我们要规定一个边框,蛇和蛋只能在这个区域内。
void Meadow::drawBorder(){
for(int x = 0; x < M; x++){
for(int y = 0; y < N; y++){
QLabel *label = labels[x][y];
if(x == 0 || y == 0 || x == M - 1 || y == N - 1)
label->show();
else
lableList.append(QPoint(x,y));
}
}
}
这里蛇的运动我用定时器来解决,定时一段时间,我们将蛇头前面label显示,隐藏蛇尾的label,这样在视觉上可以形成蛇在移动的错觉,其实只是label一个隐藏,一个显示了。
void Meadow::startGame(){
drawBorder();
initSnake();
timer.start(300);
}
void Meadow::moveStep(int dx,int dy){
emit countime();
QPoint oldHead = snake.first();
QPoint newHead = QPoint(oldHead.x() + dx, oldHead.y() + dy);
QPoint tail = snake.last();
//判断蛇是否撞到自己、墙壁
if (snake.contains(newHead)||newHead.x()==0 || newHead.y()==0 || newHead.x()==M - 1 || newHead.y() == N - 1)
{
emit gameover();
timer.stop();
return;
}
if (newHead==egg){
labels[newHead.x()][newHead.y()]->setStyleSheet("background:#e88; border-radius:8px;");
snake.prepend(newHead);
lableList.removeOne(newHead);
generateEgg();
emit SendCount(++count);
}else{
labels[newHead.x()][newHead.y()]->show();
lableList.removeOne(newHead);
labels[tail.x()][tail.y()]->hide();
snake.prepend(newHead);
snake.removeLast();
lableList.append(tail);
}
}
其中labelList这个list里面装的是除了蛇,蛋和墙,其余隐藏的label,而snake这个list就装的是蛇的label了,而label里面这个是所有的label。之所以定义这个多list,完全是为了代码的方便,逻辑清晰。下面随机生成的蛋,也就几行代码,看着就很舒服。之前想过随机生成的蛋有可能落在蛇圣商,或者周围的墙上,如果发生了这样的情况还要重新生成。所以很纠结,还好多定义几个list,这样就方便多了。
void Meadow::generateEgg(){
int n = qrand()%lableList.size();
egg = lableList.takeAt(n);
labels[egg.x()][egg.y()]->setStyleSheet("background:#384; border-radius:8px;");
labels[egg.x()][egg.y()]->show();
}
界面几乎就是原始界面,因为刚学,不会画,之前了解过,Qt有画的类,但是无奈花在Qt上的时间总是很少。所以只能简单的用颜色和方块来表示了。
Qt的弹球游戏、舒码特方格也做过,但是代码之前交完作业也就不见了,只有小蛇的代码刚交完,所以我这里上传一份,作为笔记。
这是全部代码的github链接地址,如果需要参考可以前往下载