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

  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/umgsai/p/3908081.html
Copyright © 2011-2022 走看看