Demo_2:Qt实现猜字小游戏
1 环境
系统:windows 10
代码编写运行环境:Qt Creator 4.4.1 (community)
Github:
2 简介
参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=35https://www.bilibili.com/video/BV1XW411x7NU?p=35
参考博客:https://blog.csdn.net/fengge2018/article/details/106411326
实现功能:一个猜字小游戏,系统随机产生一个4位数,在规定时间内,我们输入4位数进行匹配,如果相同,则赢了;不同且时间到了,则输了。
赢了的实现效果如下:
输了的实现效果如下:
3 实现过程
下面简单说明一下实现的过程:
(1)先创建一个带ui的项目工程,主要包含了如下文件。
(2)ui界面的设计
我们进入widget.ui进行界面设计。使用QStackWidget来存放多个页面,包括以下4个页面:
pageSet是我们刚开始运行时的页面,包含两个QLabel、一个QComboBox、两个QPushButton,如下图:
pageGame是我们玩游戏时的页面,包含一个QProgressBar、一个QTextEdit、10个按钮,如下图:
pageWin是胜利时显示的页面,就只包含一个QLabel组件:
pageLose是输了的时候显示的页面,也只包含一个QLabel组件:
(3)代码逻辑
启动后,我们点击“进入游戏按钮”切换到pageGame,并读取出QComboBox中设置的倒计时时间,启动一个计数器开始计数,并生成一个四位数的随机数;
然后我们输入数字按钮开始进行匹配,数字按钮的槽函数使用同一个,因为它们处理的逻辑是一样的;
若我们输入的数字和随机数相同,则计数器停止计数,并切换到pageWin,启动另一个计时器,显示5s动画后,回到pageSet;
若我们输入的数字和随机数不同,则判断其和随机数的大小,并给出对应的提示;
若时间到了且我们没有猜出成功的答案,则切换到pageLose,启动另一个计时器,显示5s动画后,回到pageSet。
(4)实现代码
widget.h代码:


#ifndef WIDGET_H
#define WIDGET_H #include <QWidget>
#include <QString>
#include <QTimer>
#include <QMovie> namespace Ui {
class Widget;
} //目的:实现一个猜字游戏
//说明:
// class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); //槽函数
void on_PushButtonStart_clicked();
void on_PushButtonQuit_clicked();
void on_PushButtonRollback_clicked();
void on_PushButtonNotice_clicked();
void dealNum();
void timerEvent(QTimerEvent *event); private:
int gameTime;
int gameTimerId; //游戏定时器
int loseTimerId; //输了
int winTimerId; //赢了
QString randStr; //随机数
QString resultStr; //结果数
QMovie winMovie; //赢了的动画
QMovie loseMovie; //输了的动画 private:
Ui::Widget *ui;
}; #endif // WIDGET_H
widget.cpp代码:


