打字速度小游戏 多线程
Qt5.9环境
源代码mainscence.h
#include <QWidget>
#include"movetext.h"
#include"config.h"
class MainScence : public QWidget
{
Q_OBJECT
public:
MainScence(QWidget *parent = 0);
~MainScence();
//初始化
void init();
//获取单词
void getWord();
//更新单词表
void updateWords(int i);
//开始界面
void startScence();
//开始游戏
void playGame();
//更新坐标
void updatePosition();
//单词限制
void limitWords();
//重新画家事件
void paintEvent(QPaintEvent *);
//单词出场
void wordToScence();
//写单词
void writeWord();
//计时器
void timeShow();
void timerEvent(QTimerEvent *);
int t;
QLabel *label;
QLabel *label_2;
//背景
BackGround bg;
//开始按钮
QPushButton *btn;
//单词数组
MoveText words[WORD_NUM];
//单词记录
int word_record;
//定时器对象
QTimer timer;
//单词文件
QString path;
//QList
//QList<QString> list;
//排重
int rand1;
int temp;
//单词列表
//QList<wordlist> list;
QVector<wordlist> vec;
QVector<wordlist> vec1;
//单词数量
int num;
//错过单词数
int miss_num;
QLabel *label_3;
QLabel *label_4;
//屏幕中有的单词
int show_words_num;
//限制单词数量
int limit_show_words_num;
//线程锁
QMutex mutex;
};
mainscence.cpp
#include "mainscence.h"
MainScence::MainScence(QWidget *parent)
: QWidget(parent)
{
//初始化
init();
//获取单词
//getWord();
startScence();
//开始游戏
//playGame();
//输入
writeWord();
}
MainScence::~MainScence()
{
}
void MainScence::init()
{
//窗口设置
this->setFixedSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
this->setWindowTitle("handspeed");
this->setWindowIcon(QIcon(":/res/W.ico"));
QPalette palette(this->palette());
palette.setColor(QPalette::Background,QColor(51,51,51));
this->setPalette(palette);
//分隔线
QFrame *line = new QFrame(this);
line->setObjectName(QString::fromUtf8("line"));
line->setGeometry(QRect(0, WINDOWS_HEIGHT-60, WINDOWS_WIDTH, 1));
line->setStyleSheet("QFrame{background-color:gray}");
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
//间隔
timer.setInterval(GAME_RATE);
word_record=0;
//随机种子
srand((unsigned int)time(NULL));
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
rand1=0;
temp=0;
//初始化单词数量
num=0;
//初始化
miss_num=0;
//miss单词数
//屏幕中有的单词
show_words_num=0;
//限制单词数量
limit_show_words_num=21;
QtConcurrent::run([=](){
//qDebug()<<"mythread:"<<QThread::currentThread();
mutex.lock();
getWord();
mutex.unlock();
});
}
void MainScence::getWord()
{
path=FILE_PATH;
//子线程随机种子
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
QFile file(path);
if(!file.open(QIODevice::ReadOnly))
{
qDebug()<<file.errorString();
}
for(int i=0;!file.atEnd();i++){
QString str;
wordlist wl;
str=file.readLine();
str=str.trimmed();
wl.flag=true;
wl.str=str;
vec.append(wl);
}
file.close();
for(int i=0;i<WORD_NUM;i++){
int rand2=qrand()%vec.size();
words[i].word=vec.at(rand2).str;
wordlist wl;
wl.str=vec.at(rand2).str;
wl.flag=false;
vec.replace(i,wl);
//qDebug()<<rand2;
}
}
void MainScence::playGame()
{
//计时器
timeShow();
//启动定时器
timer.start();
//监听定时器的信号
connect(&timer,&QTimer::timeout,[=](){
//单词滚动
wordToScence();
//更新位置
updatePosition();
//更新
update();
});
}
void MainScence::updateWords(int i)
{
for(int j=0;j<vec.size();j++){
int rand2=qrand()%vec.size();
if(vec.at(rand2).flag){
words[i].word=vec.at(rand2).str;
wordlist wl;
wl.str=vec.at(rand2).str;
wl.flag=false;
vec.replace(rand2,wl);
break;
}
else continue;
}
}
void MainScence::startScence()
{
btn=new QPushButton(this);
btn->setFixedSize(200,50);
btn->move((this->width()-btn->width())*0.5,(this->height()-btn->height())*0.5);
btn->setText("开始");
btn->setFont(QFont("consolas",14,QFont::Normal));
btn->setFocus();
btn->setDefault(true);
//btn->setStyleSheet("background-color: rgb(51, 51, 51);");
connect(btn,&QPushButton::clicked,[=](){
btn->hide();
timeShow();
playGame();
});
}
void MainScence::updatePosition()
{
for(int i=0;i<WORD_NUM /*&& miss_num < 10*/;i++){
if(words[i].flag==false){
words[i].updatePosition();
if(words[i].x>WINDOWS_WIDTH){
miss_num++;
words[i].flag=true;
show_words_num--;
//更新单词
updateWords(i);
label_4->setText(QString::number(miss_num));
qDebug()<<miss_num;
}
}
}
}
void MainScence::limitWords()
{
if(t<30&&num<3){
limit_show_words_num=21;
timer.setInterval(GAME_RATE-5);
}
else if((t>=30&&t<60)||(num>=3&&num<8)){
limit_show_words_num=20;
timer.setInterval(GAME_RATE-2);
}
else if((t>=60&&t<120)||(num>=8 && num<=20)){
limit_show_words_num=19;
timer.setInterval(GAME_RATE-3);
}
else if((t>=120&&t<240)||(num>20&&num<=30)){
limit_show_words_num=18;
timer.setInterval(GAME_RATE-5);
}
else if((t>=240&&t<480)||(num>30&&num<=60)){
limit_show_words_num=17;
timer.setInterval(GAME_RATE-6);
}
else{
limit_show_words_num=0;
timer.setInterval(GAME_RATE-8);
}
}
void MainScence::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pen;
QFont font("consolas",13,QFont::Thin);
painter.setFont(font);
for(int i=0;i<WORD_NUM;i++){
if(words[i].flag==false){
if(words[i].x<=WINDOWS_WIDTH-400)
{
pen.setColor(QColor(0,255,0));
painter.setPen(pen);
painter.drawText(words[i].x,words[i].y,words[i].word);
}
if(words[i].x>WINDOWS_WIDTH-400 && words[i].x<=WINDOWS_WIDTH-200)
{
pen.setColor(QColor(255,187,97));
painter.setPen(pen);
painter.drawText(words[i].x,words[i].y,words[i].word);
}
if(words[i].x>WINDOWS_WIDTH-200){
pen.setColor(QColor(255,0,0));
painter.setPen(pen);
painter.drawText(words[i].x,words[i].y,words[i].word);
}
}
}
}
void MainScence::wordToScence()
{
word_record++;
if(word_record<(20+temp)){
return;
}
temp=qrand()%80;
word_record=0;
limitWords();
for(int i=0;i<WORD_NUM-limit_show_words_num;i++){
if(words[i].flag){
words[i].flag=false;
show_words_num++;
words[i].x=WORD_POSITION_X;
words[i].y=qrand()%(WINDOWS_HEIGHT-150)+20;
while(words[i].y<(rand1+20)&&words[i].y>(rand1-20)){
words[i].y=qrand()%(WINDOWS_HEIGHT-150)+10;
}
rand1=words[i].y;
break;
}
}
}
void MainScence::writeWord()
{
QLineEdit *lineEdit=new QLineEdit(this);
lineEdit->move(10,WINDOWS_HEIGHT-50);
lineEdit->setFixedSize(200,40);
lineEdit->setFocus();
lineEdit->setFont(QFont("consolas",14,QFont::Light));
lineEdit->setStyleSheet("QLineEdit{border-width:0;"
"border-style:outset;"
"background-color:rgba(51,51,51,255);"
"color:white}");
connect(lineEdit,&QLineEdit::returnPressed,[=](){
//qDebug()<<lineEdit->text();
for(int i=0;i<WORD_NUM;i++){
if(words[i].flag==false){
if(lineEdit->text()==words[i].word){
words[i].flag=true;
num++;
show_words_num--;
//更新单词
updateWords(i);
//qDebug()<<num;
}
}
}
lineEdit->clear();
});
}
void MainScence::timeShow()
{
//时间
t=0;
QPalette pe;
pe.setColor(QPalette::WindowText,QColor(0,255,255));
QPalette pe1;
pe1.setColor(QPalette::WindowText,QColor(255,255,255));
label=new QLabel(this);
label->move(220,WINDOWS_HEIGHT-40);
label->setText("TIME: ");
label->setPalette(pe1);
label->setFont(QFont("consolas",14,QFont::Bold));
label->adjustSize();
label_2=new QLabel(this);
label_2->move(280,WINDOWS_HEIGHT-40);
label_2->setText("0");
label_2->setPalette(pe);
label_2->setFont(QFont("consolas",14,QFont::Bold));
label_2->setFixedSize(100,20);
label_3=new QLabel(this);
label_3->move(400,WINDOWS_HEIGHT-40);
label_3->setText("MISS: ");
label_3->setPalette(pe1);
label_3->setFont(QFont("consolas",14,QFont::Bold));
label_4=new QLabel(this);
label_4->move(460,WINDOWS_HEIGHT-40);
label_4->setPalette(pe);
label_4->setText("0");
label_4->setFont(QFont("consolas",14,QFont::Bold));
label_4->setFixedSize(100,20);
//时间
startTimer(1000);
}
void MainScence::timerEvent(QTimerEvent *)
{
label_2->setText(QString::number(t++));
}
movetext类头文件
#include<QString>
class MoveText
{
public:
MoveText();
void updatePosition();
QString word;
//位置
int x;
int y;
//状态
bool flag;
//速度
int speed;
};
cpp文件
#include "movetext.h"
MoveText::MoveText()
{
x=0;
y=0;
flag=true;
speed=1;
}
void MoveText::updatePosition()
{
if(flag) return ;
x+=speed;
if(x>600){
//flag=true;
}
}