QT 貪吃蛇簡單代碼實現(原創用於理解原理,請勿隨意傳播)

main.cpp 

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *w = new MainWindow;
    w->show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void paintEvent(QPaintEvent*event);
    void keyPressEvent(QKeyEvent*event);
    void keyReleaseEvent(QKeyEvent *event);

    void timerEvent(QTimerEvent *event);
    void move_judg(QString snake);

    int get_random_number(int min,int max);
    void set_food();
    void init_snake();
public:
    int snake_max = 100;
    int speed = 10;
    int timerate = 150;
    int maxview_x = 450;
    int maxview_y = 600;
    QString snakedirection = "down";

private:
    Ui::MainWindow *ui;

    int snake_x[100] =
    {
       50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    };
    int snake_y[100] =
    {
       30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    };
    int time_ID = 0;
    int fast_time_ID = 0;
    int random_x = 0;
    int random_y = 0;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QKeyEvent>
#include <QTimer>
#include <QTime>
#include <QtGlobal>
#include <QMessageBox>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    set_food();//投食;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *event)//畫最大界面以及蛇頭
{
    QPainter painter(this);

    painter.setPen(QPen(Qt::blue, 1));
    for(int i=0; i < snake_max; i ++)
    painter.drawEllipse(snake_x[i], snake_y[i], 10, 10);

    painter.setPen(QPen(Qt::black, 1));
    painter.drawRect(10, 20, maxview_x, maxview_y);

    painter.setPen(QPen(Qt::red, 1));
    painter.drawRect(random_x, random_y, 5, 5);
}
void MainWindow::keyPressEvent(QKeyEvent *event)//短按
{
    switch (event->key())
    {
    case Qt::Key_Left:
        if(snakedirection == "right" && snake_x[1] != 0)
        {
            init_snake();break;
        }
        snakedirection = "left"; break;
    case Qt::Key_Right:
        if(snakedirection == "left" && snake_x[1] != 0)
        {
            init_snake();break;
        }
        snakedirection = "right"; break;
    case Qt::Key_Up:
        if(snakedirection == "down" && snake_x[1] != 0)
        {
            init_snake();break;
        }
        snakedirection = "up"; break;
    case Qt::Key_Down:
        if(snakedirection == "up" && snake_x[1] != 0)
        {
            init_snake();break;
        }
        snakedirection = "down"; break;
    default:
        break;
    }
    repaint();
    QWidget::keyPressEvent(event);
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)//檢測鬆開
{
    switch (event->key())
    {
    case Qt::Key_Left:
    case Qt::Key_Right:
    case Qt::Key_Up:
    case Qt::Key_Down:
        if (event->isAutoRepeat())
        {
            killTimer(time_ID);
            killTimer(fast_time_ID);
            fast_time_ID = this->startTimer(0.1 * timerate);//定時器啓動
        }
        else
        {
            killTimer(time_ID);
            killTimer(fast_time_ID);
            time_ID = this->startTimer(timerate);
        }
        break;
    default:
        break;
    }
    QWidget::keyReleaseEvent(event);
}
void MainWindow::timerEvent(QTimerEvent *event)//定時器
{
    move_judg(snakedirection);
}
void MainWindow::move_judg(QString snake)//移動,以及判斷撞牆
{
    int temp_x = 0;
    int temp_y = 0;
    for(int i = (snake_max - 1); i >= 0; i--)
    {
        if(snake_x[i] != 0)
        {
            temp_x = snake_x[i];
            temp_y = snake_y[i];
            if(i != 0)
            {
                snake_x[i] = snake_x[i-1];
                snake_y[i] = snake_y[i-1];
            }
        }
    }
    if(snake == "left")
        snake_x[0] -= speed;
    if(snake == "right")
        snake_x[0] += speed;
    if(snake == "up")
        snake_y[0] -= speed;
    if(snake == "down")
        snake_y[0] += speed;
    if(snake_x[0] >= 10 && snake_x[0] <= maxview_x && snake_y[0] >= 20 && snake_y[0] <= (maxview_y + 10))
    {
        int i = 0;
        if((snake_x[0] - random_x) >= -10
                && (snake_x[0] - random_x) <= 5
                && (snake_y[0] - random_y) >= -10
                && (snake_y[0] - random_y) <= 5)//吃到食物的情況下
        {
            for(i = (snake_max - 1); i >= 0; i--)
            {
                if(snake_x[i] != 0)
                {
                    snake_x[i+1] = temp_x;
                    snake_y[i+1] = temp_y;
                    break;
                }
            }
            set_food();
        }
        for(i = 1; i < snake_max; i++)
        {
            if((snake_x[0] - snake_x[i]) > -10
                    && (snake_x[0] - snake_x[i]) < 10
                    && (snake_y[0] - snake_y[i]) > -10
                    && (snake_y[0] - snake_y[i]) < 10)
            {
                init_snake();
            }
            if(snake_x[i] == 0 && snake_y[i] == 0)
                break;
        }
    }
    else
    {
        init_snake();
    }
    repaint();
}
int MainWindow::get_random_number(int min,int max)//隨機生成min到max的隨機數
{
     int temp = 0;
     //qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//定義隨機數種子
     temp = qrand() % (max - min);
     return temp + min;
}
void MainWindow::set_food()
{
    random_x = get_random_number(10,maxview_x);
    random_y = get_random_number(20,maxview_y + 10);
    if((snake_x[0] - random_x) >= -10
            && (snake_x[0] - random_x) <= 5
            && (snake_y[0] - random_y) >= -10
            && (snake_y[0] - random_y) <= 5)
        set_food();
    for(int i = 0; i < snake_max; i++ )
        if(random_x == snake_x[i] && random_y == snake_y[i] )
            set_food();
    repaint();
}
void MainWindow::init_snake()
{
    killTimer(time_ID);
    killTimer(fast_time_ID);
    QMessageBox::StandardButton reply;
    reply = QMessageBox::information(this, tr("GAME OVER"), "Game have been over? Restart?", QMessageBox::Ok);
    if (reply == QMessageBox::Ok)
    {
     for(int i = (snake_max - 1); i > 0; i--)
     {
         snake_x[i] = 0;
         snake_y[i] = 0;
     }
     snake_x[0] = 50;
     snake_y[0] = 30;
     snakedirection = "down";
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章