qt实现拖拽形状匹配小游戏

本文介绍如何使用C++在VS2017环境下开发一款带有语音指导的游戏,玩家需匹配图形并听从提示。游戏包含计分系统,分数保存于output文件夹。开发过程中涉及预设编号判断、拖拽操作与错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发环境:VS2017,qt5.9.8
开发语言:c++

实现目标:(效果图如下)
1.游戏目标:播放游戏规则语音,语言结束后玩家可以从右边选择和左边轮廓相似的图形;
  并将右边图形拖拽到左边相应位置上即为匹配成功。如果匹配错误,或者拖拽中途松开鼠标,图片回到原来的位置。根据操作会有相关语音提示。
  最右边栏记录时间、分数,并提供刷新按钮可以重置页面。
  游戏内将玩家游戏分数保存在output文件夹下进行简单记录。

2. 匹配过程思路:预先将图片编号,后续根据编号判断是否匹配,将匹配过程分解成三个动作
2.1 鼠标按下动作:记录此时被点击的图片序号
2.2 鼠标拖拽动作:将步骤1记录下的图片,不断更新位置Pos信息,Pos信息为当前鼠标在的位置
2.3 鼠标释放动作:判断释放的鼠标位置在不在左边图片范围内,不在的话就直接将图片复位。在的话,判断拖拽的图片序号和鼠标释放位置图片序号是否可以匹配,进行下一步操作。

在这里插入图片描述项目创建方式参考打地鼠游戏:打地鼠游戏简单实现
本小游戏下载地址:项目代码下载

项目下载以后应该主要需要修改项目的vc++目录和qt版本。
右击项目名称,进入属性页
1.修改VC++目录中include和lib内容,为自己电脑上qt的安装包内include和lib包的位置
2. 修改qt versions 为自己配置的qt版本

在这里插入图片描述在这里插入图片描述

1.鼠标按下动作


void MacthPic::mousePressEvent(QMouseEvent *event)
{
	 if (isBegin == 0) {
		 return;
	 }
	//QLabel* btn = static_cast<QLabel*>(childAt(pos));
	if (m_bIsMoving != -1)
	{
		return;
	}
	QLabel* lab = static_cast<QLabel *>(childAt(event->pos()));
	if (!lab)
	{
		return;
	}
	if (m_labChild.contains(lab))//&&!m_labChild.indexOf(lab))
	{
		int index = m_labChild.indexOf(lab);
		if (!m_stateChild[index])
		{
			m_labChild[index]->raise();
			m_posOriset = lab->pos(); //原来的点
			m_posOffset = event->pos() - lab->pos();
			m_bIsMoving = m_labChild.indexOf(lab);  //记录在动的是哪个
		}
		else
		{
			return;
		}
	}	
	//qDebug() << m_posOriset;
}
  1. 鼠标移动动作
void MacthPic::mouseMoveEvent(QMouseEvent *event)
{
	if (isBegin == 0) {
		return;
	}
	if (m_bIsRunning == 1 && m_bIsMoving != -1)
	{
		//qDebug() << "move";
		QPoint pos = event->pos();
		int x = pos.x()- m_posOffset.x();
		int y = pos.y()- m_posOffset.y();
		m_labChild[m_bIsMoving]->move(x, y);
	}
	else
	{
		return;
	}
}
  1. 鼠标释放动作

void MacthPic::mouseReleaseEvent(QMouseEvent *event)
{
	if (isBegin == 0) {
		return;
	}
	if (m_bIsRunning == 1 && m_bIsMoving != -1)
	{
		QPoint offset;
		int    index;
		offset = m_posOffset;
		index = m_bIsMoving;
		//判断child与mother Flag是否对应
		for (int i = 0; i < 8; i++)
		{
			if (index < 4) {
				if (isRectInside(event->pos(), rectMother[index])) {
					if (rectMother[i].contains(event->pos()))
					{
						if (i == index) { //如果移动到了对应的区域
							//替换掉轮廓
							qDebug() << index + "   111";
							m_stateChild[i] = 1;
							m_labChild[index]->hide();
							m_labChild[index]->update();

							m_labParent[index]->setPixmap(m_imgChild[index]);
							m_score++;
							emit setScore(m_score);
							beginSound("checked");
							sum++;
							break;

						}
						else {
							qDebug() << index + "   222";
							if (!m_stateChild[i]) {
								m_labChild[i]->move(pointChild[i]);
								beginSound("error");
							}
							//m_labChild[index]->move(pointChild[index]);
						}
					}
					else
					{
						/*if (!m_stateChild[i]) {
							m_labChild[i]->move(pointChild[i]);
							beginSound("error");
						}
						qDebug() << index + "   333";*/
					}
				}
				else {
					qDebug() << index + "   444";
					if (!m_stateChild[i]) {
						m_labChild[i]->move(pointChild[i]);
						beginSound("error");
					}
				}
			}					
			else {			
				qDebug() << index + "   444";
				if (!m_stateChild[i]) {
					m_labChild[i]->move(pointChild[i]);
					beginSound("error");
				}
			}
		}		
		m_bIsMoving = -1;
	}
	else
	{
		event->ignore();
	}
	if (sum >= 4 && m_bIsRunning==1) {  //sum应该就是最终得分
		m_bIsRunning = -1;
		beginSound("success");
		PauseTiming();  //记录总用时
		beginTime->stop();
		QObject::disconnect(beginTime, SIGNAL(timeout()), this, SLOT(nowTimeOver()));
		OnSaveData();
		hideGame();
		//得到最终分以后 输出数据。
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值