#include "MainWindow.h"
#include "ui_widget.h"
#include <QLabel>
#include <QPushButton>
//主窗口构造函数
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this); //初始化出.ui界面
//一个格子宽高25像素,地图宽高600像素,每行有24个格子
//设置固定窗口大小
setFixedSize(1000,600);
//设置得分标签控件的属性
ui->label->setFont(QFont("黑体", 20, QFont::Bold, false));
//设置游戏速度标签内容
ui->label_2->setFont(QFont("楷体", 16, QFont::Bold, false));
ui->label_2->setText("游戏速度:");
//滑动条控件,这里将数值按一定比例放大缩小
ui->horizontalSlider->setValue(200 >> 2);
//监听滑动条控件滑动时,改变定时器速度为滑动条的值
connect(ui->horizontalSlider,QSlider::valueChanged,[=]()
{
timerspeed = ui->horizontalSlider->value() << 2;
});
//设置重新开始按钮属性和内容
ui->pushButton_3->setFont(QFont("黑体",12));
ui->pushButton_3->setText("重新开始");
//监听重新开始按钮
connect(ui->pushButton_3,QPushButton::clicked,[=]()
{
snake.Reset(); //重置蛇
score = 0; //得分清0
key = 'd'; //key值向右
timerspeed = 200 << 2;//重置游戏速度
timer->start(timerspeed);//重置定时器
ui->horizontalSlider->setValue(200 >> 2);//重置滑动条
gameflag = false; //重置游戏结束标志
});
//开启定时器
timer->start(timerspeed);
//监听定时器的信号,执行表达式内容
connect(timer,&QTimer::timeout,[=]()
{
timer->start(timerspeed); //调整定时器的速度
snake.Move(key); //蛇移动函数
//吃到食物的情况
(food.getfoodX() == snake.snakevec.at(0).x && food.getfoodY() == snake.snakevec.at(0).y) ?
score++, food.randfood(): //得分+1,随机产生一个食物坐标
snake.snakevec.pop_back(); //删除蛇尾
GameOver(); //游戏失败的情况
update(); //调用绘图函数
//更新标签控件的文本内容
ui->label->setText(QString("得分:%1").arg(score));
});
}
//游戏失败情况
void Widget::GameOver()
{
//撞墙失败
if(snake.snakevec.at(0).x >= 24 * 25 || snake.snakevec.at(0).x < 0 ||
snake.snakevec.at(0).y < 0 || snake.snakevec.at(0).y >= 24 * 25)
{
gameflag = true;
timer->stop(); //暂停定时器
return;
}
//撞自己失败
for(int i = 1; i < snake.snakevec.size(); i++)
{
if(snake.snakevec.at(0).x == snake.snakevec.at(i).x &&
snake.snakevec.at(0).y == snake.snakevec.at(i).y)
gameflag = true, timer->stop();
}
}
//绘图事件
void Widget::paintEvent(QPaintEvent *)
{
//创建画家对象,指定绘图设备为this主窗口
QPainter painter(this);
//设置画刷为红色
QBrush brush1(Qt::red);
//让画家使用画刷
painter.setBrush(brush1);
//画食物
painter.drawRect(QRect(food.getfoodX(),food.getfoodY(),25,25));
//设置画刷为黑色
QBrush brush2(Qt::blue);
painter.setBrush(brush2);
//遍历蛇坐标容器,画出代表蛇身的矩形
for(auto snakenodei : snake.snakevec)
//蛇头画圆形
(snakenodei.x == snake.snakevec.at(0).x &&
snakenodei.y == snake.snakevec.at(0).y) ?
//蛇头画圆形
painter.setRenderHint(QPainter::Antialiasing), //用抗锯齿画圆
painter.drawEllipse(QPoint(snakenodei.x + 12,snakenodei.y + 12),12,12):
//蛇身画矩形
painter.drawRect(QRect(snakenodei.x,snakenodei.y,25,25));
bugflag = false; //在画出蛇之后将标志设为假
//设置画刷为黑色
QBrush brush3(QColor(128, 64, 0));
painter.setBrush(brush3);
//画出墙壁
for(int i = 0; i < 24; i++)
painter.drawRect(QRect(25 * 25, i * 25, 25, 25));
//游戏结束时的绘图
if(gameflag)
{ //设置文字属性
QFont font("楷体", 80, QFont::Bold, false);
painter.setFont(font); //使用字体
painter.drawText(QRect(240, 200, 1000, 500), "游戏结束"); //画出游戏结束文字
}
}
//键盘事件,改变贪吃蛇移动方向
void Widget::keyPressEvent(QKeyEvent *ev)
{
if(bugflag) //bug标志为真直接返回
return;
switch (ev->key())
{
case Qt::Key_W:
if(key == 's') break; //按下与当前方向相反按键时break
key = 'w';
bugflag = true; break; //按键之后将标志设为真
case Qt::Key_S:
if(key == 'w') break;
key = 's';
bugflag = true; break;
case Qt::Key_A:
if(key == 'd') break;
key = 'a';
bugflag = true; break;
case Qt::Key_D:
if(key == 'a') break;
key = 'd';
bugflag = true; break;
case Qt::Key_Space: //空格键暂停,这里有点问题
timer->stop(); break;
default: //其他键重启定时器
timer->start(timerspeed);
}
}
//析构
Widget::~Widget()
{
delete ui;
}
|