523 lines
16 KiB
C++
523 lines
16 KiB
C++
|
#include "gamecontrol.h"
|
||
|
#include <QFile>
|
||
|
#include <QTextStream>
|
||
|
#include "readconfig.h"
|
||
|
#include <QDebug>
|
||
|
#include <QJsonDocument>
|
||
|
#include <QJsonObject>
|
||
|
#include <QJsonParseError>
|
||
|
#include <QDateTime>
|
||
|
#include "currentuserdata.h"
|
||
|
#include "cdatabaseinterface.h"
|
||
|
#include <QTimer>
|
||
|
|
||
|
//LOG4QT_DECLARE_STATIC_LOGGER(logger, GameControl)
|
||
|
|
||
|
GameControl* GameControl::m_GameParamControl = NULL;
|
||
|
|
||
|
GameControl::GameControl(QWidget *parent)
|
||
|
: QWidget(parent),
|
||
|
m_gameSocket(NULL),
|
||
|
// m_waitingDialog(NULL),
|
||
|
m_trainReport(NULL),
|
||
|
waitTimer(NULL),
|
||
|
m_activeMaxAngle(0),
|
||
|
m_activeMinAngle(0),
|
||
|
currentGameID(0)
|
||
|
{
|
||
|
m_Process = new QProcess();
|
||
|
// initGameSocket();
|
||
|
// m_waitingDialog = new WaitingDialog();
|
||
|
// m_waitingDialog->setWaitingType(INITWAITING);
|
||
|
m_trainReport = new TrainReport();
|
||
|
|
||
|
waitTimer = new QTimer();
|
||
|
waitTimer->setInterval(500);
|
||
|
waitTimer->setSingleShot(true);
|
||
|
connect(waitTimer,SIGNAL(timeout()),this,SLOT(slotWaitTimer()));
|
||
|
|
||
|
player = new QMediaPlayer();
|
||
|
}
|
||
|
|
||
|
GameControl::~GameControl()
|
||
|
{
|
||
|
if(m_trainReport)
|
||
|
{
|
||
|
delete m_trainReport;
|
||
|
}
|
||
|
if(waitTimer)
|
||
|
{
|
||
|
delete waitTimer;
|
||
|
}
|
||
|
if(player)
|
||
|
{
|
||
|
delete player;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void GameControl::initGameSocket()
|
||
|
{
|
||
|
m_gameSocket = new QUdpSocket();
|
||
|
int16_t port;
|
||
|
QString IP;
|
||
|
ReadConfig::getInstance()->getGameServerAddress(port,IP);
|
||
|
if(m_gameSocket->bind(port))
|
||
|
{
|
||
|
qDebug()<<(QString("游戏服务端口%1").arg(port));
|
||
|
}
|
||
|
connect(m_gameSocket,&QUdpSocket::readyRead,this,&GameControl::slotReceiveGameData);
|
||
|
}
|
||
|
|
||
|
GameControl* GameControl::getInstance()
|
||
|
{
|
||
|
if(!m_GameParamControl)
|
||
|
{
|
||
|
m_GameParamControl = new GameControl();
|
||
|
}
|
||
|
return m_GameParamControl;
|
||
|
}
|
||
|
|
||
|
void GameControl::updateXml(ST_GameParam& st_GameParam)
|
||
|
{
|
||
|
QFile file("./gameExecutable/gameConfig.xml");
|
||
|
if(!file.open(QFile::ReadOnly))
|
||
|
return;
|
||
|
QDomDocument doc;
|
||
|
|
||
|
if(!doc.setContent(&file))
|
||
|
{
|
||
|
file.close();
|
||
|
return;
|
||
|
}
|
||
|
file.close();
|
||
|
|
||
|
QDomElement root = doc.documentElement();
|
||
|
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList timeList = root.elementsByTagName("GameTime");
|
||
|
QDomNode timeNode = timeList.at(0);
|
||
|
QDomNode oldnode=timeNode.firstChild();
|
||
|
timeNode.firstChild().setNodeValue(QString::number(st_GameParam.gameTime));
|
||
|
QDomNode newNode = timeNode.firstChild();
|
||
|
timeNode.replaceChild(newNode,oldnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList levelList = root.elementsByTagName("Level");
|
||
|
QDomNode levelNode = levelList.at(0);
|
||
|
QDomNode oldLevelnode=levelNode.firstChild();
|
||
|
levelNode.firstChild().setNodeValue(QString::number(st_GameParam.hardLevel));
|
||
|
QDomNode newLevelNode = levelNode.firstChild();
|
||
|
levelNode.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("Speed");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
node.firstChild().setNodeValue(QString::number(st_GameParam.speed));
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("TrainType");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
node.firstChild().setNodeValue(QString::number(st_GameParam.trainType));
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("AngleVlue");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
node.firstChild().setNodeValue(QString::number(st_GameParam.angleValue));
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("WaitTime");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
node.firstChild().setNodeValue(QString::number(st_GameParam.waitTime));
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("MaxCircle");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
node.firstChild().setNodeValue(QString::number(st_GameParam.maxCircle));
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
if(1)
|
||
|
{
|
||
|
QDomNodeList List = root.elementsByTagName("ReadPosTable");
|
||
|
QDomNode node = List.at(0);
|
||
|
QDomNode oldLevelnode=node.firstChild();
|
||
|
QString ok("false");
|
||
|
if(st_GameParam.readPosTable)
|
||
|
ok = "true";
|
||
|
else
|
||
|
ok = "false";
|
||
|
node.firstChild().setNodeValue(ok);
|
||
|
QDomNode newLevelNode = node.firstChild();
|
||
|
node.replaceChild(newLevelNode,oldLevelnode);
|
||
|
}
|
||
|
|
||
|
QDomNode n = root.firstChild();
|
||
|
while(!n.isNull())
|
||
|
{
|
||
|
QDomElement e = n.toElement();
|
||
|
if(!e.isNull())
|
||
|
{
|
||
|
if(e.tagName() == "TrainingTrack")
|
||
|
{
|
||
|
e.setAttribute("path",st_GameParam.trainTrackFilePath);
|
||
|
}
|
||
|
}
|
||
|
n = n.nextSibling();
|
||
|
}
|
||
|
|
||
|
if(!file.open(QFile::WriteOnly|QFile::Truncate))
|
||
|
return;
|
||
|
//输出到文件
|
||
|
QTextStream out_stream(&file);
|
||
|
doc.save(out_stream,4); //缩进4格
|
||
|
file.close();
|
||
|
}
|
||
|
|
||
|
void GameControl::setGamParam(ST_GameParam& st_GameParam)
|
||
|
{
|
||
|
//将本地参数转化成游戏中用到的参数
|
||
|
if(5 == st_GameParam.trainType)
|
||
|
st_GameParam.trainType = 1;
|
||
|
if(6 == st_GameParam.trainType)
|
||
|
st_GameParam.trainType = 2;
|
||
|
updateXml(st_GameParam);
|
||
|
}
|
||
|
|
||
|
void GameControl::readGameConfigMsg()
|
||
|
{
|
||
|
QList<ST_GameMsg> gameMsgList;
|
||
|
QFile file("./DependFile/ConfigFile/gameListConfig.xml");
|
||
|
|
||
|
if(!file.open(QIODevice::ReadOnly))
|
||
|
{
|
||
|
qDebug()<<"read gameListConfig failed";
|
||
|
return ;
|
||
|
}
|
||
|
QDomDocument doc;
|
||
|
QString error;
|
||
|
int row,colum;
|
||
|
if(!doc.setContent(&file,&error,&row,&colum))
|
||
|
{
|
||
|
qDebug()<<"gameList error"<<error<<row<<colum;
|
||
|
file.close();
|
||
|
return ;
|
||
|
}
|
||
|
file.close();
|
||
|
|
||
|
QDomElement root=doc.documentElement(); //返回根节点
|
||
|
|
||
|
QDomNode node=root.firstChild(); //获得第一个子节点
|
||
|
|
||
|
while(!node.isNull())
|
||
|
{
|
||
|
if(node.isElement()) //如果节点是元素
|
||
|
{
|
||
|
ST_GameMsg st_GameMsg;
|
||
|
QDomElement e=node.toElement();
|
||
|
st_GameMsg.gameID = e.attribute("ID").toInt();
|
||
|
st_GameMsg.gameName = e.attribute("gameName");
|
||
|
st_GameMsg.gamePath = e.attribute("path");
|
||
|
st_GameMsg.iconPath = e.attribute("iconPath");
|
||
|
st_GameMsg.className = e.attribute("className");
|
||
|
st_GameMsg.windownName = e.attribute("windownName");
|
||
|
gameMsgList.append(st_GameMsg);
|
||
|
m_mapGameName.insert(st_GameMsg.gameID,st_GameMsg);
|
||
|
}
|
||
|
node = node.nextSibling();
|
||
|
}
|
||
|
|
||
|
m_gameMsgList = gameMsgList;
|
||
|
}
|
||
|
|
||
|
QList<ST_GameMsg> GameControl::getGameMsgs()
|
||
|
{
|
||
|
return m_gameMsgList;
|
||
|
}
|
||
|
|
||
|
ST_GameMsg GameControl::getGameMsgByName(int ID)
|
||
|
{
|
||
|
ST_GameMsg st_gameMsg;
|
||
|
QMapIterator<int, ST_GameMsg> i(m_mapGameName);
|
||
|
|
||
|
while(i.hasNext())
|
||
|
{
|
||
|
i.next();
|
||
|
}
|
||
|
|
||
|
if(m_mapGameName.contains(ID))
|
||
|
{
|
||
|
st_gameMsg = m_mapGameName.value(ID);
|
||
|
}
|
||
|
return st_gameMsg;
|
||
|
}
|
||
|
|
||
|
ST_GameMsg GameControl::getCurrentGameMsg()
|
||
|
{
|
||
|
return getGameMsgByName(currentGameID);
|
||
|
}
|
||
|
|
||
|
void GameControl::startGame(QString path)
|
||
|
{
|
||
|
//1.开启游戏进程
|
||
|
if(path.isEmpty())
|
||
|
return;
|
||
|
QString hardDisk = path.mid(0,2);
|
||
|
hardDisk.append("\n\r");
|
||
|
|
||
|
QString gameName = path.mid(path.lastIndexOf('/')+1);
|
||
|
gameName.prepend("start ");
|
||
|
gameName.append("\n\r");
|
||
|
QString gamePath = path.mid(0,path.lastIndexOf('/'));
|
||
|
gamePath.prepend("cd ");
|
||
|
gamePath.append("\n\r");
|
||
|
m_Process->start("cmd.exe");
|
||
|
//切换盘符
|
||
|
m_Process->write(hardDisk.toLatin1());
|
||
|
//进入文件夹
|
||
|
m_Process->write(gamePath.toLatin1());
|
||
|
//开启进程
|
||
|
m_Process->write(gameName.toLatin1());
|
||
|
m_Process->write("exit\n\r");
|
||
|
m_Process->waitForFinished();
|
||
|
m_Process->close();
|
||
|
//2.关闭设备复位中的界面
|
||
|
}
|
||
|
|
||
|
//游戏数据接收
|
||
|
void GameControl::slotReceiveGameData()
|
||
|
{
|
||
|
while(m_gameSocket->hasPendingDatagrams())
|
||
|
{
|
||
|
QByteArray buf;
|
||
|
buf.resize(m_gameSocket->pendingDatagramSize());
|
||
|
m_gameSocket->readDatagram(buf.data(),buf.size());
|
||
|
// parseGameMsg(buf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***
|
||
|
void GameControl::parseGameMsg(QByteArray jsonArray)
|
||
|
{
|
||
|
QJsonParseError jsonError;
|
||
|
QJsonDocument doucment = QJsonDocument::fromJson(jsonArray, &jsonError); // 转化为 JSON 文档
|
||
|
#if 1
|
||
|
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
|
||
|
{
|
||
|
if(doucment.isObject())
|
||
|
{
|
||
|
QJsonObject object = doucment.object(); // 转化为对象
|
||
|
if(object.contains("msgID"))
|
||
|
{
|
||
|
int msgID = object.value("msgID").toInt();
|
||
|
switch(msgID)
|
||
|
{
|
||
|
case 1: //游戏开始信号
|
||
|
{
|
||
|
m_spasmTimes = 0;
|
||
|
isTraining = true;
|
||
|
waitTimer->start();
|
||
|
st_TrainReport.startTime = QDateTime::currentDateTime();
|
||
|
emit signalGameState(e_TrainMode,GameStart_E);
|
||
|
}
|
||
|
break;
|
||
|
case 2: //游戏给出的目标位置
|
||
|
{
|
||
|
{
|
||
|
if(object.contains("m_xv"))
|
||
|
{
|
||
|
QJsonObject xObject = object.value("m_xv").toObject();
|
||
|
int current = 0;
|
||
|
int max = 1;
|
||
|
if(xObject.contains("current"))
|
||
|
current = xObject.value("current").toInt();
|
||
|
if(xObject.contains("max"))
|
||
|
max = xObject.value("max").toInt();
|
||
|
}
|
||
|
if(object.contains("m_yv"))
|
||
|
{
|
||
|
QJsonObject yObject = object.value("m_yv").toObject();
|
||
|
int current = 0;
|
||
|
int max = 1;
|
||
|
if(yObject.contains("current"))
|
||
|
current = yObject.value("current").toInt();
|
||
|
if(yObject.contains("max"))
|
||
|
max = yObject.value("max").toInt();
|
||
|
}
|
||
|
if(object.contains("tarAngle"))
|
||
|
{
|
||
|
float angle = 0;
|
||
|
angle = object.value("tarAngle").toDouble();
|
||
|
// emit signalSendDestPosition(angle);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
case 3: //结束信息
|
||
|
{
|
||
|
isTraining = false;
|
||
|
if(object.contains("quitType"))
|
||
|
{
|
||
|
//告知下位机训练完成
|
||
|
sendStopCmd();
|
||
|
m_quitType = object.value("quitType").toInt();
|
||
|
//正常退出
|
||
|
if(1 == m_quitType)
|
||
|
{
|
||
|
emit signalGameState(e_TrainMode,GameEnd_E);
|
||
|
st_TrainReport.endTime = QDateTime::currentDateTime();
|
||
|
if(object.contains("totalTime"))
|
||
|
st_TrainReport.duration = object.value("totalTime").toInt();
|
||
|
if(object.contains("totalScore"))
|
||
|
st_TrainReport.score = object.value("totalScore").toInt();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
emit signalGameState(e_TrainMode,GameEnd_E);
|
||
|
st_TrainReport.endTime = QDateTime::currentDateTime();
|
||
|
if(object.contains("totalTime"))
|
||
|
st_TrainReport.duration = object.value("totalTime").toInt();
|
||
|
if(object.contains("totalScore"))
|
||
|
st_TrainReport.score = object.value("totalScore").toInt();
|
||
|
}
|
||
|
//生成训练报告
|
||
|
createTrainReport();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// logger()->debug(jsonError.errorString());
|
||
|
//此处不该在此处停止心跳
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
***/
|
||
|
void GameControl::createTrainReport()
|
||
|
{
|
||
|
/***
|
||
|
ST_PatientMsg st_currentPatient = CurrentUserData::getInstace()->getCurrentPatientMsg();
|
||
|
st_TrainReport.ID = st_currentPatient.ID;
|
||
|
st_TrainReport.name = st_currentPatient.name;
|
||
|
|
||
|
//从数据库中查询总时间
|
||
|
int lastTotalDuration;
|
||
|
QString query("select * from TrainReport order by startTime DESC;");
|
||
|
if(!CDatabaseInterface::getInstance()->exec(query))
|
||
|
qDebug()<<CDatabaseInterface::getInstance()->getLastError()<<"ERROR";
|
||
|
int count = CDatabaseInterface::getInstance()->getValuesSize();
|
||
|
if(count >0)
|
||
|
{
|
||
|
QList<QVariantMap> maplist = CDatabaseInterface::getInstance()->getValues(0,1);
|
||
|
ST_TrainReport st_trainReport = variantMapToTrainReport(maplist.at(0));
|
||
|
lastTotalDuration = st_trainReport.totalDuration;
|
||
|
st_TrainReport.totalDuration = lastTotalDuration + st_TrainReport.duration;
|
||
|
}
|
||
|
st_TrainReport.level = 1;
|
||
|
if(0 == st_TrainReport.trainMode)
|
||
|
m_trainReport->setReportType(tr("被动训练报告"));
|
||
|
else if(1 == st_TrainReport.trainMode)
|
||
|
m_trainReport->setReportType(tr("主动训练报告"));
|
||
|
***/
|
||
|
m_trainReport->setReportData(st_TrainReport,1);
|
||
|
}
|
||
|
|
||
|
void GameControl::sendStopCmd()
|
||
|
{
|
||
|
QJsonObject object;
|
||
|
object.insert("msgID",2);
|
||
|
object.insert("GameState",0);
|
||
|
QJsonDocument document;
|
||
|
document.setObject(object);
|
||
|
QByteArray sendArray = document.toJson();
|
||
|
QString ip("127.0.0.1");
|
||
|
int16_t port = 12000;
|
||
|
for(int i = 0;i < 5;i++)
|
||
|
{
|
||
|
m_gameSocket->writeDatagram(sendArray,QHostAddress(ip),port);
|
||
|
Sleep(100);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void GameControl::setTrainParam(ST_TrainParam &st_TrainParam)
|
||
|
{
|
||
|
m_st_TrainParam = st_TrainParam;
|
||
|
}
|
||
|
|
||
|
ST_TrainParam GameControl::getTrainParam()
|
||
|
{
|
||
|
return m_st_TrainParam;
|
||
|
}
|
||
|
|
||
|
//游戏界面关闭时间
|
||
|
void GameControl::slotWaitTimer()
|
||
|
{
|
||
|
//关闭等待界面
|
||
|
// m_waitingDialog->setDialogCloseState(true);
|
||
|
}
|
||
|
|
||
|
//关闭游戏
|
||
|
void GameControl::stopGame()
|
||
|
{
|
||
|
sendStopCmd();
|
||
|
}
|
||
|
|
||
|
void GameControl::sendGameControlData(const ST_GameControlParam &st_gameControlParam)
|
||
|
{
|
||
|
QJsonObject object;
|
||
|
object.insert("msgID",st_gameControlParam.MsgId);
|
||
|
object.insert("ID",st_gameControlParam.ID);
|
||
|
object.insert("userName",st_gameControlParam.userName);
|
||
|
object.insert("speed",st_gameControlParam.speed);
|
||
|
object.insert("forceLeft",st_gameControlParam.forceLeft);
|
||
|
object.insert("forceRight",st_gameControlParam.forceRight);
|
||
|
object.insert("angle",st_gameControlParam.angle);
|
||
|
|
||
|
QJsonDocument document;
|
||
|
document.setObject(object);
|
||
|
QByteArray sendArray = document.toJson();
|
||
|
}
|
||
|
|
||
|
void GameControl::setCurrentGame(int ID)
|
||
|
{
|
||
|
currentGameID = ID;
|
||
|
}
|
||
|
|
||
|
void GameControl::playTipMusic(QString path)
|
||
|
{
|
||
|
player->setMedia(QUrl::fromLocalFile(path));
|
||
|
player->setVolume(90);
|
||
|
player->play();
|
||
|
}
|
||
|
|
||
|
int GameControl::getCurrentGameID()
|
||
|
{
|
||
|
return currentGameID;
|
||
|
}
|