基本信息
源码名称:QT 贪吃蛇 小游戏源码
源码大小:12.42M
文件格式:.rar
开发语言:C/C++
更新时间:2019-03-28
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
请注意 程序下载后 改个目录名,程序所在目录不能有汉字)
请注意 程序下载后 改个目录名,程序所在目录不能有汉字)
#include "mywidget.h" #include "ui_mywidget.h" #include <QPainter> #include <Qpen> #include <QBrush> #include <QDebug> #include <QKeyEvent>//键盘事件 #include <QMediaPlayer> #include <QString> //全局宏定义 #define Bsize 20//格子的尺寸(像素) #define startX 50//地图起始x坐标 #define startY 75//地图起始y坐标 #define Cwidth 500//地图宽500px #define Cheight 420//地图高420px #define W 25//宽25格 #define H 21//高21格 #define appleW 19//苹果宽19px #define appleH 22//苹果高22px #define snakeLen 4//初始蛇长度 #define snakeSpeed 1//蛇速,待定 #define s_up 1 #define s_down 2 #define s_left 3 #define s_right 4//枚举类不知道怎么用,暂时用1、2、3、4代表上下左右,初始向右吧 //全局变量声明 int appleX, appleY;//苹果格子坐标 int posAppleX, posAppleY;//苹果像素坐标 int headX, headY;//蛇头坐标 int score = 0; QString strScore; bool isEated = false;//是否吃到了? bool crashed = false;//是否撞墙或者撞到自己 bool gamePause = false;//游戏是否暂停 bool bg = true; bool bgm = true; bool gameStart = false;//需要点击开始才可以玩耍 char op = 'o';//获取操作指令 int Smap[W][H];//地图尺寸,值为信息标记 int direction = s_right; int Sround = 1;//第一关 int gameStartClickCount = 0; QMediaPlayer *player = new QMediaPlayer; QMediaPlayer *player_gg = new QMediaPlayer; QMediaPlayer *player_eat = new QMediaPlayer; //这里写全局函数声明 void init(); void createApple(); void goUp(); void goDown(); void goLeft(); void goRight(); void autoRun(); void setRound();//设置关卡 void snakeInit();//初始化蛇身 //类不会用,用结构体实现 struct Point { int xvar; int yvar; public: Point() {} ~Point() {} Point(int x, int y) :xvar(x), yvar(y) {} int x()const { return xvar; } int y()const { return yvar; } }; struct Snake {//蛇类 int length = snakeLen; int speed = snakeSpeed; int direction = s_right; public: Snake() {} ~Snake() {} int len()const { return length; } int sp()const { return speed; } int Direction() const {return direction; } //std::vector<Point> snakeBody{ Point(3,3),Point(3,4),Point(3,5),Point(3,6) };//蛇身 std::vector<Point> snakeBody;//蛇身 }; Snake s; myWidget::myWidget(QWidget *parent) : QWidget(parent), ui(new Ui::myWidget) { ui->setupUi(this); setWindowTitle("贪吃蛇小游戏"); setWindowIcon(QIcon("../image/apple1.png"));//设置窗口图标 init(); qDebug() << s.snakeBody.size(); timerId = this->startTimer(500);//毫秒为单位,一个叫做timerId的定时器 connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player->setMedia(QUrl::fromLocalFile("../image/bgm2.mp3"));//游戏背景音乐 player->setVolume(30); player->play(); connect(player_gg, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player_gg->setMedia(QUrl::fromLocalFile("../image/gg.mp3"));//GameOver的声音 player_gg->setVolume(80); connect(player_eat, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player_eat->setMedia(QUrl::fromLocalFile("../image/eated.mp3"));//吃到东西的声音 player_eat->setVolume(80); } myWidget::~myWidget() { delete ui; } void myWidget::timerEvent(QTimerEvent *e){//定时器 if(e->timerId() == timerId && gamePause){ if(direction == s_right){ goRight(); }else if(direction == s_up){ goUp(); }else if(direction == s_down){ goDown(); }else if(direction == s_left){ goLeft(); } //qDebug()<<score; if(isEated){ strScore = QString::number(score); ui->label->setText(strScore); } update(); if(crashed){ player->stop(); player_gg->play(); Sleep(1000); //MessageBox(0, TEXT("不要灰心!继续游戏??"), TEXT("Sorry,defeat!!"), 0);//游戏结束时 gamePause = !gamePause; init(); strScore = QString::number(score); ui->label->setText(strScore); } } } void myWidget::keyPressEvent(QKeyEvent *e){//键盘事件监听 // qDebug()<<(char)e->key(); if(gameStart){//游戏开始时才可以手动 if(e->key() == Qt::Key_W){ if(direction == s_down) return;//不做处理 direction = s_up; //if(e->isAutoRepeat())//重复按下再快跑会有迟钝效果。。 goUp(); if(isEated) createApple();//随机产生苹果位置 }else if(e->key() == Qt::Key_S){ if(direction == s_up) return;//不做处理 direction = s_down; goDown(); if(isEated) createApple();//随机产生苹果位置 }else if(e->key() == Qt::Key_A){ if(direction == s_right) return;//不做处理 direction = s_left; goLeft(); if(isEated) createApple();//随机产生苹果位置 }else if(e->key() == Qt::Key_D){ if(direction == s_left) return;//不做处理 direction = s_right; goRight(); if(isEated) createApple();//随机产生苹果位置 } strScore = QString::number(score); ui->label->setText(strScore); update(); } } void myWidget::paintEvent(QPaintEvent *) { //QPainter p(this); QPainter p;//创建画家对象 p.begin(this);//指定当前窗口为绘图设备 //绘图操作 //p.drawPixmap(0,0,width(),height(),QPixmap("../image/bg.jpg"));//背景图 if(bg) p.drawPixmap(rect(),QPixmap("../image/bg.jpg"));//背景图 else{ p.drawPixmap(rect(),QPixmap("../image/bg.png"));//背景图 } //定义画笔 QPen pen; pen.setWidth(6); pen.setColor(RGB(60,60,60)); p.setPen(pen);//把画笔交给画家 // p.drawRect(startX,startY,Cwidth,Cheight);//画出游戏边界 for(int i=-1;i<=W;i ){//画出游戏边界 p.drawPixmap(i*Bsize startX,-1*Bsize startY,Bsize,Bsize,QPixmap("../image/shitou.png")); p.drawPixmap(i*Bsize startX,21*Bsize startY,Bsize,Bsize,QPixmap("../image/shitou.png")); } for(int j=0;j<H;j ){//画出游戏边界 p.drawPixmap(-1*Bsize startX,j*Bsize startY,Bsize,Bsize,QPixmap("../image/shitou.png")); p.drawPixmap(25*Bsize startX,j*Bsize startY,Bsize,Bsize,QPixmap("../image/shitou.png")); } if(Sround == 1){//画出第一关障碍物 for(int i=4;i<=8;i ){ p.drawPixmap(6*Bsize startX,i*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); p.drawPixmap(18*Bsize startX,i*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); } for(int i=11;i<=15;i ){ p.drawPixmap(6*Bsize startX,i*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); p.drawPixmap(18*Bsize startX,i*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); } for(int i=7;i<=10;i ){ p.drawPixmap(i*Bsize startX,4*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); p.drawPixmap(i*Bsize startX,15*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); } for(int i=14;i<=17;i ){ p.drawPixmap(i*Bsize startX,4*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); p.drawPixmap(i*Bsize startX,15*Bsize startY,Bsize,Bsize,QPixmap("../image/wall.png")); } } /*pen.setWidth(1);//重新设置画笔宽度 p.setPen(pen);//把画笔交给画家 for(int i=startX,j=startY;j<startY Cheight;j =Bsize){//画格子辅助线 p.drawLine(i,j,i Cwidth,j); } for(int i=startX,j=startY;i<startX Cwidth;i =Bsize){ p.drawLine(i,j,i,j Cheight); }*/ strScore = QString::number(score);//刷新分数 ui->label->setText(strScore); if(appleX%2==0)//画苹果 p.drawPixmap(posAppleX,posAppleY-2,appleW,appleH,QPixmap("../image/apple1.png")); else//画月饼 p.drawPixmap(posAppleX,posAppleY,Bsize,Bsize,QPixmap("../image/shead.png")); if(isEated){ createApple();//随机产生苹果位置 update(); } for(std::vector<Point>::iterator it=s.snakeBody.begin();it!=s.snakeBody.end();it ){//遍历蛇身,画蛇 Smap[(*it).x()][(*it).y()] = 1; if(it == s.snakeBody.end()-1){//vector数组尾作为蛇头,红点 headX = (*it).x();//蛇头坐标 headY = (*it).y();//蛇头坐标 int posHeadX = headX*Bsize startX;//蛇头像素位置 int posHeadY = headY*Bsize startY;//蛇头像素位置 if(direction == s_up){ p.drawPixmap(posHeadX-10,posHeadY-15,2*Bsize,2*Bsize,QPixmap("../image/shead_up.png")); }else if(direction == s_down){ p.drawPixmap(posHeadX-10,posHeadY-5,2*Bsize,2*Bsize,QPixmap("../image/shead_down.png")); }else if(direction == s_left){ p.drawPixmap(posHeadX-15,posHeadY-10,2*Bsize,2*Bsize,QPixmap("../image/shead_left.png")); }else if(direction == s_right){ p.drawPixmap(posHeadX-5,posHeadY-10,2*Bsize,2*Bsize,QPixmap("../image/shead_right.png")); } }else{//蛇身黑点 int xx=(*it).x()*Bsize startX; int yy=(*it).y()*Bsize startY; p.drawPixmap(xx,yy,Bsize,Bsize,QPixmap("../image/snake1.png")); } if (headX == appleX && headY == appleY){//吃到了! isEated = true; } } p.end(); } void init() {//每次游戏开始的数据初始化 for (int i = 0; i < W; i ) for (int j = 0; j < H; j ) Smap[i][j] = 0; s.snakeBody.clear(); direction = s_right; crashed = false; gameStart = false; score = 0; gameStartClickCount = 0; snakeInit();//初始化蛇身 setRound();//设置第几关 createApple();//随机产生苹果位置 } void createApple() {//随机产生苹果位置 if (isEated){ player_eat->play();//吃到音效 score = 10; } while (true) { srand((int)time(NULL)); int row = rand() % 21;//产生0~24的随机数 int col = rand() % 25; if (Smap[col][row] == 0) { //Smap[row][col] = 1; appleX = col; appleY = row; posAppleX = appleX*Bsize startX;//像素位置与坐标转换 posAppleY = appleY*Bsize startY; break; } } isEated = false;//刚产生的苹果吃不到! } void goUp() { //五种情况①撞墙;②撞苹果;③撞自己;④都不撞;⑤撞障碍物 direction = s_up; if (!((headX == appleX) && (headY - 1 == appleY)) && (headY - 1 >= 0) && (Smap[headX][headY - 1] == 0)) {//都不撞(头插一点,尾删一点) s.snakeBody.push_back(Point(headX, headY - 1));//头插一点 //Smap[headX][headY - 1] = 1; std::vector<Point>::iterator it = s.snakeBody.begin();//找到第一个点(尾部) Smap[(*it).x()][(*it).y()] = 0; s.snakeBody.erase(it);//尾删一点 } else if ((headX == appleX) && (headY - 1 == appleY)) {//撞苹果,吃到(头插一点,尾不删) s.snakeBody.push_back(Point(headX, headY - 1));//头插一点 //Smap[headX][headY - 1] = 1; isEated = true; }else if(Smap[headX][headY - 1]==1){ crashed = true; return; } else if (headY - 1 < 0) {//不是撞苹果->撞墙:GameOver crashed = true; return; } else{//撞自己 crashed = true; return; } } void goDown() { //五种情况①撞墙;②撞苹果;③撞自己;④都不撞 direction = s_down; if (!((headX == appleX) && (headY 1 == appleY)) && (headY 1 < H) && (Smap[headX][headY 1] == 0)) {//都不撞(头插一点,尾删一点) s.snakeBody.push_back(Point(headX, headY 1));//头插一点 //Smap[headX][headY 1] = 1; std::vector<Point>::iterator it = s.snakeBody.begin();//找到第一个点(尾部) Smap[(*it).x()][(*it).y()] = 0; s.snakeBody.erase(it);//尾删一点 } else if ((headX == appleX) && (headY 1 == appleY)) {//撞苹果,吃到(头插一点,尾不删) s.snakeBody.push_back(Point(headX, headY 1));//头插一点 //Smap[headX][headY 1] = 1; isEated = true; } else if(Smap[headX][headY - 1]==1){ crashed = true; return; } else if (headY 1 >= H) {//撞墙:GameOver crashed = true; return; } else{//撞自己 crashed = true; return; } } void goLeft() { //五种情况①撞墙;②撞苹果;③撞自己;④都不撞; ⑤撞障碍物 direction = s_left; if (!((headX - 1 == appleX) && (headY == appleY)) && (headX - 1 >= 0) && (Smap[headX - 1][headY] == 0)) {//都不撞(头插一点,尾删一点) s.snakeBody.push_back(Point(headX - 1, headY));//头插一点 //Smap[headX - 1][headY] = 1; std::vector<Point>::iterator it = s.snakeBody.begin();//找到第一个点(尾部) Smap[(*it).x()][(*it).y()] = 0; s.snakeBody.erase(it);//尾删一点 } else if ((headX - 1 == appleX) && (headY == appleY)) {//撞苹果,吃到(头插一点,尾不删) s.snakeBody.push_back(Point(headX - 1, headY));//头插一点 //Smap[headX - 1][headY] = 1; isEated = true; } else if(Smap[headX - 1][headY]==1){ crashed = true; return; } else if (headX - 1 < 0) {//撞墙:GameOver crashed = true; return; } else{//撞自己 crashed = true; return; } } void goRight() { //五种情况①撞墙;②撞苹果;③撞自己;④都不撞; ⑤撞障碍物 direction = s_right; if (!((headX 1 == appleX) && (headY == appleY)) && (headX 1 < W) && (Smap[headX 1][headY] == 0)) {//都不撞(头插一点,尾删一点) s.snakeBody.push_back(Point(headX 1, headY));//头插一点 //Smap[headX 1][headY] = 1; std::vector<Point>::iterator it = s.snakeBody.begin();//找到第一个点(尾部) Smap[(*it).x()][(*it).y()] = 0; s.snakeBody.erase(it);//尾删一点 } else if ((headX 1 == appleX) && (headY == appleY)) {//撞苹果,吃到(头插一点,尾不删) s.snakeBody.push_back(Point(headX 1, headY));//头插一点 //Smap[headX 1][headY] = 1; isEated = true; } else if(Smap[headX][headY - 1]==1){ crashed = true; return; } else if (headX 1 >= W) {//撞墙:GameOver crashed = true; return; } else{//撞自己 crashed = true; return; } } //槽函数 void myWidget::on_pushButton_clicked() { gameStart = true; player->play(); gameStartClickCount ; if(gameStartClickCount<2)//每次游戏开始按钮只有第一次生效,避免和暂停按钮发生冲突 gamePause = true; update(); } void myWidget::on_pushButton_2_clicked() { if(gameStartClickCount){//大于1生效,避免和开始按钮发生冲突 gamePause = !gamePause;//取反实现toggle开关 if(gamePause){ ui->pushButton_2->setText("暂停"); }else{ ui->pushButton_2->setText("继续"); } update(); } } void snakeInit(){ s.snakeBody.push_back(Point(3,2)); s.snakeBody.push_back(Point(4,2)); s.snakeBody.push_back(Point(5,2)); s.snakeBody.push_back(Point(6,2));//初始化蛇身从左上角出发 Smap[3][2] = 1,Smap[4][2] = 1,Smap[5][2] = 1,Smap[6][2] = 1; } void setRound(){//设置关卡 if(score>=500){//满500分进入下一关 Sround ; //message:恭喜进入下一关 } if(Sround == 1){ Smap[6][4]=Smap[6][5]=Smap[6][6]=Smap[6][7]=Smap[6][8]=1; Smap[6][11]=Smap[6][12]=Smap[6][13]=Smap[6][14]=Smap[6][15]=1; Smap[18][4]=Smap[18][5]=Smap[18][6]=Smap[18][7]=Smap[18][8]=1; Smap[18][11]=Smap[18][12]=Smap[18][13]=Smap[18][14]=Smap[18][15]=1; Smap[7][4]=Smap[8][4]=Smap[9][4]=Smap[10][4]=1; Smap[14][4]=Smap[15][4]=Smap[16][4]=Smap[17][4]=1; Smap[7][15]=Smap[8][15]=Smap[9][15]=Smap[10][15]=1; Smap[14][15]=Smap[15][15]=Smap[16][15]=Smap[17][15]=1; }else if(Sround == 2){ //第二关待定 } } void myWidget::on_pushButton_4_clicked() { bg=!bg;//背景切换 update(); } void myWidget::on_pushButton_5_clicked() { if(bgm){ player->stop(); }else{ player->play(); } bgm = !bgm; }