Qt实战之接金币小游戏
自学了大概两个月Qt,今天做了一个小小的项目,参照书为Qt图形界面编程入门(清华大学仇国巍编著),本次项目主要是为了实现一个以接金币目的的小游戏,主要包括图片导入,大小规划,Qt重新绘图Event,鼠标事件和定时器事件的使用,使用随机数生成金币,界面是这样的:
代码主要有以下部分:
H文件:
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QLabel> struct Money{ QRect rc;//金币位置矩形 int Value;//分数 int type;//-1 隐藏 0:5分 1:10分 2:20分 }; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); QRect pplRect;//包含人物的矩形 //人物 背景位图 以及分数 剩余时间背景位图 QPixmap picPPL,picBack,picScore,picTime; //三种分数的位图 QPixmap goldPic[3]; //最多产生200个各种金币 Money gold[200]; //定时器编号,第一个用于倒计时,后三个用于控制金币产生和下落 int timer0,timer1,timer2,timer3; //现有金币数 int numOfCoins; //下一次产生金币前调用函数次数,分数,秒表 int interval,score,stopWatch; protected: void paintEvent(QPaintEvent *); void keyPressEvent(QKeyEvent *e); void timerEvent(QTimerEvent * event); }; #endif // WIDGET_H
C文件,包括构造函数,定时器事件,鼠标时间以及重绘事件:
#include "widget.h" #include <QDebug> #include <ctime> #include <QPainter> #include <QKeyEvent> Widget::Widget(QWidget *parent) : QWidget(parent) { //加载背景位图 picBack.load(":/prj1/bg.jpeg"); picBack = picBack.scaled(650,500,Qt::IgnoreAspectRatio,Qt::FastTransformation); //加载人物背景位图 picPPL.load(":/prj1/1.png"); picPPL = picPPL.scaled(100,100,Qt::IgnoreAspectRatio,Qt::FastTransformation); pplRect = QRect(5,400,picPPL.width(),picPPL.height()); //加载分数背景位图 picScore.load(":/prj1/5.png"); picScore = picScore.scaled(100,100,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); picTime.load(":/prj1/time.png"); picTime = picTime.scaled(100,100,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); goldPic[0].load(":/prj1/2.png"); goldPic[0] = goldPic[0].scaled(30,30,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); goldPic[1].load(":/prj1/3.png"); goldPic[1] = goldPic[1].scaled(50,50,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); goldPic[2].load(":/prj1/4.png"); goldPic[2] = goldPic[2].scaled(100,100,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); //创建并且启动定时器 timer0=this->startTimer(1000); timer1=this->startTimer(300); timer2=this->startTimer(700); timer3=this->startTimer(1400); //实际获得的金币数量 numOfCoins = 0; //使得产生的随机序号每次不同 srand(time(0)); interval = 0; //分数 score = 0; //剩余时间 stopWatch = 90; setFocusPolicy(Qt::StrongFocus); resize(picBack.width(),picBack.height()); } Widget::~Widget() { } void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); //绘制背景位图 painter.drawPixmap(0,0,picBack.width(),picBack.height(),picBack); painter.drawPixmap(0,0,picScore.width(),picScore.height(),picScore); painter.drawPixmap(picBack.width()-picTime.width(),0, picTime.width(),picTime.height(),picTime); //卡通人物 painter.drawPixmap(pplRect,picPPL); //绘制金币 for(int i = 0;i < numOfCoins;i ++) { if(gold[i].type >= 0) painter.drawPixmap(gold[i].rc,goldPic[gold[i].type]); } QFont font(tr("微软雅黑"),15,QFont::Normal,false); painter.setFont(font); QRect rect(62,18,50,18); painter.drawText(rect,Qt::AlignCenter,QString::number(score)+ "分"); QRect rect2(593,18,50,18); painter.drawText(rect2,Qt::AlignCenter,QString::number(stopWatch)+ "秒"); } void Widget::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case(Qt::Key_Left): { if(pplRect.left() >= 20)//没有超出左边界 { int x = pplRect.left() - 20; pplRect.moveLeft(x); } update(); break; } case(Qt::Key_Right): { if(pplRect.right() <= (picBack.width() - 20))//没有超出边界 { int x = pplRect.right() + 20; pplRect.moveRight(x); } update(); break; } } QWidget::keyPressEvent(e); } void Widget::timerEvent(QTimerEvent * event) { if(numOfCoins >= 200) return; if(event->timerId() == timer0) { stopWatch --; return; } if(stopWatch == 0) { killTimer(timer0); killTimer(timer1); killTimer(timer2); killTimer(timer3); } //处理金币消失的情况 for(int i = 0;i < numOfCoins;i ++) { if(gold[i].type != -1 && pplRect.intersects(gold[i].rc)) { score = score + gold[i].Value; gold[i].type = -1; } if(gold[i].type != -1 && pplRect.bottom() < gold[i].rc.top()) { gold[i].type = -1; } } //处理金币移动 for(int i = 0;i < numOfCoins;i ++) { int y; if(gold[i].type == 0) y = gold[i].rc.top() + 10; if(gold[i].type == 1) y = gold[i].rc.top() + 18; if(gold[i].type == 2) y = gold[i].rc.top() + 26; gold[i].rc.moveTop(y); } //若interval大于0,返回 if(interval > 0) { interval --; update(); return; } //若interval等于0,则产生金币 //产生第一种分数 if(event->timerId() == timer1) { //随机产生横坐标 int x = rand() % (picBack.width() - goldPic[0].width() - 20) + 10; gold[numOfCoins].type = 0; gold[numOfCoins].rc = QRect(x,77,goldPic[0].width(),goldPic[0].height()); gold[numOfCoins].Value = 5; numOfCoins++; } //产生第二种分数 if(event->timerId() == timer2) { //随机产生横坐标 int x = rand() % (picBack.width() - goldPic[0].width() - 20) + 10; gold[numOfCoins].type = 1; gold[numOfCoins].rc = QRect(x,77,goldPic[1].width(),goldPic[1].height()); gold[numOfCoins].Value = 10; numOfCoins++; } //产生第三种分数 if(event->timerId() == timer3) { //随机产生横坐标 int x = rand() % (picBack.width() - goldPic[0].width() - 20) + 10; gold[numOfCoins].type = 2; gold[numOfCoins].rc = QRect(x,77,goldPic[2].width(),goldPic[2].height()); gold[numOfCoins].Value = 20; numOfCoins++; } //再次产生间隔次数3~5 interval=rand()%3 + 3; update(); }
Qt大概学了个一知半解,准备去肝图像处理了。
版权声明
本文仅代表作者观点。
本文系作者发表,未经许可,不得转载。
上一篇:搭建博客 下一篇:1-数据向量化及使用meshgrid函数
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。