zoukankan      html  css  js  c++  java
  • QT实现贪吃蛇

    board.h

    #ifndef BOARD_H
    #define BOARD_H
    
    #define MAX_X 40
    #define MAX_Y 30
    #define NORMAL_LABEL 0//普通label
    #define BORDER_LABEL 1//边界label
    #define SNAKE_LABEL 2//蛇身label
    #define FOOD_LABEL 3//食物label
    
    #include <QWidget>
    #include <QLabel>
    #include <QList>
    #include <QTimer>
    #include <QKeyEvent>
    
    struct Node{
        QLabel *label;
        int type;//边界:1   蛇身:2  普通:0 食物:3
        int x;
        int y;
    };
    
    class Board : public QWidget
    {
        Q_OBJECT
    public:
        explicit Board(QWidget *parent = 0);
        void init();
        void drawBorder();//画边界
        void initSnake();
        void moveStep();
        void getHeadTail();//得到头和尾
        bool left();//判断是否能上下左右移动
        bool right();
        bool up();
        bool down();
        void keyPressEvent(QKeyEvent *e);//键盘事件
    //    void gameover();
    //    void showAllType();
        void generateFood();//生成食物
    
    signals:
    
    public slots:
        void slotMoveStep();//槽函数,可以当做普通函数使用
    
    
    private:
        Node *matrix[MAX_X][MAX_Y];
        QList<Node*> snake;//蛇身
    
        int dx, dy;
        Node *head;//蛇头指针
        Node *tail;//蛇尾指针
    
        QTimer timer;
    
    };
    
    #endif // BOARD_H


    boarder.cpp

    #include "board.h"
    #include <QDebug>
    #include <QString>
    #include <QTimer>
    #include <QMessageBox>
    #include <QKeyEvent>
    #include <ctime>
    
    Board::Board(QWidget *parent) :
        QWidget(parent)
    {
        this->setWindowTitle("贪吃蛇");
        init();//初始化
        drawBorder();//画边界
        initSnake();//初始化蛇身
        moveStep();
    
        generateFood();//初始化完就产生一个食物
    
        connect(&timer, SIGNAL(timeout()), this, SLOT(slotMoveStep()));
        timer.start(100);
    
    }
    
    void Board::init(){
        int gridSize = 25;
    
        for(int x = 0; x < MAX_X; x++){
            for(int y = 0; y < MAX_Y; y++){
                QLabel *label = new QLabel(this);
                label->setStyleSheet("background:red");
                label->setGeometry(x * gridSize, y * gridSize, gridSize - 1, gridSize - 1);
                label->hide();
                matrix[x][y]= new Node;
                matrix[x][y]->label =label;
                matrix[x][y]->type = NORMAL_LABEL;//将所有的都初始化成普通label
                matrix[x][y]->x = x;
                matrix[x][y]->y = y;
            }
        }
    }
    
    void Board::drawBorder(){//画边界
        for(int x = 0; x < MAX_X; x++){
            for(int y = 0; y < MAX_Y; y++){
                if(x == 0 || x == MAX_X - 1 || y == 0 || y == MAX_Y - 1){
                    matrix[x][y]->label->show();
                    matrix[x][y]->type = BORDER_LABEL;//边界label
                }
            }
        }
    }
    
    void Board::initSnake(){//画蛇身
        int x0 = 5, y0 = 5;
        int snakeLen = 5;//初始蛇身长5
    
        dx = 1;
        dy = 0;
        snake.clear();
        for(int x = x0; x < x0 + snakeLen; x++){
    
            snake.append(matrix[x][y0]);
            snake.at(snake.length() - 1)->x = x;
            snake.at(snake.length() - 1)->y = y0;
            matrix[x][y0]->type = SNAKE_LABEL;//蛇身label
            matrix[x][y0]->label->show();
        }
    
    }
    
    void Board::moveStep(){
        getHeadTail();//获取蛇头和蛇尾指针
        Node *n = matrix[head->x + dx][head->y + dy];
        n->label->show();
        //n是即将变成蛇头的那个label
        if(n->type == BORDER_LABEL || n->type == SNAKE_LABEL){
            qDebug() << "Game over@!!!";
            timer.stop();
            QMessageBox::information(this, "提示", "*** Game Over ***", QMessageBox::Ok);
        }else{
            if(n->type == FOOD_LABEL){//吃到食物了
                n->type = SNAKE_LABEL;
                snake.append(n);
                //不移除尾巴
                generateFood();//生成下一个食物
            }else{
                n->type = SNAKE_LABEL;
                snake.append(n);
                tail->label->hide();
                tail->type = NORMAL_LABEL;
                snake.removeFirst();
            }
        }
    }
    
    void Board::getHeadTail(){
        head = snake.at(snake.length() - 1);//蛇头其实是list的尾巴
        tail = snake.at(0);//蛇尾其实是list的第一个元素
        //    gameover();
    }
    
    void Board::slotMoveStep(){
        //    qDebug() << "movestep";
        moveStep();
    }
    
    void Board::keyPressEvent(QKeyEvent *e){
        //qDebug() << Qt::Key_up;
        qDebug() << e->key();
        switch (e->key()) {
        case 16777235://上
            if(up()){
                dy = -1;
                dx = 0;
            }
            break;
        case 16777237://下
            if(down()){
                dy = 1;
                dx = 0;
            }
            break;
        case 16777234://左
            if(left()){
                dx = -1;
                dy = 0;
            }
            break;
        case 16777236://右
            if(right()){
                dx = 1;
                dy = 0;
            }
            break;
        default:
            break;;
        }
    }
    
    void Board::generateFood(){//生成食物
        int food_x,food_y;
        srand((unsigned)time(0));
        do{
            food_x = rand()%MAX_X;
            food_y = rand()%MAX_Y;
        }while(matrix[food_x][food_y]->type != NORMAL_LABEL);
    //    matrix[food_x][food_y]->label->setText("food");
        matrix[food_x][food_y]->type = FOOD_LABEL;
        matrix[food_x][food_y]->label->show();
    
    }
    
    bool Board::left(){
        if(dy == 0){//向左或向右走
            return false;
        }
        return true;
    }
    
    bool Board::right(){
        if(dy == 0){//向左或向右走
            return false;
        }
        return true;
    }
    
    bool Board::up(){
        if(dx == 0){//向上或向下走
            return false;
        }
        return true;
    }
    
    bool Board::down(){
        if(dx == 0){//向上或向下走
            return false;
        }
        return true;
    }


    wKiom1Oeqa-ymO_qAAG6R9KtXxQ333.jpg

    本文出自 “阿凡达” 博客,请务必保留此出处http://shamrock.blog.51cto.com/2079212/1426968

  • 相关阅读:
    CCF NOI1121 逆波兰表达式
    Vijos P1217 乒乓球【模拟+输入输出】
    Vijos P1304 回文数【回文+进制】
    NUC1041 数字三角形【DP】
    CCF NOI1070 汉诺塔游戏
    CCF NOI1069 分解因数
    CCF NOI1149 N皇后问题
    CCF NOI1153 素数环
    CCF NOI1170 质因数分解
    POJ NOI MATH-7832 最接近的分数
  • 原文地址:https://www.cnblogs.com/umgsai/p/3908081.html
Copyright © 2011-2022 走看看