#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTime>
#include <QMessageBox> Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this); //显示第一个页面,设置页面
ui->stackedWidget->setCurrentWidget(ui->pageSet);
//失败动画
loseMovie.setFileName(":/new/prefix1/image/over.gif");
ui->label_lose->setMovie(&loseMovie);//给标签设置动画
ui->label_lose->setScaledContents(true);//让动画自动适应标签大小
//胜利动画
winMovie.setFileName(":/new/prefix1/image/win.gif");
ui->label_win->setMovie(&winMovie);
ui->label_win->setScaledContents(true); //启动游戏
connect(ui->pushButton_enter, &QPushButton::clicked, this, &Widget::on_PushButtonStart_clicked);
//退出游戏
connect(ui->pushButton_quit, &QPushButton::clicked, this, &Widget::close);
//删除前一个数字
connect(ui->pushButton_rollback, &QPushButton::clicked, this, &Widget::on_PushButtonRollback_clicked);
//提示
connect(ui->pushButton_notice, &QPushButton::clicked, this, &Widget::on_PushButtonNotice_clicked); //对数字按钮的处理使用同一个槽函数
connect(ui->pushButton_0, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_1, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_2, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_3, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_4, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_5, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_6, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_7, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_8, &QPushButton::clicked, this, &Widget::dealNum);
connect(ui->pushButton_9, &QPushButton::clicked, this, &Widget::dealNum);
} void Widget::on_PushButtonStart_clicked()
{
//获取下拉框时间,并将字符串转换为整数
gameTime = ui->comboBox->currentText().toInt();
qDebug() << gameTime << "s"; //切换到游戏界面
ui->stackedWidget->setCurrentWidget(ui->pageGame); int num;
//从0时0分0秒到现在的秒数为种子
qsrand(QTime(, , ).secsTo(QTime::currentTime()));
//调用全局的qsrand()函数生成随机数,对10000取余,保证位于10000的范围内
while((num = qrand()%) < );
randStr = QString::number(num);
qDebug() << "randNum" << randStr; //设置进度条
ui->progressBar->setMinimum(); //最小值
ui->progressBar->setMaximum(gameTime); //最大值
ui->progressBar->setValue(gameTime); //当前值 //启动定时器
gameTimerId = startTimer(); //以1000ms为间隔
resultStr.clear();
ui->textEdit->clear();
} void Widget::on_PushButtonRollback_clicked()
{
//退格按钮,删除最后一个数字
if(resultStr.size() == ) {
resultStr.clear();
ui->textEdit->clear();
} else {
resultStr.chop(); //截断最后一位字符
ui->textEdit->setText(resultStr);
}
} void Widget::on_PushButtonNotice_clicked()
{
//提示
resultStr.clear();
QString str = "正确答案为:" + randStr;
ui->textEdit->setText(str);
} void Widget::timerEvent(QTimerEvent *event)
{
if(event->timerId() == gameTimerId) { //游戏时间
gameTime--;
//设置进度条
ui->progressBar->setValue(gameTime); //当前值
//时间到
if( == gameTime) {
//关闭定时器
killTimer(gameTimerId);
QMessageBox::information(this, "失败", "时间到了啊!!!");
loseMovie.start();//启动动画
//切换失败动画页面
ui->stackedWidget->setCurrentWidget(ui->pageLose);
loseTimerId = startTimer(); //启动定时器
}
} else if(event->timerId() == loseTimerId) { //失败动画时间
//停止动画,停止定时器,回到游戏设置页面
loseMovie.stop();//停止动画
killTimer(loseTimerId); //停止定时器
//切换到游戏设置页面
ui->stackedWidget->setCurrentWidget(ui->pageSet);
} else if(event->timerId() == winTimerId) { //胜利动画时间
winMovie.stop();//停止动画
killTimer(winTimerId); //停止定时器
//切换到游戏设置页面
ui->stackedWidget->setCurrentWidget(ui->pageSet);
}
} void Widget::dealNum()
{
//获取信号发送者
QObject *mysender = sender();
//转换为按钮类型
QPushButton *pb = (QPushButton *)mysender;
if (NULL != pb) {
//获取按钮内容
QString numStr = pb->text();
resultStr += numStr;
//数字不能以0开始
if (resultStr.size() == && resultStr=="") {
resultStr.clear();
}
//保证显示结果为4位
if(resultStr.size() <= ) {
ui->textEdit->setText(resultStr);
if (resultStr.size() == ) {
if (resultStr > randStr) {
ui->textEdit->append("数字大了点!!!");
} else if (resultStr < randStr) {
ui->textEdit->append("数字小了点!!!");
} else {
ui->textEdit->append("恭喜你答对了!!!");
//停止定时器
killTimer(gameTimerId);
QMessageBox::information(this, "胜利", "恭喜你!!!");
//启动win页面
winMovie.start();
ui->stackedWidget->setCurrentWidget(ui->pageWin);
//启动定时器
winTimerId = startTimer(); //5s
}
//初始化字符串结果,清空
resultStr.clear();
}
}
}
} Widget::~Widget()
{
delete ui;
}
4 总结
主要有以下问题可能实现的时候会遇到:
(1)布局
布局这个确实不好弄,我也不太熟悉,当布局时最好先把相关联的组件放在一个Widget里面布好局之后,再进行全体布局。
(2)按钮的字体设置在QWidget类里面,而不是在QAbstractButton里。
(3)代码中,定时器我们是使用的定时器事件处理函数timerEvent()来做的,而不是信号与槽。
如果代码中还有其它问题,希望网友指出来。
Demo_2:Qt实现猜字小游戏的更多相关文章
- LY.猜字小游戏
猜字小游戏
- python -猜字小游戏
代码运行效果如下: 注意: 1.必须要在python3环境想使用 2.QQ:3084276329(一起交流学习) 3.还请大家评论 Guess the word game代码如下: #! /usr/b ...
- day06-java-(方法,猜字符小游戏)
day05-java-(方法,猜字符小游戏) 1.方法: 1)用于封装一段特定的逻辑功能 2)方法应尽可能的独立,只干一件事 3)方法可以被反复的调用多次 4)避免代码重复,有利于代码的维护, ...
- Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例
1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...
- java猜数字小游戏
/* * * 猜数字小游戏 * * 先由系统生成一个2-100之间的随机数字, * * 然后捕获用户从控制台中输入的数字是否与系统生成的随机数字相同, * * 如果相同则统计用户所猜的次数,并给出相应 ...
- 简单的C语言猜数字小游戏
猜数字小游戏可谓是C语言最为基础的一个知识点了,我们可以在此基础上进行延伸,实现随机数的猜测,然后是加入再来一局的模式,等等.这里是抛砖引玉,希望你能做出你的经典之作. #include <st ...
- 常用Java API之Ramdom--用代码模拟猜数小游戏
常用Java API之Ramdom Ramdom类用来生成随机数字.使用起来也是三个步骤: 1.导包 import java.util.Random; 2.创建 Random r = new Rand ...
- [Python3 练习] 007 简单的猜数字小游戏
题目:简单的猜数字小游戏 (1) 描述 程序随机生成一个数字,玩家用键盘输入所猜数字,在规定次数内猜对为胜. (2) 要求 程序随机生成一个 1 到 100 的自然数 有 7 次机会去猜 机会用尽之前 ...
- Java数组重修,猜数小游戏改进和打印正三角形
数组重修,猜数小游戏 要求:从键盘输入一个数,判断数组是否包含此数,运用随机数 我们可能会这样写 import java.util.Random; import java.util.Scanner; ...
随机推荐
- Java中那些烦人的位运算(&,|...)
& 和 && 相同点: 都表示"与"操作.这里的"与"和数学中的"与或非"中的"与"意义相同,都 ...
- Java实现 LeetCode 109 有序链表转换二叉搜索树
109. 有序链表转换二叉搜索树 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. ...
- Java实现 LeetCode 16 最接近的三数之和
16. 最接近的三数之和 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存 ...
- java实现排列序数
X星系的某次考古活动发现了史前智能痕迹. 这是一些用来计数的符号,经过分析它的计数规律如下: (为了表示方便,我们把这些奇怪的符号用a~q代替) abcdefghijklmnopq 表示0 abcde ...
- java实现第七届蓝桥杯生日蜡烛
生日蜡烛 生日蜡烛 某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛. 现在算起来,他一共吹熄了236根蜡烛. 请问,他从多少岁开始过生日party的? 请填写他开始过 ...
- 手把手教你用redis实现一个简单的mq消息队列(java)
众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...
- 区分http请求状态码来理解缓存(协商缓存和强制缓存)
什么是http缓存呢,当我们使用chrome浏览器,按F12打开控制台,在网络请求中有时候看到状态码是200,有时候状态码是304,当我们去看这种请求的时候,我们会发现状态码为304的状态结果是:St ...
- vue2.0 + Element UI + axios实现表格分页
注:本文分页组件用原生 html + css 实现,element-ui里有专门的分页组件可以不用自己写,详情见另一篇博客:https://www.cnblogs.com/zdd2017/p/1115 ...
- Java并发相关知识点梳理和研究
1. 知识点思维导图 (图比较大,可以右键在新窗口打开) 2. 经典的wait()/notify()/notifyAll()实现生产者/消费者编程范式深入分析 & synchronized 注 ...
- 2w字长文!手撸一套 Java 基础面试题
Java 基础篇 Java 有哪些特点 并发性的: 你可以在其中执行许多语句,而不必一次执行它 面向对象的:基于类和面向对象的编程语言. 独立性的: 支持一次编写,到处运行的独立编程语言,即编译后的代 ...