wordpress个人站主题,渭南做网站哪家公司,模板网站可以自己买空间吗吗,软文广告怎么写目录
先看效果
项目介绍 界面一#xff1a;游戏大厅界面
界面二#xff1a;关卡选择界面编辑
界面三#xff1a;游戏界面
游戏大厅页面
游戏关卡选择页面
游戏房间页面
封装贪吃蛇数据结构
初始化游戏房间界面
设置窗口大小、标题、图标等
蛇的移动
初始化贪…
目录
先看效果
项目介绍 界面一游戏大厅界面
界面二关卡选择界面编辑
界面三游戏界面
游戏大厅页面
游戏关卡选择页面
游戏房间页面
封装贪吃蛇数据结构
初始化游戏房间界面
设置窗口大小、标题、图标等
蛇的移动
初始化贪吃蛇本体和食物节点
实现各个方向的移动
实现向上移动
实现向下移动
实现向左移动
实现向右移动
检查是否自己会不会撞自己
设置游戏开始和游戏暂停按钮
设置退出游戏按钮
获取历史战绩 先看效果 项目介绍 贪吃蛇游戏是⼀款休闲益智类游戏。它通过控制蛇头⽅向吃⻝物从⽽使得蛇变得越来越⻓。在本游戏中设置了上下左右四个⽅向键来控制蛇的移动⽅向。⻝物的产⽣是随机⽣成的当蛇每吃⼀次⻝物就会增加⼀节⾝体同时游戏积分也会相应的加⼀。在本游戏的设计中蛇的⾝体会越吃越⻓⾝体越⻓对应的难度就越⼤因为⼀旦蛇头和⾝体相交游戏就会结束。 界面一游戏大厅界面 当用户点击 “开始游戏” 按钮之后就会进⼊到关卡选择界面。 界面二关卡选择界面 在关卡选择界⾯上设置了三个游戏模式按钮分别是简单模式、正常模式、困难模式⼀个 “历史战绩” 按钮⼀个返回游戏⼤厅界⾯的按钮。 当我们点击三个游戏按钮中的任意⼀个时就会进⼊游戏房间界⾯游戏房间界⾯如下 界面三游戏界面 在游戏界⾯如果想要开始游戏⾸先点击 “开始” 按钮此时蛇就会移动并且还有背景⾳效。如果 想要暂停游戏那么点击 “暂停” 按钮即可。当我们在游戏时可以通过右边控制区域的上下左右方向键来控制蛇的移动。当蛇每吃⼀次⻝物时伴随有吃⻝物的⾳效蛇⾝会增加⼀节⻓度并且分数 积分也会相应的加⼀。最后在控制区域的右下⻆布局了⼀个 “退出” 按钮当点击 “退出” 按钮时就会弹出一个对话框我们点击OK就会退出游戏点击cancel我们便不会退出游戏。 在刚进⼊游戏房间界⾯时⼀定不能点击 “退出” 按钮如果点击 “退出” 按钮那么程序就会异常退出。点击的顺序⼀定是先点击 “开始” 按钮最后才能点击 “退出” 。 游戏大厅页面 主要内容重写了绘图事件 //重写绘图事件void paintEvent(QPaintEvent *event);
void GameHall::paintEvent(QPaintEvent *event)
{(void) event;//实例化画家对象QPainter painter(this);//QpixmapQPixmap pix(:/res/game_hall.png);//画家绘画painter.drawPixmap(0,0,this-width(),this-height(),pix);} 固定窗口的大小同时将其与的窗口也设置为1000,800设置窗口的图标以及窗口的标题名使用信号和槽函数点击开始按钮跳转的游戏选择窗口。 GameHall::GameHall(QWidget *parent): QWidget(parent), ui(new Ui::GameHall)
{ui-setupUi(this);//调整窗口大小this-setFixedSize(1000,800);//设置窗口的图表this-setWindowIcon(QIcon(:/res/ico.png));this-setWindowTitle(贪吃蛇游戏);QFont font(华为行楷,24);QPushButton* starBtn new QPushButton(this);starBtn-move(430,530);starBtn-setFont(font);starBtn-setText(开始游戏);starBtn-setStyleSheet(QPushButton{border:0px;}); //去掉边框//跳转到第二个窗口GameSelect * gameSelect new GameSelect;connect(starBtn,QPushButton::clicked,[](){this-close();//设置第二个窗口和第一个窗口一样大gameSelect-setGeometry(this-geometry());gameSelect-show();QSound::play(:/res/clicked.wav);});
} 使用的知识点总结 通过使用setFixedSize设置窗口的大小 使用setWindowIcon设置左上角的图标使用setWindowTitle设置文本标题 使用lambda表达式 使用信号和槽函数跳转到第二个页面 游戏关卡选择页面 实现代码如下 //绘图事件void paintEvent(QPaintEvent *event);
GameSelect::GameSelect(QWidget *parent) : QWidget(parent)
{this-setFixedSize(1000,800); //设置窗口大小其实可以设置也可以不设置this-setWindowIcon(QIcon(:/res/ico.png));this-setWindowTitle(游戏关卡选择);QPushButton* backBtn new QPushButton(this);backBtn-move(900,730);backBtn-setIcon(QIcon(:/res/back.png));//信号和槽 跳转到第一个页面connect(backBtn,QPushButton::clicked,[](){this-close();GameHall* gameHall new GameHall;gameHall-show();//加上音效QSound::play(:/res/clicked.wav);});QFont font(华文行楷,24);GameRoom* gameRoom new GameRoom;QPushButton * simpleBtn new QPushButton(this);simpleBtn-move(420,160);simpleBtn-setText(简单模式);simpleBtn-setFont(QFont(font));connect(simpleBtn,QPushButton::clicked,[](){this-close();gameRoom-show();QSound::play(:/res/clicked.wav);gameRoom-setTimerout(400);});QPushButton * normalBtn new QPushButton(this);normalBtn-move(420,260);normalBtn-setText(正常模式);normalBtn-setFont(QFont(font));connect(normalBtn,QPushButton::clicked,[](){this-close();gameRoom-setGeometry(this-geometry());gameRoom-show();QSound::play(:/res/clicked.wav);gameRoom-setTimerout(200);});QPushButton * difficultBtn new QPushButton(this);difficultBtn-move(420,360);difficultBtn-setText(困难模式);difficultBtn-setFont(QFont(font));connect(difficultBtn,QPushButton::clicked,[](){this-close();gameRoom-setGeometry(this-geometry());gameRoom-show();QSound::play(:/res/clicked.wav);gameRoom-setTimerout(50);});QPushButton * history new QPushButton(this);history-move(420,460);history-setText(历史战绩);history-setFont(QFont(font));QSound::play(:/res/clicked.wav);connect(history,QPushButton::clicked,[](){QWidget * widget new QWidget;widget-setWindowTitle(历史战绩);widget-setFixedSize(500,300);QTextEdit* edit new QTextEdit(widget);edit-setFont(font);edit-setFixedSize(500,300);//获取历史战绩 获取蛇的长度 -3 就表示吃的食物QFile file(C:/Users/19846/Desktop/greedy_snack/1.txt);file.open(QIODevice::ReadOnly);QTextStream in(file);int data in.readLine().toInt();edit-append(得分为);edit-append(QString::number(data));widget-show();});
}void GameSelect::paintEvent(QPaintEvent *event)
{(void) event;//实例化 画家对象QPainter painter(this);QPixmap pix(:/res/game_select.png);painter.drawPixmap(0,0,this-width(),this-height(),pix);
}游戏房间页面
• 蛇的绘制、蛇的移动、判断蛇是否会撞到自己 • 积分的累加和绘制 在这⾥我们要考虑几个比较核心的问题 1. 怎么让蛇动起来 • 我们可以用⼀个链表表示贪吃蛇⼀个⼩方块表示蛇的⼀个节点 我们设置蛇的默认长度为3 • 向上移动的逻辑就是在蛇的上方加入⼀个小方块 然后把最后⼀个小方块删除即可 • 需要用到定时器Qtimer 每100 - 200ms 重新渲染。 2. 怎么判断蛇有没有吃到⻝物 • 判断蛇头和⻝物的坐标是否相交Qt 有相关的接口调用。 3. 怎么控制蛇的移动 • 借助QT的实践机制实现 重写keyPressEvent即可 在函数中监控想要的键盘事件即可 • 我们通过绘制四个按钮使⽤信号和槽的机制控制蛇的上、下、左、右移动⽅向
封装贪吃蛇数据结构
//枚举蛇的移动方向
enum class SnakeDirect{UP 0,DOWN,LEFT,RIGHT
};class GameRoom : public QWidget
{Q_OBJECT
public:explicit GameRoom(QWidget *parent nullptr);void paintEvent(QPaintEvent *event);void moveUp(); //蛇向上移动void moveDown();//蛇向下移动void moveLeft(); //蛇向左移动void moveRight();//蛇向右移动bool checkFail(); //判断游戏是否结束void crateNewFood(); //创建食物void setTimerout(int timeout){moveTimeout timeout;}signals:private:const int kSnakeNodeWidth 20; //表示蛇身体节点的宽度const int kSnakeNodeHeight 20; //表示蛇身体的高度const int kDefaultTimeout 200; //设默认的移动速度QListQRectF snakeList; //表示贪吃蛇链表QRectF foodRect; //表示食物节点SnakeDirect moveDirect SnakeDirect::UP; //默认移动方向是向上QTimer* timer; //定时器bool isGameStart false;QSound* sound;int moveTimeout kDefaultTimeout;
};
初始化游戏房间界面
设置窗口大小、标题、图标等 GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui-setupUi(this);// 初始化窗⼝设置this-setFixedSize(1000, 800);this-setWindowTitle(贪吃蛇游戏);this-setWindowIcon(QIcon(:res/ico.png));
}
蛇的移动 蛇的移动⽅向为上、下、左、右。通过在游戏房间中布局四个按钮来控制蛇的移动⽅向。 注意 这⾥贪吃蛇不允许直接掉头 ⽐如当前是向上的 不能直接修改为向下。 QPushButton *Up new QPushButton(this);QPushButton *Down new QPushButton(this);QPushButton *Left new QPushButton(this);QPushButton *Right new QPushButton(this);Up-move(880,400);Down-move(880,480);Left-move(840,440);Right-move(920,440);Up-setStyleSheet(QPushButton{border:0px;});Up-setFont(font);Up-setText(↑);Down-setStyleSheet(QPushButton{border:0px;});Down-setFont(font);Down-setText(↓);Left-setStyleSheet(QPushButton{border:0px;});Left-setFont(font);Left-setText(←);Right-setStyleSheet(QPushButton{border:0px;});Right-setFont(font);Right-setText(→);connect(Up,QPushButton::clicked,this,[](){if(moveDirect ! SnakeDirect::DOWN)moveDirect SnakeDirect::UP;});connect(Down,QPushButton::clicked,this,[](){if(moveDirect ! SnakeDirect::UP)moveDirect SnakeDirect::DOWN;});connect(Left,QPushButton::clicked,this,[](){if(moveDirect ! SnakeDirect::RIGHT)moveDirect SnakeDirect::LEFT;});connect(Right,QPushButton::clicked,this,[](){if(moveDirect ! SnakeDirect::LEFT)moveDirect SnakeDirect::RIGHT;
})初始化贪吃蛇本体和食物节点
GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{// 初始化贪吃蛇snakeList.push_back(QRectF(this-width() * 0.5, this-height() * 0.5,
kSnakeNodeWidth, kSnakeNodeHeight));moveUp();moveUp();// 初始化⻝物createNewFood();
} moveUp() 的功能是将蛇向上移动⼀次 即在上方新增⼀个节点 但不删除尾部节点。 createNewFood() 方法的功能是随机创建⼀个食物节点 void GameRoom::createNewFood()
{foodRect QRectF(qrand() % (this-width() / kSnakeNodeWidth) * kSnakeNodeWidth ,qrand() % (this-height() / kSnakeNodeWidth) * kSnakeNodeWidth,kSnakeNodeWidth,kSnakeNodeHeight);
}
实现定时器的超时槽函数 定时器的是为了实现每隔⼀段时间能处理移动的逻辑并且更新绘图事件。
• ⾸先 需要判断蛇头和食物节点坐标是否相交 ◦ 如果相交 需要创建新的食物节点 并且需要更新蛇的长度 所以 cnt 需要 1 ◦ 如果不相交 那么直接处理蛇的移动即可。
• 根据蛇移动方向 moveDirect 来处理蛇的移动 处理方法是在前方加⼀个 并且删除后方节点 • 重新触绘图事件 更新渲染。 GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{timer new QTimer(this);connect(timer, QTimer::timeout, this, [](){int cnt 1;// 判断是否贪吃蛇和⻝物是否相交if (snakeList.front().intersects(foodRect)) {createNewFood();cnt;}while(cnt--) {// 处理蛇的移动switch (moveDirect) {case SnakeDirect::UP:moveUp();break;case SnakeDirect::DOWN:moveDown();break;case SnakeDirect::LEFT:moveLeft();break;case SnakeDirect::RIGHT:moveRight();break;default:qDebug() ⾮法移动⽅向;break;}}// 删除最后⼀个节点snakeList.pop_back();update();});
}
实现各个方向的移动
实现向上移动
void GameRoom::moveUp()
{QPointF leftTop; //左上角坐标QPointF rightBottom; //右下角坐标auto snakeNode snakeList.front(); //头int headX snakeNode.x();int headY snakeNode.y();// 头到墙了穿墙了if(headY 0){leftTop QPointF(headX,this-height() - kSnakeNodeHeight);}else{leftTop QPointF(headX,headY - kSnakeNodeHeight);}rightBottom leftTop QPointF(kSnakeNodeWidth,kSnakeNodeHeight); //为一个矩形 左上角snakeList.push_front(QRectF(leftTop,rightBottom));
} 实现向下移动
void GameRoom::moveDown()
{QPointF leftTop;//左上角坐标QPointF rightBottom; //右下角坐标 左上角坐标右下角坐标唯一确定一个矩形auto snakeNode snakeList.front(); //链表int headX snakeNode.x(); //蛇头xint headY snakeNode.y(); //蛇头yif(headY this-height() ) //蛇头跑到外面了{leftTop QPointF(headX,0);}else{leftTop snakeNode.bottomLeft();}rightBottom leftTopQPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom));}
实现向左移动
void GameRoom::moveLeft()
{QPointF leftTop;QPointF rightButtom;auto snakeNode snakeList.front();int headX snakeNode.x();int headY snakeNode.y();if(headX 0){leftTop QPointF(800 - kSnakeNodeWidth,headY);}else{leftTop QPointF(headX - kSnakeNodeWidth,headY);}rightButtom leftTop QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightButtom));}
实现向右移动
void GameRoom::moveRight()
{QPointF leftTop;QPointF rightButtom;auto snakeNode snakeList.front();int headX snakeNode.x();int headY snakeNode.y();if(headX kSnakeNodeWidth 780){leftTop QPointF(0,headY);}else{leftTop snakeNode.topRight();}rightButtom leftTop QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightButtom));
}
重写绘图事件函数进行渲染 重写基类的 paintEvent() 方法进行渲染
渲染背景图渲染蛇头渲染蛇⾝体渲染蛇尾巴渲染右边游戏控制区域渲染食物节点渲染当前分数游戏结束渲染 game over!
void gameroom::paintEvent(QPaintEvent *event)
{QPainter painter(this);QPixmap pix;pix.load(:res/simple_room.png);painter.drawPixmap(0,0,800,800,pix);painter.setRenderHint(QPainter::Antialiasing); //设置抗锯⻮// 渲染蛇头if(moveDirect SnakeDirect::UP) {pix.load(:res/up.png);} else if(moveDirect SnakeDirect::DOWN) {pix.load(:res/down.png);} else if(moveDirect SnakeDirect::LEFT) {pix.load(:res/left.png);} else {pix.load(:res/right.png);}auto snakeHead snakeList.front();painter.drawPixmap(snakeHead.x(), snakeHead.y(), snakeHead.width(),
snakeHead.height(), pix);//渲染蛇⾝体pix.load(:res/body.png);for (int i 1; i snakeList.size() - 1; i) {
auto node snakeList.at(i);painter.drawPixmap(node.x(),node.y(),node.width(),node.height(),pix);}// 渲染贪吃蛇尾巴auto snakeTail snakeList.back();painter.drawPixmap(snakeTail.x(),snakeTail.y(),snakeTail.width(),snakeTail.heig
ht(),pix);//渲染⻝物pix.load(:res/normal_food.bmp);painter.drawPixmap(foodRect.x(), foodRect.y(), foodRect.width(),
foodRect.height(), pix);//渲染右边区域pix.load(:res/right_area.png);painter.drawPixmap(800, 0, 200, 1000, pix);// 渲染分数pix.load(:res/sorce_bg.png);painter.drawPixmap(this-width() * 0.85, this-height() * 0.02, 90, 40,
pix);QPen pen;pen.setColor(Qt::black);painter.setPen(pen);QFont font(⽅正舒体, 22, QFont::ExtraLight, false);painter.setFont(font);painter.drawText(this-width() * 0.90, this-height() * 0.06,
QString(%1).arg(snakeList.size()));// 如果检查失败 渲染game overif(checkFail()){pen.setColor(Qt::red);painter.setPen(pen);QFont font(⽅正舒体, 50, QFont::ExtraLight, false);painter.setFont(font);painter.drawText(this-width() * 0.5 - 250, this-height() * 0.5,
QString(GAME OVER!));timer-stop();QSound::play(:res/gameover.wav);sound-stop();
}
}
检查是否自己会不会撞自己
bool GameRoom::checkFail()
{// 判断头尾是否出现相交for(int i 0; i snakeList.size(); i){for(int j i 1; j snakeList.size(); j){if(snakeList.at(i) snakeList.at(j)) {return true;}}}return false;
}
设置游戏开始和游戏暂停按钮 QPushButton *startbtn new QPushButton(this);QPushButton *stopbtn new QPushButton(this);QFont ft(楷体, 20, QFont::ExtraLight, false);//设置按钮的位置startbtn-move(860,150);stopbtn-move(860,200);//设置按钮⽂本startbtn-setText(开始);stopbtn-setText(暂停);//设置按钮样式startbtn-setStyleSheet(QPushButton{border:0px;});stopbtn-setStyleSheet(QPushButton{border:0px;});
//设置按钮字体格式startbtn-setFont(ft);stopbtn-setFont(ft);connect(startbtn,QPushButton::clicked,this,[](){sound new QSound(:res/Trepak.wav); //声⾳路径sound-play(); //播放sound-setLoops(-1); //循环播放isGameStart true;timer-start(moveTimeout);});connect(stopbtn,QPushButton::clicked,this,[](){sound-stop();isGameStart false;timer-stop();});
设置退出游戏按钮 当我们点击退出游戏按钮时当前游戏房间窗口不会立即退出是会弹窗提示提示我们是否要退出游戏 //退出游戏按钮QPushButton *ExitGame new QPushButton(this);ExitGame-setStyleSheet(QPushButton{border:0px;});ExitGame-move(860,750);ExitGame-setFont(ft);ExitGame-setText(退出);//消息提⽰QPushButton *okbtn new QPushButton(Ok);QPushButton *cancelbtn new QPushButton(Cancel);QMessageBox *msg new QMessageBox(this);msg-setWindowTitle(退出游戏); //设置消息对话框的标题msg-setText(确认退出游戏吗); //设置消息对话框内容msg-setIcon(QMessageBox::Question); //设置消息对话框类型msg-addButton(okbtn,QMessageBox::AcceptRole); //Accept Role接受的⻆⾊msg-addButton(cancelbtn,QMessageBox::RejectRole); //Reject Role排斥
作⽤connect(ExitGame,QPushButton::clicked,[](){//消息提⽰msg-show();QSound::play(:res/clicked.wav);msg-exec(); //阻塞等待⽤⼾输⼊if(msg-clickedButton() okbtn) //点击了ok按钮{this-close();//如果点击了 Ok 按钮那么就会跳转到游戏关卡界⾯GameSelect *s new GameSelect;s-show();s-setGeometry(this-geometry());QSound::play(:res/clicked.wav);sound-stop(); //停⽌背景⾳乐}else{msg-close();QSound::play(:res/clicked.wav);}});
获取历史战绩
int c snakeList.size();
2 QFile file(C:/Users/Lenovo/Desktop/1.txt);
3 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
4 QTextStream out(file);
5 int num c;
6 out num; // 将int类型数据写⼊⽂件
7 file.close(); 读⽂件读取写⼊文件中蛇的长度 QFile file(C:/Users/Lenovo/Desktop/1.txt);
2 file.open(QIODevice::ReadOnly);
3
4 QTextStream in(file); //创建⽂本流对象
5 int data in.readLine().toInt(); //读取第⼀⾏作为整形数据