①实现贪吃蛇游戏基本功能,屏幕上随机出现一个"食物”,称为豆子。上下左右控制"蛇"的移动,吃到“豆子"以后"蛇"的身体加长一点。
②“蛇"碰到边界或蛇头与蛇身相撞,蛇死亡,游戏结束。
③为游戏设计友好的交互界面; 例如欢迎界面,游戏界面,游戏结束界面。
要有开始键、暂停键和停止退出的选项。
④对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。
1.绘制游戏界面。
2.绘制移动的贪吃蛇。
3.随机绘制食物并且位置不与当前蛇身体重合且不超出游戏界面。
4.键盘按键控制蛇的前进方向。
5.文件读写,存入和读取最高分。
新豆子的生成规则为:
①不能超出游戏区域
②不能在蛇身上
游戏结束时的检测规则为:
①蛇是否超出游戏区域
②蛇头是否撞到自己身上
头文件:
widget.h
#ifndef WIDGET_H #define WIDGET_H #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include static const int RETCODE_RESTART = 773; QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); public: void Init(); //初始化函数界面 public: QTimer *m_Timer; bool time_flag=false; int base_time=0,time_s=0; //10ms的基础时间 bool flag_times=false; private slots: void dida_time(); void start_time(); void stop_time(); void restart_time(); public: int x,y,base; int save[625][2]={{2,0},{1,0},{0,0}}; int length=3; int mark=0; int now_head_x,now_head_y; int head_x=2,head_y=0; int food_x=6,food_y=6; bool food_flag=true; char head_direction=4; // ^1 v2 <3 >4 bool head_eat=false; bool move_flag=false; void reboot(); protected: void paintEvent(QPaintEvent *); //绘制 protected: void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); private: Ui::Widget *ui; }; #endif // WIDGET_H
源文件:
main.cpp
#include "widget.h" #includeint main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->Init(); //初始化界面函数
}
Widget::~Widget()
{
delete ui;
}
void Widget::Init()//初始化函数
{
ui->lcd_mark->display(0);
//关联按键和信号函数
connect(ui->btn_start,SIGNAL(clicked()),this,SLOT(start_time()));
connect(ui->btn_stop,SIGNAL(clicked()),this,SLOT(stop_time()));
connect(ui->btn_restart,SIGNAL(clicked()),this,SLOT(restart_time()));
}
void Widget::start_time() //开启定时器
{
m_Timer = new QTimer(this);
m_Timer->start(100);//设定溢出时间100ms
connect(m_Timer,SIGNAL(timeout()),this,SLOT(dida_time()));//溢出后自动调用dida_time
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
// qDebug("OK!");
time_flag=true;
}
void Widget::stop_time() //断开连接信号,即无法自动调用dida_time
{
if(time_flag==true)
{ disconnect(m_Timer,SIGNAL(timeout()),this,SLOT(dida_time())); time_flag=false; }
}
void Widget::restart_time() //调用重启函数
{
reboot();
}
void Widget::dida_time() //每100ms调用一次
{
base_time++;
time_s=base_time/10;
// if(base_time%10==1) //1s时间到
{
if(head_x==food_x && head_y==food_y)
{
head_eat=true;
mark++;
length++;
ui->lcd_mark->display(mark);
}
if(head_eat==false) //旧食物
{
}
else //新生成食物
{
food_x=qrand()%25; //在25x25的格子内生成食物
food_y=qrand()%25;
for(int i=1;i
}
for(int i=1;i24 || head_y>24 ||head_x<0 || head_y<0)//是否为撞墙死亡
{
disconnect(m_Timer,SIGNAL(timeout()),this,SLOT(dida_time()));
QMessageBox message(QMessageBox::NoIcon, "挑战失败", "the game is over!");
message.exec();
reboot();
}
}
// qDebug("direcrtion:%d head_x:%d head_y:%d",head_direction,head_x,head_y);
for(int i=1;ikey())
{
case Qt::Key_W:
qDebug("I get up!"); if(head_direction!=2) head_direction=1; break;
case Qt::Key_S:
qDebug("I get down!"); if(head_direction!=1) head_direction=2; break;
case Qt::Key_A:
qDebug("I get left!"); if(head_direction!=4) head_direction=3; break;
case Qt::Key_D:
qDebug("I get right!");if(head_direction!=3) head_direction=4; break;
case Qt::Key_Space:
qDebug("I get Space!"); break;
default: QWidget::keyPressEvent(event); break;
}
update();
}
void Widget::keyReleaseEvent(QKeyEvent *) // 按键释放事件
{
// 其他操作
}
void Widget::reboot()//重启软件函数
{
QString program = QApplication::applicationFilePath();
QStringList arguments = QApplication::arguments();
QString workingDirectory = QDir::currentPath();
QProcess::startDetached(program, arguments, workingDirectory);
QApplication::exit();
exit(0);
}
成果展示
目前只能实现简单的游戏功能,对于重新开始、速度、退出游戏、音乐及界面美化等功能会稍后更新。



