嵌入式Linux大作业实现.docx
- 文档编号:6367584
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:29
- 大小:209.58KB
嵌入式Linux大作业实现.docx
《嵌入式Linux大作业实现.docx》由会员分享,可在线阅读,更多相关《嵌入式Linux大作业实现.docx(29页珍藏版)》请在冰豆网上搜索。
嵌入式Linux大作业实现
2018-2019学年下学期
《嵌入式Linux应用程序开发》
期末大作业
专业:
软件工程
班级:
1603
学号:
************
*****
*******
成绩:
题目内容:
在Linux下,用qt编程实现一个小游戏,2048.
整体的代码结构如图1:
图1
完成后预览如图2:
图2
游戏主逻辑说明:
1初始生成两个值,要么2,要么4
2移动(上下左右四个方向):
首先,在行/列上找到当前行第一个为空的值,记录下该位置,再往后找到第一个不为空的值,最后将这两个位置交换。
3合并:
1:
在2.移动中,边界值为空当交换后的位置与交换后的位置的前一个位置(简称前一个位置)的值相等,前一个位置值*2,删除要移动的值。
2:
在2.移动中,边界值不为空判断边界值是否与后面第一个不为空的值相等
3:
相等,边界值*2,删除第一个不为空的值
4:
不相等,不做任何操作
4:
游戏结束:
如果出现2048,赢,游戏结束,当方格填满,没有合并项,失败,游戏结束
1.
注:
要记录下该位置在同一回合中是否合并过,避免同一回合多次合并
核心步骤:
1设定背景样式:
voidBGWidget:
:
paintEvent(QPaintEvent*event)
{
QStylePainterpainter(this);
//用style画背景(会使用setstylesheet中的内容)
QStyleOptionopt;
opt.initFrom(this);
opt.rect=rect();
painter.drawPrimitive(QStyle:
:
PE_Widget,opt);
painter.setPen(QColor(204,192,180));
painter.setBrush(QColor(204,192,180));
//4*4的背景矩阵
constintcolWidth=75;
constintrowHeight=75;
constintxOffset=10;
constintyOffset=10;
for(introw=0;row<4;++row)
{
for(intcol=0;col<4;++col)
{
//背景方框
intx=col*colWidth+xOffset;
inty=row*rowHeight+yOffset;
painter.drawRoundRect(x,y,65,65,10,10);
}
}
QWidget:
:
paintEvent(event);
}
2Label类构造:
MyLabel:
:
MyLabel(inttext)
{
this->setText(QString:
:
number(text));
this->setAlignment(Qt:
:
Alignment(Qt:
:
AlignCenter));
this->setFont(QFont("Gadugi",20,QFont:
:
Bold));
//初始化样式
intindex=log_2(text)-1;//计算背景数组索引值
QStringfontColor="color:
rgb(255,255,255);";
if(index<8)
{
fontColor="color:
rgb(119,110,101);";
}
QStringbgColor=QString("QLabel{background-color:
%1;border-radius:
5px;%2}").arg(digitBkg[index]).arg(fontColor);
this->setStyleSheet(bgColor);
//透明度
QGraphicsOpacityEffect*m_pGraphicsOpacityEffect=newQGraphicsOpacityEffect(this);
m_pGraphicsOpacityEffect->setOpacity
(1);
this->setGraphicsEffect(m_pGraphicsOpacityEffect);
//动画让label慢慢出现
QPropertyAnimation*animation=newQPropertyAnimation(m_pGraphicsOpacityEffect,"opacity",this);
animation->setEasingCurve(QEasingCurve:
:
Linear);
animation->setDuration(400);
animation->setStartValue(0);
animation->setEndValue
(1);
animation->start(QAbstractAnimation:
:
KeepWhenStopped);
}
voidMyLabel:
:
reSetText(inttext)
{
this->setText(QString:
:
number(text));
intindex=log_2(text)-1;//计算背景数组索引值
QStringfontColor="color:
rgb(255,255,255);";
if(index<8)
{
fontColor="color:
rgb(119,110,101);";
}
QStringbgColor=QString("QLabel{background-color:
%1;border-radius:
5px;%2}").arg(digitBkg[index]).arg(fontColor);
this->setStyleSheet(bgColor);
this->show();
this->repaint();
}
这里,ui就不贴出了,见源代码。
3游戏主逻辑的设计与实现
//初始化
voidGameWidget:
:
initGame()
{
//初始化分数为0
m_score=0;
m_highScore=0;
//初始化
for(introw=0;row<4;++row)
{
for(intcol=0;col<4;++col)
{
labels[row][col]=NULL;
}
}
//读取文件,最高分设置
//ReadOnly文件不存在,打开失败
//WriteOnly文件不存在,会自动创建文件
//ReadWrite文件不存在,会自动创建文件
//Append文件不存在,会自动创建文件
//Truncate文件不存在,打开失败
//Text文件不存在,打开失败
//Unbuffered文件不存在,打开失败
QFile*file=newQFile("data.json");
if(file->open(QIODevice:
:
ReadOnly))
{
QByteArrayba=file->readAll();
QJsonDocumentd=QJsonDocument:
:
fromJson(ba);
QJsonObjectjson=d.object();
QJsonValuevalue=json.value(QString("m_highScore"));
QJsonValuescore=json.value(QString("m_score"));
//最高分数
m_highScore=value.toVariant().toInt();
this->ui->best_2->setText(QString:
:
number(m_highScore));
//当前分数
m_score=score.toVariant().toInt();
this->ui->score_3->setText(QString:
:
number(m_score));
//文件保存的进度
QJsonValuelabelsArr=json.value(QString("labels"));
QJsonArrayarr=labelsArr.toArray();
for(inti=0;i { QJsonValuelabelValue=arr.at(i); QJsonArrayarr1=labelValue.toArray(); for(intj=0;j { QJsonValuearrValue=arr1.at(j); intoldValue=arrValue.toVariant().toInt(); if(oldValue! =0) { MyLabel*label=newMyLabel(oldValue); intx=j*colWidth+xOffset; inty=i*rowHeight+yOffset; label->setGeometry(x,y,66,66); label->setParent(m_bgWidget); labels[i][j]=label; labels[i][j]->show(); ++m_labelCount; } } } file->close(); //判断读取的文件是否游戏结束 //这里可以不用判断,为了防止游戏在结束的时候程序意外关闭 //gameOver(); } else { //初始化两个标签 for(inti=0;i<2;i++){ createLabel(); } } } 对游戏期间数字相碰的逻辑处理: boolGameWidget: : merge(MyLabel*temp,introw,intcol) { if(temp! =NULL) { //判断两个值是否相等,是合并 if(temp->text()==labels[row][col]->text()) { intx=labels[row][col]->x(); inty=row*rowHeight+yOffset;//y轴偏移 //动画效果 QPropertyAnimation*animation=newQPropertyAnimation(temp,"geometry"); animation->setStartValue(temp->geometry()); animation->setEndValue(QRect(x,y,temp->width(),temp->height())); animation->setDuration(100); animation->setEasingCurve(QEasingCurve: : Linear); animation->start(QAbstractAnimation: : DeleteWhenStopped); intscore=2*labels[row][col]->text().toInt(); labels[row][col]->reSetText(score); m_score+=score; emitScoreChange(); --m_labelCount; returntrue; } } returnfalse; } boolGameWidget: : isMerge() { for(introw=0;row<4;++row) { for(intcol=0;col<4;++col) { if(isMergeDown(row,col)||isMergeRight(row,col)) { returntrue; } } } returnfalse; } 游戏胜利或者失败的判断: boolGameWidget: : gameOver() { boolflag=false; //如果格子全满(m_labelCount==16) if(m_labelCount==16) { boolisWin=isMerge(); if(! isWin){ //没有可以合并的标签,显示失败 QMessageBox: : about(this,"信息","失败! "); flag=true; } } else { //最大数出现2048,则显示胜利 for(introw=0;row<4;++row) { for(intcol=0;col<4;++col) { if(labels[row][col]! =NULL&&labels[row][col]->text()=="2048") { QMessageBox: : about(this,"信息","恭喜,你赢了! "); flag=true; break; } } if(flag) { break; } } } if(flag) { //删除数组,从头开始 releaseRes(); m_labelCount=0; m_score=0; emitScoreChange(); for(inti=0;i<2;i++){ createLabel(); } } returnflag; } 保存数据: voidGameWidget: : saveGame() { QFile*file=newQFile("data.json"); if(file->open(QIODevice: : WriteOnly)) { QJsonDocumentd; QJsonObjectjson=d.object(); //进度 QJsonArrayarr; for(inti=0;i<4;i++) { QJsonArrayarr1; for(intj=0;j<4;j++) { if(labels[i][j]! =NULL) { arr1.append(labels[i][j]->text()); } else { arr1.append(0); } } arr.append(arr1); } json.insert("labels",arr); //分数 json.insert("m_highScore",m_highScore); json.insert("m_score",m_score); d.setObject(json); QByteArrayba=d.toJson(QJsonDocument: : Indented); //将数据写入文件 file->write(ba); file->close(); } } voidGameWidget: : releaseRes() { for(intcol=0;col<4;++col) { for(introw=0;row<4;++row) { if(labels[row][col]! =NULL) { deletelabels[row][col]; labels[row][col]=NULL; } } } } voidGameWidget: : closeEvent(QCloseEvent*event) { saveGame(); } voidGameWidget: : setScore() { this->ui->score_3->setText(QString: : number(m_score)); if(m_score>m_highScore) { m_highScore=m_score; this->ui->best_2->setText(QString: : number(m_highScore)); } } voidGameWidget: : keyPressEvent(QKeyEvent*event) { switch(event->key()){ caseQt: : Key_Left: emitGestureMove(GestureDirect: : LEFT); break; caseQt: : Key_Right: emitGestureMove(GestureDirect: : RIGHT); break; caseQt: : Key_Down: emitGestureMove(GestureDirect: : DOWN); break; caseQt: : Key_Up: emitGestureMove(GestureDirect: : UP); break; default: break; } QWidget: : keyPressEvent(event); } voidGameWidget: : moveLabel(GestureDirectdirection) { boolisMove=false; switch(direction){ caseLEFT: isMove=moveLeft(); break; caseRIGHT: isMove=moveRight(); break; caseUP: isMove=moveUp(); break; caseDOWN: isMove=moveDown(); break; default: break; } //游戏胜利结束 boolisOver=gameOver(); //能移动才创建,不能移动并且游戏结束不创建新的标签 if(isMove&&! isOver){ createLabel(); } //游戏失败结束 if(! isOver) { gameOver(); } } 游戏重置: voidGameWidget: : on_bt_restart_clicked() { //删除数组,从头开始 releaseRes(); m_labelCount=0; m_score=0; emitScoreChange(); for(inti=0;i<2;i++){ createLabel(); } this->m_bgWidget->setFocus(); } 上下左右移动时的设计: boolGameWidget: : moveUp() { boolisMove=false;//是否能移动 inti,j;//i: 记录行 //j: 记录当前元素是否合并过的行 for(intcol=0;col<4;++col) { j=-1; for(introw=0;row<4;++row) { //找到的第一个不为null的label if(labels[row][col]==NULL) { i=row+1; while(i<4) { MyLabel*temp=labels[i][col]; if(temp! =NULL) { isMove=true; boolflag=false; if(j! =(row-1)) { flag=isMergeUp(i,col); } if(flag) { --row; j=row; --m_labelCount; }else { //交换两个元素 labels[row][col]=temp; j=-1;//将j重置为-1; } intx=temp->x(); inty=row*rowHeight+yOffset;//y轴偏移 //动画让label往上升 QPropertyAnimation*animation=newQPropertyAnimation(temp,"geometry"); //开始值和结束值 animation->setStartValue(temp->geometry()); animation->setEndValue(QRect(x,y,temp->width(),temp->height())); animation->setDuration(100);//动画播放时长 //设置动画的运动曲线 animation->setEasingCurve(QEasingCurve: : Linear); animation->start(QAbstractAnimation: : DeleteWhenStopped); //改变标签值,并改变分数 if(flag){ intscore=2*labels[row][col]->text().toInt(); labels[row][col]->reSetText(score); m_score+=score; emitScoreChange(); deletetemp; temp=NULL; } labels[i][col]=NULL; ++row; } ++i; } } elseif(row+1<4) { //当标签第一个不为空的时候 //如果该位置上有值,并且相邻的位置依然有值 MyLabel*temp=labels[row+1][col]; boolflag=merge(temp,row,col); if(flag) { isMove=true; j=row; deletelabels[row+1][col]; labels[row+1][col]=NULL; } } } } returnisMove; } boolGameWidget: : moveDown() { boolisMove=false;//是否能移动,不能移动 inti,j;//i: 记录行 //j: 记录当前元素是否合并过的行 for(int
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 Linux 作业 实现