一、实现思路
- 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