目录
一.实验内容:
二.贪吃蛇的代码实现
(1)类的声明
(2)初始化界面
(3)游戏界面
(4)蛇的位置
(5)键盘监听
(6)更新蛇的位置
(7)产生食物
(8)是否吃到食物
(9)是否撞到自己
(10)游戏是否胜利
(11)游戏开始与暂停
(12)音乐设置
三 游戏测试
开始游戏
蛇穿墙移动
游戏结束
四.打包发布
一.实验内容:
1)实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子。玩家能利用上下左右键控制“蛇”的移动,“蛇”吃到“豆子”后“蛇”身体加长一节,得分增加,“蛇”碰到边界或蛇头与蛇身相撞,“蛇”死亡,游戏结束。
2)进行交互界面的设计,要有开始键、暂停键和停止退出的选项,能够控制游戏进程。对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。
3)实验设备QT5.9
二.贪吃蛇的代码实现
(1)类的声明
class Snake : public QMainWindow
{Q_OBJECTpublic:Snake(QWidget *parent = nullptr);~Snake();//游戏界面void paintEvent(QPaintEvent *event);//初始化蛇void InitSnake();QRect CreateFood();//产生食物void IsEat();//判断是否吃到了食物void IsHit();//判断是否撞到了自己void IsWin();//判断是否赢得了游戏private slots://定义槽函数的方式//蛇的移动void Snake_update();void on_pushButton_3_clicked();void on_pushButton_5_clicked();void on_pushButton_2_clicked();void on_pushButton_4_clicked();private:Ui::Snake *ui;QTimer *timer;//计时器事件,只要设置了这个,每隔一段时间会去执行指定的东西int nDirection;//蛇的移动方向bool blsRun;//用于控制是否开始的变量bool blsOver;//用于控制是否结束的变量void keyPressEvent(QKeyEvent *key);//键盘事件QVector<QRect> vSnakeRect; //n个小方块组成的vector,代表蛇QRect SnakeHead;//蛇头QString Display;//显示的内容QRect Food;//用来表示食物的变量int Score;//得分int Speed;//蛇的移动速度
};
#endif // SNAKE_H
(2)初始化界面
ui->setupUi(this);setFixedSize(600,480);//设置图标setWindowIcon(QIcon(":/image/1.jpg"));//设置标题setWindowTitle("贪吃蛇大逃亡");
(3)游戏界面
//实现游戏界面,所有在游戏界面中显示的都要在这个函数中实现,在第一次启动程序和调用update的时候会被执行
void Snake::paintEvent(QPaintEvent *event){ //所有的绘图都要在paintEvent函数里面进行QPainter painter(this);if(!blsRun)//只在第一次运行的时候初始化蛇InitSnake(); //在游戏界面中出现蛇//画游戏的背景,这里先设置墙体painter.setPen(Qt::black);//上边框用黑色的画笔去画painter.setBrush(Qt::yellow);//设置填充的颜色为黄色painter.drawRect(0,0,600,70);painter.setPen(Qt::black);painter.setBrush(Qt::blue);painter.drawRect(0,70,600,410);//绘制矩形,换算四个边界的坐标painter.drawPixmap(20,0,200,70,QPixmap(":/image/3 (1).png"));//画格子,用循环实现painter.setPen(Qt::gray);for(int ii = 7;ii <= 48;ii++){painter.drawLine(0,ii*10,600,ii*10);}for(int ii = 0;ii <= 60;ii++){painter.drawLine(ii*10,70,ii*10,600);}//显示游戏开始和结束QFont font1("Courier",50);painter.setFont(font1);painter.setPen(Qt::white);painter.setBrush(Qt::black);painter.drawText(200,150,Display); //将display的内容显示在140,150的位置上//显示分数QFont font2("Courier",15);painter.setFont(font2);painter.setPen(Qt::black);painter.setBrush(Qt::black);painter.drawText(20,65,"得分:");painter.drawText(70,65,QString::number(Score));//把score转换成字符串并显示出来//游戏停止,通过让计时器停止来结束if(blsOver)timer->stop();//画蛇painter.setPen(Qt::black);//设置蛇的边界颜色painter.setBrush(Qt::green);//设置蛇的颜色painter.drawRects(&vSnakeRect[0],vSnakeRect.size());//把整个蛇画出来//在界面中画出食物painter.drawPixmap(Food,QPixmap(":/image/3 (2).png"));}
(4)蛇的位置
//说明代表蛇应该画在什么地方
void Snake::InitSnake(){blsRun=true;blsOver=false;nDirection=2;//默认刚开始蛇的移动方向是向下Food=CreateFood();//在游戏开始的时候产生食物Score=0;//矩形框vSnakeRect.resize(5);//蛇的长度//用for循环实现蛇的移动坐标for(int i=0;i<vSnakeRect.size();i++){QRect rect(30,70+10*i,10,10);vSnakeRect[vSnakeRect.size()-1-i]=rect;}timer=new QTimer(this);//设定计时器timer->start(Speed);//设定计时器的间隔时间为500mstimer->stop();connect(timer,SIGNAL(timeout()),SLOT(Snake_update()));//SIGNAL:信号 SLOT:槽,对信号和槽的连接
}
(5)键盘监听
//键盘事件
void Snake::keyPressEvent(QKeyEvent *event){QKeyEvent *key=(QKeyEvent*) event;//用switch语句判断键盘输入的是哪个按键switch (key->key()) {case Qt::Key_W://如果按的是上键,规定蛇的移动方向记为1,也就是说1对应向上,且向上的时候不能向下if(nDirection!=2){nDirection=1;}break;//下面三个方向同理case Qt::Key_S:if(nDirection!=1){nDirection=2;}break;case Qt::Key_A:if(nDirection!=4){nDirection=3;}break;case Qt::Key_D:if(nDirection!=3){nDirection=4;}break;default:;//}
}
(6)更新蛇的位置
//更新蛇
void Snake::Snake_update(){Display="";SnakeHead=vSnakeRect.first();//获取蛇头,让蛇头等于vector中的第一个元素IsEat();//判断是否吃到食物IsHit();//判断是否撞到自己IsWin();//判断是否赢了//非蛇头的蛇身的移动for(int j=0;j<vSnakeRect.size()-1;j++){vSnakeRect[vSnakeRect.size()-1-j]=vSnakeRect[vSnakeRect.size()-2-j];}//根据蛇头的朝向来更新蛇的位置switch (nDirection) {case 1:SnakeHead.setTop(SnakeHead.top()-10);//如果是往上移动,让蛇的上面的坐标减10SnakeHead.setBottom(SnakeHead.bottom()-10);//同时蛇的底部也向上移动10break;case 2:SnakeHead.setTop(SnakeHead.top()+10);SnakeHead.setBottom(SnakeHead.bottom()+10);break;case 3:SnakeHead.setLeft(SnakeHead.left()-10);SnakeHead.setRight(SnakeHead.right()-10);break;case 4:SnakeHead.setLeft(SnakeHead.left()+10);SnakeHead.setRight(SnakeHead.right()+10);break;default:; //默认情况下就什么都不做}vSnakeRect[0]=SnakeHead;//如果蛇头离开了墙壁的范围,即蛇头撞墙,则游戏结束//穿墙更新蛇头位置if(SnakeHead.left()<0){QRect rect(590,SnakeHead.top(),10,10);vSnakeRect[0]=rect;}if(SnakeHead.right()>600){QRect rect(0,SnakeHead.top(),10,10);vSnakeRect[0]=rect;}if(SnakeHead.top()<70){QRect rect(SnakeHead.left(),470,10,10);vSnakeRect[0]=rect;}if(SnakeHead.bottom()>480){QRect rect(SnakeHead.left(),70,10,10);vSnakeRect[0]=rect;}update();//刷屏,更新print
(7)产生食物
//产生食物
QRect Snake::CreateFood(){int x,y;//随机产生食物,使用到随机函数//x和y是0到25之间的随机的整数x=qrand()%25;y=qrand()%25;QRect rect(10+x*10,80+y*10,10,10);return rect;
}
(8)是否吃到食物
//产生食物
QRect Snake::CreateFood(){int x,y;//随机产生食物,使用到随机函数//x和y是0到25之间的随机的整数x=qrand()%25;y=qrand()%25;QRect rect(10+x*10,80+y*10,10,10);return rect;
}
(9)是否撞到自己
//判断是否撞到自己
void Snake::IsHit(){//用for循环遍历蛇身,0是蛇头,因此从1开始for(int i=1;i<vSnakeRect.size();i++){//如果撞上了if(SnakeHead==vSnakeRect[i]){SnakeHead==vSnakeRect[i-1];Display="游戏结束";blsOver=true;QMessageBox::StandardButton box;box = QMessageBox::question(this, "提示", "游戏结束,是否重开?", QMessageBox::Yes|QMessageBox::No);if(box==QMessageBox::No)timer->stop();//return;if(box==QMessageBox::Yes){InitSnake();Snake_update();timer->start();}}}
}
(10)游戏是否胜利
//判断是否游戏胜利
void Snake::IsWin(){if(Score==500){Display="恭喜你赢了";blsOver=true;update();}
}
(11)游戏开始与暂停
void Snake::on_pushButton_3_clicked()//暂停游戏
{timer->stop();}
void Snake::on_pushButton_4_clicked()//继续游戏
{timer->start();}
(12)音乐设置
void Snake::on_pushButton_2_clicked()//打开音乐设置
{QSound *startSound = new QSound(":/image/武汉麻将-背景音乐 - 小旭音乐.wav",this);startSound->play();startSound->setLoops(100);
}
三 游戏测试
开始游戏
蛇穿墙移动
游戏结束
四.打包发布