一、實作思路
QPainter 繪制 遊戲界面
PS:根據方塊坐标連結清單繪制所有方塊
支援兩種操作方式
PS:滑鼠事件 和 鍵盤事件(Q,W,E,R,T)
- 定時器(10ms) 重新整理 方塊坐标資料
根據得分修改方塊的步進速度
PS:簡單的 step = sum % 10;【自己可以修改成喜歡的規則】
二、實際效果

三、關鍵代碼分析
源碼連結 : 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