今年最火爆的解压小游戏电子木鱼,现在许多软件都上架了这个小程序。我在网上看了一下基本上都是用py和Java写的,所以我用QT重新写了一下,作为小白练手项目非常适合
功能设计
鼠标点击和释放事件,模拟敲打木鱼动作
每一次的敲打木鱼都会缩小和放大一次
并且在木鱼上方显示出"功德+1"字样和播放一次敲打木鱼的声音
背景音乐一直播放
设置一个按钮为自动敲击木鱼
设置一个按钮为背景音乐的开关
我是使用的一个label来放图片
缩小的原理是在现有木鱼图片大小上长和宽都同时缩小一个比例m
因为是按照中心点不变的缩小
所以左上点pos的坐标下降m/2
放大同理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// m = 10 图签放大,pos点上移. // m = -10 图签缩小,pos点下移. void Widget::MuYu(int m) { //获取当前label图片宽 int currentWidth = ui->label->width(); //获取当前label图片高 int currentHeight = ui->label->height(); //改变图片大小 currentWidth += m; currentHeight += m; //在标签上重新设置图片大小和图片起始位置 ui->label->setGeometry(ui->label->pos().x()-m/2,ui->label->pos().y()-m/2,currentWidth, currentHeight); } |
用一个label设置文字 “功德+1”
这里文字出现的位置可以是随机的也可以定点出现
随机出现可以跟踪鼠标点击的位置
定点出现要提前写一个QPoint指定地点 (示例这个方式)
每一次出现后先上移一定位置(会使用QT动画函数 QPropertyAnimation ),然后消失
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void Widget::gongde() { ui->label_2->setText("功德+1"); //QPropertyAnimation *m_TopPropertyAnimation; //绑定要移动的label对象 m_TopPropertyAnimation->setTargetObject(ui->label_2); //设置按pos属性移动 m_TopPropertyAnimation->setPropertyName("pos"); // set 动画的起点、终点、持续时间 m_TopPropertyAnimation->setDuration(600); m_TopPropertyAnimation->setStartValue(pos); m_TopPropertyAnimation->setEndValue(pos+QPoint(0, -120)); // 启动和结束 m_TopPropertyAnimation->start(); //这里加一个延时函数避免,避免动画没有结束直接清除文字 Delay(600); //清除文字 ui->label_2->clear(); } |
背景音乐BGM<<大悲咒>>直接功德加满
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void Widget::bgMusice() { //QMediaPlayer *bg_player; qDebug()<<"dmz"; //BACKMUSICE 宏定义文件路径 bg_player->setMedia(QUrl::fromLocalFile(BACKMUSICE)); bg_player->setVolume(10); bg_player->play(); // 槽函数 监听QMediaPlayer::mediaStatusChanged信号 实现背景音乐循环播放 connect(bg_player, &QMediaPlayer::mediaStatusChanged,this,&Widget::initStatus); } void Widget::initStatus(QMediaPlayer::MediaStatus status) { if(status == QMediaPlayer::EndOfMedia) { bg_player->setPosition(0); bg_player->play(); } } |
敲击木鱼声音
1 2 3 4 5 6 7 8 9 10 11 |
void Widget::MuYuMusice() { //QMediaPlayer *MuYu_player; //设置要播放的媒体 //MUYUMUSICE宏定义文件路径 MuYu_player->setMedia(QUrl::fromLocalFile(MUYUMUSICE)); //设置音量 MuYu_player->setVolume(50); //播放 MuYu_player->play(); } |
写个槽函数,定时器定时触发,可以绑定滑杆设置一个敲打频率,同理可以调节背景音乐大小
1 2 3 4 5 6 7 8 9 10 11 12 |
void Widget::Auto() { qDebug()<<"Auto"; //图片缩小 MuYu(-10); //敲到木鱼声音 MuYuMusice(); //功德+1文字 gongde(); //图片放大 MuYu(10); } |
1 2 3 4 5 6 |
void Widget::Delay(int delay_time) { QEventLoop loop; QTimer::singleShot(delay_time,&loop,SLOT(quit())); loop.exec(); } |
widget.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#ifndef WIDGET_H #define WIDGET_H
#include <QWidget> #include <QPainter> #include <QRect> #include <QPropertyAnimation> #include <QMediaPlayer> #include <QTime> #include <QTimer> #include <QSystemTrayIcon> #include <QLabel> #include <QPainter> #include <QRect>
#define WIDTH 480 #define HEIGH 640 #define MUYUMUSICE "C:\\Users\\Liu\\Desktop\\code\\QT\\muyu\\untitled\\musice\\muyu.mp3" #define BACKMUSICE "C:\\Users\\Liu\\Desktop\\code\\QT\\muyu\\untitled\\musice\\bg.mp3" #define ICON ":/img/muy.ico"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; } QT_END_NAMESPACE
class Widget : public QWidget { Q_OBJECT
public: Widget(QWidget *parent = nullptr); ~Widget();
void mousePressEvent(QMouseEvent *event); //点击 void mouseReleaseEvent(QMouseEvent *event); //释放 void MuYu(int); void gongde(); void MuYuMusice(); void bgMusice(); void Delay(int); void tray(); void initStatus(QMediaPlayer::MediaStatus status); // 槽函数 监听QMediaPlayer::mediaStatusChanged信号 private slots: void on_toolButton_2_clicked(bool checked); void on_toolButton_clicked(bool checked); void Auto();
private: Ui::Widget *ui; QMediaPlayer *MuYu_player; QMediaPlayer *bg_player; QPoint pos; QPropertyAnimation *m_TopPropertyAnimation; QTimer *timer; QSystemTrayIcon *m_systemTray; int conut=0; }; #endif // WIDGET_H |
widget.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
#include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QMouseEvent>
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { setMouseTracking(true); ui->setupUi(this); bg_player = new QMediaPlayer; MuYu_player = new QMediaPlayer;
this->setWindowTitle("电子木鱼"); this->setFixedSize(WIDTH,HEIGH); this->setWindowIcon(QIcon(ICON)); m_TopPropertyAnimation = new QPropertyAnimation(this); pos=ui->label_2->pos();
timer = new QTimer; connect(timer,SIGNAL(timeout()),this,SLOT(Auto())); bgMusice(); tray();
}
Widget::~Widget() { delete ui; }
void Widget::tray() { m_systemTray = new QSystemTrayIcon(this); m_systemTray->setIcon(QIcon(ICON)); m_systemTray->setToolTip("SystemTray Program"); m_systemTray->show(); }
// m=10 图签放大 pos点上移 // m=-10 图签缩小 pos点下移 void Widget::MuYu(int m) { //获取当前label图片宽 int currentWidth = ui->label->width(); //获取当前label图片高 int currentHeight = ui->label->height(); //改变图片大小 currentWidth += m; currentHeight += m; //在标签上重新设置图片大小和图片起始位置 ui->label->setGeometry(ui->label->pos().x()-m/2,ui->label->pos().y()-m/2,currentWidth, currentHeight); } void Widget::MuYuMusice() { //设置要播放的媒体 MuYu_player->setMedia(QUrl::fromLocalFile(MUYUMUSICE)); //设置音量 MuYu_player->setVolume(50); //播放 MuYu_player->play(); }
void Widget::bgMusice() { qDebug()<<"dmz"; bg_player->setMedia(QUrl::fromLocalFile(BACKMUSICE)); bg_player->setVolume(10); bg_player->play(); // 槽函数 监听QMediaPlayer::mediaStatusChanged信号 实现背景音乐循环播放 connect(bg_player, &QMediaPlayer::mediaStatusChanged,this,&Widget::initStatus); } void Widget::initStatus(QMediaPlayer::MediaStatus status) { if(status == QMediaPlayer::EndOfMedia) { bg_player->setPosition(0); bg_player->play(); } }
void Widget::gongde() { ui->label_2->setText("功德+1"); // bind m_TopPropertyAnimation->setTargetObject(ui->label_2); m_TopPropertyAnimation->setPropertyName("pos"); // set 动画的起点、终点、持续时间 m_TopPropertyAnimation->setDuration(600); m_TopPropertyAnimation->setStartValue(pos); m_TopPropertyAnimation->setEndValue(pos+QPoint(0, -120)); // 启动和结束 m_TopPropertyAnimation->start(); Delay(600); ui->label_2->clear(); }
void Widget::mousePressEvent(QMouseEvent *event) { qDebug()<<"press"; MuYu(-10); MuYuMusice(); gongde(); }
void Widget::mouseReleaseEvent(QMouseEvent *event) { qDebug()<<"release"; MuYu(10); }
void Widget::on_toolButton_clicked(bool checked) { if (checked) { timer->start(500); } else { timer->stop(); } }
void Widget::on_toolButton_2_clicked(bool checked) { if(checked) { bg_player->stop(); }else { bg_player->play(); } }
void Widget::Auto() { qDebug()<<"Auto"; MuYu(-10); MuYuMusice(); gongde(); MuYu(10); }
//延时 void Widget::Delay(int delay_time) { QEventLoop loop; QTimer::singleShot(delay_time,&loop,SLOT(quit())); loop.exec(); } |