1.打开窗口实现:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QLabel>
#include <QFont>
#include <QSound>
#include "gameselect.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//初始化窗口,标题,图标,窗口大小
ui->setupUi(this);
this->setWindowTitle("贪吃蛇");
this->setWindowIcon(QIcon(":/image/pix.png"));
this->setFixedSize(600,400);
//窗口背景设置,将图片设置自动拉伸
QLabel* label=new QLabel(this);
label->setGeometry(0,0,this->width(),this->height());
label->setPixmap(QPixmap(":/image/enter.jpg"));
label->setScaledContents(true);
//设置进入按钮
QPushButton* enter_but=new QPushButton(this);
enter_but->move(250,250);
enter_but->setText("进入游戏");
enter_but->setStyleSheet("QPushButton{border:0px;color:red;}");
//按钮文本设置
QFont font("华文行楷",18);
enter_but->setFont(font);
//创建选项页面,设置点击音效,打开新窗口,关闭旧窗口
GameSelect* gameSelect=new GameSelect;
connect(enter_but,&QPushButton::clicked,[=]()
{
gameSelect->setGeometry(this->geometry());
QSound::play(":/image/6.wav");
gameSelect->show();
this->close();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
2.选项窗口实现:
#include "gameselect.h"
#include <QIcon>
#include <QLabel>
#include <QDebug>
#include <QVBoxLayout>
#include <QPushButton>
#include <QFont>
#include "mainwindow.h"
#include <QSound>
#include "gameroom.h"
#include <QFile>
GameSelect::GameSelect(QWidget *parent) : QWidget(parent)
{
//窗口大小固定,设置图标,标题
this->setFixedSize(600,400);
this->setWindowTitle("关卡选择");
this->setWindowIcon(QIcon(":/image/pix.png"));
//加载背景
QLabel* label=new QLabel(this);
label->setGeometry(this->geometry());
label->setPixmap(QPixmap(":/image/load.jpg"));
//创建一个widget对象存放布局管理器,管理选项按钮
QWidget* widget=new QWidget(this);
widget->setGeometry(150,100,300,250);
//创建布局管理器,并将它设置到widget对象
QVBoxLayout* layout=new QVBoxLayout;
widget->setLayout(layout);
//选项按钮创建
QPushButton* but_easy=new QPushButton("简单模式");
QPushButton* but_normal=new QPushButton("正常模式");
QPushButton* but_diff=new QPushButton("困难模式");
QPushButton* but_grades=new QPushButton("战绩查询");
QPushButton* but_ret=new QPushButton("返回上页");
//按钮添加到布局管理器
layout->addWidget(but_easy);
layout->addWidget(but_normal);
layout->addWidget(but_diff);
layout->addWidget(but_grades);
layout->addWidget(but_ret);
//设置按钮的拉伸策略,是的可以占满整个布局管理器
but_easy->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
but_normal->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
but_diff->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
but_grades->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
but_ret->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
QFont font("华文行楷",25);
widget->setFont(font);
//设置按钮无边框,文本显示颜色为蓝色
but_easy->setStyleSheet("QPushButton{border: 0px;color:blue;}");
but_normal->setStyleSheet("QPushButton{border: 0px;color:blue;}");
but_diff->setStyleSheet("QPushButton{border: 0px;color:blue;}");
but_grades->setStyleSheet("QPushButton{border: 0px;color:blue;}");
but_ret->setStyleSheet("QPushButton{border: 0px;color:blue;}");
//连接按钮和槽函数,直接使用lambda表达式
connect(but_ret,&QPushButton::clicked,[=]()
{
MainWindow* mainwindow=new MainWindow;
QSound::play(":/image/6.wav");
mainwindow->show();
this->close();
});
GameRoom* room=new GameRoom;
connect(but_easy,&QPushButton::clicked,[=]()
{
room->setGeometry(this->geometry());
QSound::play(":/image/6.wav");
room->show();
this->close();
room->setMoveTimeout(300);
});
connect(but_normal,&QPushButton::clicked,[=]()
{
room->setGeometry(this->geometry());
QSound::play(":/image/6.wav");
room->show();
this->close();
room->setMoveTimeout(200);
});
connect(but_diff,&QPushButton::clicked,[=]()
{
room->setGeometry(this->geometry());
QSound::play(":/image/6.wav");
room->show();
this->close();
room->setMoveTimeout(100);
});
connect(but_grades, &QPushButton::clicked, [=]() {
QSound::play(":/image/6.wav");
QWidget* widget = new QWidget;
widget->setWindowTitle("历史分数");
widget->setWindowIcon(QIcon(":/image/pix.png"));
widget->setFixedSize(400, 200);
QLabel* label=new QLabel(widget);
label->setGeometry(0,0,400,200);
QFile file("C:/Users/86133/Desktop/Qt-tmp.txt");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QString grade=in.readLine();
QFont font("行书",30);
label->setFont(font);
label->setText("最近得分:"+ grade);
widget->show();
});
}
3.游戏窗口实现
#include "gameroom.h"
#include <QIcon>
#include <QPainter>
#include <QTimer>
#include <QPushButton>
#include <QMessageBox>
#include "gameselect.h"
#include <QFile>
#include <QTextStream>
#include <QShortcut>
GameRoom::GameRoom(QWidget *parent) : QWidget(parent)
{
//初始化窗口,标题,图标,大小
this->setWindowTitle("游戏房间");
this->setWindowIcon(QIcon(":/image/pix.png"));
this->setFixedSize(600,400);
//尾插一个节点作为头节点
snakeList.push_back(QRectF(160,220,kSnakeNodeWidth,kSnakeNodeHeight));
moveUp();
moveUp();
//创建食物
createFood();
//定时器设置
timer=new QTimer(this);
connect(timer,&QTimer::timeout,[=]()
{
//如果吃到食物,重新生成食物
int cnt=1;
if(snakeList.front().intersects(foodRect))
{
createFood();
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;
}
}
snakeList.pop_back();
update();
});
//开始和暂停按钮
QPushButton* sta_but=new QPushButton("开始游戏",this);
QPushButton* stop_but=new QPushButton("暂停游戏",this);
sta_but->move(450,100);
stop_but->move(450,150);
QFont font("楷体",15);
sta_but->setFont(font);
stop_but->setFont(font);
//开始功能实现,音乐播放,音乐持续播放设置
connect(sta_but,&QPushButton::clicked,[=]()
{
isGameStart=true;
timer->start(moveTimeout);
sound=new QSound(":/image/2.wav");
sound->play();
sound->setLoops(-1);
});
connect(stop_but,&QPushButton::clicked,[=]()
{
isGameStart=false;
timer->stop();
sound->stop();
});
//移动按钮设置
QPushButton* up=new QPushButton("↑",this);
QPushButton* down=new QPushButton("↓",this);
QPushButton* left=new QPushButton("←",this);
QPushButton* right=new QPushButton("→",this);
up->move(480,230);
down->move(480,270);
left->move(440,250);
right->move(520,250);
up->setStyleSheet("QPushButton{border:0px}");
down->setStyleSheet("QPushButton{border:0px}");
left->setStyleSheet("QPushButton{border:0px}");
right->setStyleSheet("QPushButton{border:0px}");
QFont ft("楷体",25);
up->setFont(ft);
down->setFont(ft);
left->setFont(ft);
right->setFont(ft);
QShortcut* s1=new QShortcut(QKeySequence("W"),up);
QShortcut* s2=new QShortcut(QKeySequence("S"),down);
QShortcut* s3=new QShortcut(QKeySequence("A"),left);
QShortcut* s4=new QShortcut(QKeySequence("D"),right);
QObject::connect(s1,&QShortcut::activated,up,&QPushButton::click);
QObject::connect(s2,&QShortcut::activated,down,&QPushButton::click);
QObject::connect(s3,&QShortcut::activated,left,&QPushButton::click);
QObject::connect(s4,&QShortcut::activated,right,&QPushButton::click);
connect(up,&QPushButton::clicked,[=]()
{
if(moveDirect!=SnakeDirect::DOWN)
moveDirect=SnakeDirect::UP;
});
connect(down,&QPushButton::clicked,[=]()
{
if(moveDirect!=SnakeDirect::UP)
moveDirect=SnakeDirect::DOWN;
});
connect(left,&QPushButton::clicked,[=]()
{
if(moveDirect!=SnakeDirect::RIGHT)
moveDirect=SnakeDirect::LEFT;
});
connect(right,&QPushButton::clicked,[=]()
{
if(moveDirect!=SnakeDirect::LEFT)
moveDirect=SnakeDirect::RIGHT;
});
//退出按钮
QPushButton* exit_but=new QPushButton("退出游戏",this);
exit_but->move(450,350);
exit_but->setFont(font);
QMessageBox* msg=new QMessageBox(this);
QPushButton* ok=new QPushButton("ok");
QPushButton* cancel=new QPushButton("cancel");
msg->addButton(ok,QMessageBox::AcceptRole);
msg->addButton(cancel,QMessageBox::RejectRole);
msg->setWindowTitle("退出");
msg->setText("是否确定退出?");
connect(exit_but,&QPushButton::clicked,[=]()
{
msg->exec();
QSound::play(":/image/6.wav");
if(msg->clickedButton()==ok)
{
GameSelect* gameselect=new GameSelect;
gameselect->show();
this->close();
}
else
{
msg->close();
}
});
}
void GameRoom::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/image/main.jpg");
painter.drawPixmap(0,0,400,400,pix);
pix.load(":/image/control.jpg");
painter.drawPixmap(400,0,200,400,pix);
//绘制蛇头
if(moveDirect==SnakeDirect::UP)
pix.load(":/image/up.png");
else if(moveDirect==SnakeDirect::DOWN)
pix.load(":/image/down.png");
else if(moveDirect==SnakeDirect::LEFT)
pix.load(":/image/left.png");
else
pix.load(":/image/right.png");
auto snakeHead=snakeList.front();
painter.drawPixmap(snakeHead.x(),snakeHead.y(),snakeHead.width(),snakeHead.height(),pix);
//绘制蛇身
pix.load(":/image/circle.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.height(),pix);
//绘制食物
pix.load(":/image/Hamburg.png");
painter.drawPixmap(foodRect.x(),foodRect.y(),kSnakeNodeWidth,kSnakeNodeHeight,pix);
//将分数绘制到界面
QPen pen;
pen.setColor(Qt::black);
painter.setPen(pen);
QFont font("楷体",15);
painter.setFont(font);
painter.drawText(430,30,"当前等分:");
painter.drawText(530,30,QString("%1").arg(snakeList.size()-3));
//绘制失败效果
if(checkFail())
{
pen.setColor(Qt::red);
QFont font("楷体",30);
painter.setPen(pen);
painter.setFont(font);
painter.drawText(100,180,"Game Over");
timer->stop();
sound->stop();
}
//将当前分数保存到文件中
int c=snakeList.size()-3;
QFile file("C:/Users/86133/Desktop/Qt-tmp.txt");
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream out(&file);
int num=c;
out<<num;
file.close();
}
}
void GameRoom::moveUp()
{
QPointF leftTop;
QPointF rightBottom;
auto snakeHead=snakeList.front();
int headX=snakeHead.x();
int headY=snakeHead.y();
if(headY<20)
{
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 snakeHead=snakeList.front();
int headX=snakeHead.x();
int headY=snakeHead.y();
if(headY>this->height()-40)
{
leftTop=QPointF(headX,0);
}
else
{
leftTop=snakeHead.bottomLeft();
}
rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);
snakeList.push_front(QRectF(leftTop,rightBottom));
}
void GameRoom::moveLeft()
{
QPointF leftTop;
QPointF rightBottom;
auto snakeHead=snakeList.front();
int headX=snakeHead.x();
int headY=snakeHead.y();
if(headX<20)
{
leftTop=QPointF(400-kSnakeNodeWidth,headY);
}
else
{
leftTop=QPointF(headX-kSnakeNodeWidth,headY);
}
rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);
snakeList.push_front(QRectF(leftTop,rightBottom));
}
void GameRoom::moveRight()
{
QPointF leftTop;
QPointF rightBottom;
auto snakeHead=snakeList.front();
int headX=snakeHead.x();
int headY=snakeHead.y();
if(headX>360)
{
leftTop=QPointF(0,headY);
}
else
{
leftTop=snakeHead.topRight();
}
rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);
snakeList.push_front(QRectF(leftTop,rightBottom));
}
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;
}
void GameRoom::createFood()
{
foodRect=QRectF(qrand()%(400/kSnakeNodeWidth)*kSnakeNodeWidth,
qrand()%(400/kSnakeNodeHeight)*kSnakeNodeHeight,kSnakeNodeWidth,kSnakeNodeHeight);
}