天天看點

QT 小遊戲 : 别踩白塊兒~

一、實作思路

  1. QPainter 繪制 遊戲界面

    PS:根據方塊坐标連結清單繪制所有方塊

  2. 支援兩種操作方式

    PS:滑鼠事件 和 鍵盤事件(Q,W,E,R,T)

  3. 定時器(10ms) 重新整理 方塊坐标資料
  4. 根據得分修改方塊的步進速度

    PS:簡單的 step = sum % 10;【自己可以修改成喜歡的規則】

二、實際效果

QT 小遊戲 : 别踩白塊兒~

三、關鍵代碼分析

源碼連結 : https://github.com/AutoCatFuuuu/QT/tree/master/whiteblock

1. 方塊坐标資訊處理類 【BlockData】
PS: 無非就是增删查改的功能
#ifndef BLOCKDATA_H
#define BLOCKDATA_H

#include <stdio.h>

struct BData{
    int x;
    int y;
    int width;
    int height;
    BData *next;
};

class BlockData
{
public:
    BlockData();
    ~BlockData();
    void init(BData **d,int x=0,int y=0,int width=0,int height=0);   //初始化
    void insert(BData *d);          //插入資料
    bool remove(int x,int y);       //删除資料
    bool remove(int x);             //删除資料
    void updata(int step);          //更新資料
    bool judge(int y);              //判斷資料
    void clear();                   //清空資料
    BData* get(){ return head;}     //讀取資料
    void show();                    //顯示資料
private:
    BData *head;
    BData *tail;
};

#endif // BLOCKDATA_H
           
2 . 遊戲操作界面類 【TestWidget】#####
這裡有多種方法實作,我是在mianwindow.ui 裡拖個widget 再提升為 TestWidget 【記得設定facus屬性 鍵盤事件需要用到的】
#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QTimer>
#include "blockdata.h"

namespace Ui {
class TestWidget;
}

class TestWidget : public QWidget
{
    Q_OBJECT

public:
    explicit TestWidget(QWidget *parent = 0);
    ~TestWidget();
    void setDSize(int width,int height);    //設定方塊寬高
    void start();                           //開始遊戲
    void restart();                         //重新開始
protected:
    void paintEvent(QPaintEvent *event);        //繪制界面
    void mousePressEvent(QMouseEvent *event);   //點選事件
    void keyReleaseEvent(QKeyEvent *event);     //鍵盤事件
signals:
    void failure();         //失敗信号
    void value(int value);  //成績信号
private slots:
    void updateData();      //更新資料
private:
    Ui::TestWidget *ui;
    QTimer timer;       //定時器
    BlockData bData;    //方塊坐标資料類
    int step;           //步進速度
    int Dwidth;         //小方塊寬度
    int Dheight;        //小方塊高度
    bool isfailure;     //失敗标志
    int sum;            //總分
};

#endif // TESTWIDGET_H

           
void TestWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.fillRect(rect(),Qt::white);

    painter.setBrush(Qt::black);

    if(isfailure) {
        int w = 200;
        int h = 30;
        QFont f;f.setPixelSize(32);
        painter.setFont(f);
        painter.drawText((width()-w)/2,(height()-h)/2,w,h,Qt::AlignCenter,"failure!!!");
    }else {
        BData* d = bData.get();

        while(d){
            painter.drawRect(d->x,d->y,d->width,d->height);
            d = d->next;
        }
    }
}

void TestWidget::mousePressEvent(QMouseEvent *event)
{
    QPoint point = event->pos();
    if(bData.remove(point.x(),point.y())) {
        sum++;
        emit value(sum);
        //重新整理速度
        if(sum%10 == 0)
            step++;
    }
}

void TestWidget::keyReleaseEvent(QKeyEvent *event){

    if(event->isAutoRepeat())
        return;

    bool _sum = false;
    switch(event->key())
    {
        case Qt::Key_Q:     _sum = bData.remove(Dwidth-1);break;
        case Qt::Key_W:     _sum = bData.remove(2*(Dwidth-1));break;
        case Qt::Key_E:     _sum = bData.remove(3*(Dwidth-1));break;
        case Qt::Key_R:     _sum = bData.remove(4*(Dwidth-1));break;
        case Qt::Key_T:     _sum = bData.remove(5*(Dwidth-1));break;
        default:break;
    }
    if(_sum) {
        sum++;
        emit value(sum);
        //重新整理速度
        if(sum%10 == 0)
            step++;
    }
}

void TestWidget::updateData()
{
    static int _step = Dheight;
    // 插入新值
    if(_step >= Dheight) {

        BData *d = new BData;
        int x = qrand() % 4;
        bData.init(&d,x*Dwidth,-Dheight,Dwidth,Dheight);
        bData.insert(d);
        _step = 0;

    }

    // 更新資料
    bData.updata(step);
    //判斷失敗條件
    if(!bData.judge(height())) {
        isfailure = true;
        emit failure();
        timer.stop();
    }
    _step+=step;
    //重新整理界面
    update();
}

           

三、寫在最後

在B站逛的時候看見别人用JS寫了《别踩白塊兒》,發現代碼量挺少的,那如果用QT寫會怎樣呢?
然後這就是興趣使然的結果了。沒有華麗麗的效果,隻有樸實有力的功能。【強行解釋自己菜得扣腳(ˉ▽ˉ;)...】
如果有興趣和我交流的話,可以留言【佛系回複】或者 加我QQ 673315140
           
Qt

繼續閱讀