贪吃蛇

来源:互联网 发布:手机公司记账软件 编辑:程序博客网 时间:2024/04/24 06:49

第一次在这里写东西

Qt程序,参考了别人博客的贪吃蛇主体算法(抱歉网址不记得了),我又自己写了一份完整的,包括主界面、菜单和背景音乐等。

这是界面截图:


文章末尾有源代码下载地址

说一下主要部分吧:

先画这样一份地图QVector < QVector <int > > map,其值1表示墙壁,0表示空地

举个例子:

111111111111111

100000000000001

100000000000001

100000000000001

111111111111111

再做出一条蛇QVector< <QPoint> > snake和食物QPoint apple;apple的位置用随机函数确定.

然后用timer做定时器,每隔X ms进行更新,在map上画出snake,和apple.

这里可以很好的利用Qt的 信号/槽机制

QObject::connect(timer,SIGNAL(timeout()),this,SLOT(automove()));
timer发出timeout信号时,automove函数实现蛇自动前进,本质是把snake中的数据进行更新,然后调用绘图函数

需要重载两个函数

void paintEvent(QPaintEvent *event);//绘图部分
void keyPressEvent(QKeyEvent *event);//捕获键盘操作,键盘的上下左右控制蛇的前进
keyPressEvent函数根据捕获的按键更新snake数据

mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QtGui>#include<QVector>#include<QLabel>#include<QSound>#include<string>using namespace std;#define WIDTH 30#define HEIGHT 20int  const LEVEL[]={0,1000,500,200,100,50};namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTpublic:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();    enum direction{UP,DOWN,LEFT,RIGHT};private slots:    void automove();    void receiveData(string rec);    void on_action_Quit_triggered();    void on_action_New_triggered();    void on_action_Pause_triggered();    void on_action_Continue_triggered();    void on_action_level1_triggered();    void on_action_level2_triggered();    void on_action_level3_triggered();    void on_action_level4_triggered();    void on_action_level5_triggered();    void on_action_help_triggered();    void on_action_author_triggered();    void on_action_Score_triggered();    void addscore();private:    Ui::MainWindow *ui;    QPoint apple;    QVector<QPoint> snake;    QVector< QVector<int> > map;    enum direction direc;    int speed;    int level;    QTimer *timer;    int score;    void eat();    void move(enum direction direc);    void randapple();    void gameover();    void loadscore();    void getname();    void save();    void init_statuBar();    QLabel *first_statusLabel,*second_statusLabel;    string player;signals:    void gotin();protected:    void paintEvent(QPaintEvent *event);    void keyPressEvent(QKeyEvent *event);};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include"dialog.h"#include"readname.h"#include<QDebug>#include<fstream>#define ON#ifdef ON#define NEW#define PEVENT#define KEVENT#endifstring nam[3]={"player1","player2","player3"};int sco[3]={0};MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow){    ui->setupUi(this);    setWindowTitle(tr("贪吃蛇"));    setFixedSize(25*WIDTH,25*HEIGHT);    //默认方向为RIGHT    direc=RIGHT;   //默认难度为LEVEL1    level=1;    speed=LEVEL[level];    player="UnknowPlayer";    score=0;    //重置蛇的初始位置    snake.clear();    snake.push_back(QPoint(5,4));    snake.push_back(QPoint(5,5));    snake.push_back(QPoint(5,6));    snake.push_back(QPoint(5,7));    //初始化地图,1表示砖块,0表示空地    QVector<int> temp1(WIDTH,1);    map.push_back(temp1);    QVector<int> temp2;    temp2.push_back(1);    for(int i=1;i<=WIDTH-2;i++)        temp2.push_back(0);    temp2.push_back(1);    for(int i=1;i<=HEIGHT-2;i++)        map.push_back(temp2);    map.push_back(temp1);    nam[0].clear();    nam[1].clear();    nam[2].clear();    player.clear();    loadscore();    init_statuBar();    //制作定时器,每x毫秒蛇自动前进    timer=new QTimer(this);    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(automove()));    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));    QObject::connect(this,SIGNAL(gotin()),this,SLOT(addscore()));    //update();}MainWindow::~MainWindow(){    delete ui;}void MainWindow::on_action_Quit_triggered(){    save();    qApp->exit();}#ifndef NEWvoid MainWindow::on_action_New_triggered(){}#elsevoid MainWindow::on_action_New_triggered(){     //默认方向为RIGHT     direc=RIGHT;     score=0;     //重置蛇的初始位置     snake.clear();     snake.push_back(QPoint(5,4));     snake.push_back(QPoint(5,5));     snake.push_back(QPoint(5,6));     snake.push_back(QPoint(5,7));     //初始化地图,1表示砖块,0表示空地     /*      宽度WEIDTH,高度HEIGTH,"举个栗子"吧:        111111111        100000001        100000001        111111111    */     map.clear();     QVector<int> temp1(WIDTH,1);     map.push_back(temp1);     QVector<int> temp2;     temp2.push_back(1);     for(int i=1;i<=WIDTH-2;i++)         temp2.push_back(0);     temp2.push_back(1);     for(int i=1;i<=HEIGHT-2;i++)         map.push_back(temp2);     map.push_back(temp1);     randapple();     this->update();    //启动定时器     timer->start(speed);     QSound sound("sound/darling.wav");     sound.play();     //QSound::play("F:/Code/Qt/snake2/sound/darling.wav");     qDebug()<<"New 运行成功";}#endifvoid MainWindow::randapple(){    apple.setX(qrand()%WIDTH);    apple.setY(qrand()%HEIGHT);    if(map[apple.y()][apple.x()]!=0)        this->randapple();    else if(qFind(snake.begin(),snake.end(),apple)!=snake.end())            this->randapple();    else        qDebug()<<"randapple 运行成功";}void MainWindow::move(direction direc){    QVector<QPoint> temp(snake.size());    switch(direc)    {        case UP:        {        temp[0]=QPoint(snake[0].x(),snake[0].y()-1);        qCopy(snake.begin(),snake.end()-1,temp.begin()+1);        snake=temp;        break;        }        case DOWN:        {        temp[0]=QPoint(snake[0].x(),snake[0].y()+1);        qCopy(snake.begin(),snake.end()-1,temp.begin()+1);        snake=temp;        break;        }        case LEFT:        {        temp[0]=QPoint(snake[0].x()-1,snake[0].y());        qCopy(snake.begin(),snake.end()-1,temp.begin()+1);        snake=temp;        break;        }        case RIGHT:        {        temp[0]=QPoint(snake[0].x()+1,snake[0].y());        qCopy(snake.begin(),snake.end()-1,temp.begin()+1);        snake=temp;        break;        }    }    qDebug()<<"move 运行成功";}void MainWindow::eat(){    //这里需要注意容器的最后一个元素是end()-1,不是end()    //蛇尾朝右前进    if(snake[snake.size()-1].x()==snake[snake.size()-2].x()&&snake[snake.size()-1].y()<snake[snake.size()-2].y())        snake.push_back(QPoint(snake[snake.size()-1].x(),snake[snake.size()-1].y()-1));    //蛇尾朝左前进    if(snake[snake.size()-1].x()==snake[snake.size()-2].x()&&snake[snake.size()-1].y()>snake[snake.size()-2].y())        snake.push_back(QPoint(snake[snake.size()-1].x(),snake[snake.size()-1].y()+1));    //蛇尾朝上前进    if(snake[snake.size()-1].y()==snake[snake.size()-2].y()&&snake[snake.size()-1].x()>snake[snake.size()-2].x())        snake.push_back(QPoint(snake[snake.size()-1].x()+1,snake[snake.size()-1].y()));    //蛇尾朝下前进    if(snake[snake.size()-1].y()==snake[snake.size()-2].x()&&snake[snake.size()-1].x()<snake[snake.size()-2].x())        snake.push_back(QPoint(snake[snake.size()-1].x()-1,snake[snake.size()-1].y()));    //撞墙    if(map[snake[snake.size()-1].y()][snake[snake.size()-1].x()]==1)        snake.pop_back();    score+=level;    emit gotin();    QSound sound("sound/eat.wav");    sound.play();    qDebug()<<"eat 运行成功";}#ifndef PEVENTvoid MainWindow::paintEvent(QPaintEvent *event){}#elsevoid MainWindow::paintEvent(QPaintEvent *event){    QPainter mypainter(this);    mypainter.setPen(QPen(Qt::black,1));    //画地图    for(QVector< QVector<int> >::size_type i=0;i!=WIDTH;i++)        for(QVector<int>::size_type j=0;j!=HEIGHT;j++ )            switch(map.at(j).at(i))            {                case 0:                    mypainter.setBrush(Qt::black);                    mypainter.drawPixmap(i*25,j*25,QPixmap(":/xsd/images/ground.png"));                    break;                case 1:                    mypainter.setBrush(Qt::red);                    mypainter.drawPixmap(i*25,j*25,QPixmap(":/xsd/images/stone.png"));                    break;            }    //画苹果    mypainter.drawPixmap(apple.x()*25,apple.y()*25,QPixmap(":/xsd/images/apple.png"));    //画蛇    //蛇头    switch(direc)    {        case UP:            mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_up.png"));            break;        case DOWN:            mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_down.png"));            break;        case LEFT:            mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_left.png"));            break;        case RIGHT:            mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_right.png"));            break;    }    //蛇身    for(QVector<QPoint>::size_type i=1;i!=snake.size();i++)    {        mypainter.drawPixmap(snake[i].x()*25,snake[i].y()*25,QPixmap(":/xsd/images/body.png"));    }    //qDebug()<<"painter 运行成功";    event->accept();}#endif#ifndef KEVENTvoid MainWindow::keyPressEvent(QKeyEvent *event){}#elsevoid MainWindow::keyPressEvent(QKeyEvent *event){    switch(event->key())    {        case    Qt::Key_Up:            //蛇头和脖子没有都朝上前进            if(snake[0].y()!=snake[1].y()+1)                move(UP);            if(snake[0]==apple)            {                eat();                randapple();            }            if(map[snake[0].y()][snake[0].x()]==1)            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!"));                gameover();            }            if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end())            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了"));                gameover();            }            direc=UP;            update();            break;    case Qt::Key_Down:            if(snake[0].y()!=snake[1].y()-1)                move(DOWN);            if(snake[0]==apple)            {                eat();                randapple();            }            if(map[snake[0].y()][snake[0].x()]==1)            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!"));                gameover();            }            if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end())            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了"));                gameover();            }            direc=DOWN;            update();            break;        case Qt::Key_Right:            if(snake[0].x()!=snake[1].x()-1)                move(RIGHT);            if(snake[0]==apple)            {                eat();                randapple();            }            if(map[snake[0].y()][snake[0].x()]==1)            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!"));                gameover();            }            if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end())            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了"));                gameover();            }            direc=RIGHT;            update();            break;        case Qt::Key_Left:            if(snake[0].x()!=snake[1].x()+1)                move(LEFT);            if(snake[0]==apple)            {                eat();                randapple();            }            if(map[snake[0].y()][snake[0].x()]==1)            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!"));                gameover();            }            if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end())            {                 timer->stop();                QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了"));                gameover();            }            direc=LEFT;            update();            break;    }    qDebug()<<"kevent 运行成功";    event->accept();}#endifvoid MainWindow::automove(){    move(direc);    if(snake[0]==apple)    {        eat();        randapple();    }    if(map[snake[0].y()][snake[0].x()]==1)    {         timer->stop();        QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!"));        gameover();    }    if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end())    {         timer->stop();        QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了"));        gameover();    }    update();    qDebug()<<"automove 运行成功";}void MainWindow::gameover(){    int f=-1;    for(int i=0;i<3;i++)    {        if(score>=sco[i])        {            f=i;            break;        }    }    if(0<=f&&f<=2)    {        getname();        switch(f)        {        case 0:            sco[2]=sco[1];            sco[1]=sco[0];            sco[0]=score;            nam[2]=nam[1];            nam[1]=nam[0];            nam[0]=player;            break;        case 1:            sco[2]=sco[1];            sco[1]=score;            nam[2]=nam[1];            nam[1]=player;            break;        case 2:            sco[2]=score;            nam[2]=player;            break;            default:break;        }        save();    }    exit(EXIT_SUCCESS);}void MainWindow::save(){    fstream file1;    file1.open("score.dat",ios::out);    if(file1)    {       for(int i=0;i<3;i++)       {           if(nam[i].length()==0)               nam[i]="UnknowPlayer";           file1<<nam[i]<<" "<<sco[i]<<endl;       }        file1.close();    }    else    {        QMessageBox message(QMessageBox::NoIcon, "报告", "保存失败");        message.exec();    }}void MainWindow::on_action_Pause_triggered(){  timer->stop();}void MainWindow::on_action_Continue_triggered(){    timer->start(speed);}void MainWindow::on_action_level1_triggered(){    timer->stop();    level=1;    speed=LEVEL[level];}void MainWindow::on_action_level2_triggered(){    timer->stop();    level=2;    speed=LEVEL[level];}void MainWindow::on_action_level3_triggered(){    timer->stop();    level=3;    speed=LEVEL[level];}void MainWindow::on_action_level4_triggered(){    timer->stop();    level=4;    speed=LEVEL[level];}void MainWindow::on_action_level5_triggered(){    timer->stop();    level=5;    speed=LEVEL[level];}void MainWindow::on_action_help_triggered(){    QMessageBox message(QMessageBox::NoIcon, "说明", "使用键盘上的 ↑ ↓ ← → 四个按键控制蛇\n");    message.setIconPixmap(QPixmap(":/fire/icon/snake.ico"));    message.exec();}void MainWindow::on_action_author_triggered(){    QMessageBox message(QMessageBox::NoIcon, "作者", "Made by Fire\nQQ:759378563\nE-mail:dd759378563@126.com\n\t2013.11\n");    message.setIconPixmap(QPixmap(":/fire/icon/author.ico"));    message.exec();}void MainWindow::loadscore(){       fstream file1;       file1.open("score.dat",ios::in);       if(file1)       {           for(int i=0;i<3;i++)               file1>>nam[i]>>sco[i];        file1.close();       }       else       {            QMessageBox message(QMessageBox::NoIcon, "报告", "读取失败");            message.exec();       }}void MainWindow::on_action_Score_triggered(){    Dialog dia;    dia.exec();}void MainWindow::getname(){    readname *rname;    rname=new readname();    if(connect(rname,SIGNAL(sendData(string)),this,SLOT(receiveData(string))))        qDebug()<<"rname 连接成功";    else        qDebug()<<"rname 连接失败";    rname->exec();}void MainWindow::receiveData(string rec){    player=rec;    qDebug( )<<"用户名字是:"<< QString::fromStdString(player);}void MainWindow::init_statuBar(){    QStatusBar * bar=ui->statusBar;    first_statusLabel=new QLabel;       first_statusLabel->setMinimumSize(150,20);       first_statusLabel->setFrameShape(QFrame::WinPanel);       first_statusLabel->setFrameShadow(QFrame::Sunken);       second_statusLabel=new QLabel;       second_statusLabel->setMinimumSize(150,20);       second_statusLabel->setFrameShape(QFrame::WinPanel);       second_statusLabel->setFrameShadow(QFrame::Sunken);       bar->addWidget(first_statusLabel);       bar->addWidget(second_statusLabel);       first_statusLabel->setText(tr("欢迎使用贪食蛇"));       second_statusLabel->setText(tr("Fire制作"));}void MainWindow::addscore(){    second_statusLabel->setText(tr("当前得分: %1").arg(score));}


源代码下载地址:

http://download.csdn.net/detail/d759378563/6618471

原创粉丝点击