首页 > 其他 > 详细

QT实现贪吃蛇

时间:2014-06-17 18:37:18      阅读:448      评论:0      收藏:0      [点我收藏+]

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;
}


bubuko.com,布布扣

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

QT实现贪吃蛇,布布扣,bubuko.com

QT实现贪吃蛇

原文:http://shamrock.blog.51cto.com/2079212/1426968

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!