一、实验环境
QT
语言:C++
二、实验目的
1)实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子。玩家能利用上下左右键控制“蛇”的移动,“蛇”吃到“豆子”后“蛇”身体加长一节,得分增加,“蛇”碰到边界或蛇头与蛇身相撞,“蛇”死亡,游戏结束。
2)进行交互界面的设计,要有开始键、暂停键和停止退出的选项,能够控制游戏进程。对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。
三、代码实现
首先,游戏实现的最基本的条件是能用键盘操控蛇的移动。这就需要使用keyEvent的头函数。有一点要注意的是,当蛇向上(下)或左(右)移动的时候,蛇不能向下(上)或右(左)移动。这里只要一个if条件句判断即可。
void Widget::keyPressEvent(QKeyEvent *event) {
switch(event->key()) {
case Qt::Key_Up:
if(moveFlag != DIR_DOWN){
moveFlag = DIR_UP;
}
break;
case Qt::Key_Down:
if (moveFlag != DIR_UP) {
moveFlag = DIR_DOWN;
}
break;
case Qt::Key_Right:
if (moveFlag != DIR_LEFT) {
moveFlag = DIR_RIGHT;
}
break;
case Qt::Key_Left:
if (moveFlag != DIR_RIGHT) {
moveFlag = DIR_LEFT;
}
break;
case Qt::Key_Space:
if (gameStart == false) {
gameStart = true;
timer->start(time);
} else {
gameStart = false;
timer->stop();
}
break;
default:
break;
}
}
接下来的移动速度只要一个计时器来操控。
蛇身可以用QPainter画出。蛇的移动可以想象成方块的增加和删减。比如,蛇向上移动的时候,蛇身堆栈顶部添加一个方块,蛇的尾部删除一个方块。
pen.setColor(QColorConstants::Svg::lightblue);
brush.setColor(QColorConstants::Svg::blue);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
for(int i=0; i<snake.length(); i++) {
painter.drawRect(snake[i]);
}
食物的生成操作和蛇身一样。
当蛇头碰到食物的时候,判断为吃到食物,蛇身加一。其中要注意的是蛇原本移动的方向,蛇身要加在原方向上。这就要再写四个函数。以向上为例。
void Widget::addTop() {
QPointF leftTop;
QPointF rightBotom;
if (snake[0].y() - nodeHeight < 0) {
leftTop = QPoint(snake[0].x(), this->height() - nodeHeight);
rightBotom = QPointF(snake[0].x() + nodeWidth, this->height());
} else {
leftTop = QPointF(snake[0].x(), snake[0].y()-nodeHeight);
rightBotom = snake[0].topRight();
}
snake.insert(0, QRectF(leftTop, rightBotom));
c++;
}
还有游戏结束的判断。游戏结束有两种可能:一是蛇头碰到蛇身,二是蛇头撞向边界。其中第二个我已将蛇设置为可以穿过边界。具体操作就是当蛇碰到边界的时候在同等高度(宽度)生成蛇头。
接下来蛇头碰到蛇身的判断就只需要从堆栈入手。写一个判断循环即可。
bool Widget::checkContact() {
for (int i=0; i<snake.length(); i++)
for (int j=i+1; j<snake.length(); j++) {
if(snake[i] == snake[j]) {
return true;
}
}
再使用QPainter画出失败界面,计时器停止,游戏就结束了。