QT实现两条贪吃蛇
最终效果图https://www.52pojie.cn/forum.php?mod=image&aid=1033033&size=300x300&key=720d8214ad8b7c09&nocache=yes&type=fixnone
刚学qt两个礼拜,代码编的比较差,望各位看官海涵。
代码如下:
02_Snake.pro
#-------------------------------------------------#
# Project created by QtCreator 2017-12-11T22:59:40
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = 02_Snake
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
widget.cpp \
mythread.cpp
HEADERS+= widget.h \
mythread.h \
allparameter.h
FORMS += widget.ui
CONFIG +=C++11
allparameter.h
#ifndef ALLPARAMETER_H
#define ALLPARAMETER_H
extern QVector<QRect>rects; //存放第一条蛇
extern QVector<QRect>rectsfight;//存放第二条蛇
extern QRect newrect;//存放食物
//两条蛇的方向状态标志
extern int state,statefight;
extern int begin;
//方框长度和高度,列数,行数
extern int g_length,g_width,g_lines,g_rows;
#endif // ALLPARAMETER_H
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include<QImage>
class MyThread : public QObject
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void DrawImage();
signals:
void UpdateImage(QImage temp);
void Touch();
public slots:
private:
QImage image;
};
#endif // MYTHREAD_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QThread>
#include<QTimer>
#include"mythread.h"
#include<QPaintEvent>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void paintEvent(QPaintEvent *event);
void dealUpdateImage(QImage);
void closeThread();
void keyPressEvent(QKeyEvent *event);
void Paint();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
MyThread *MyT;
QThread *thread;
QTimer *time_1;
QImage image;
int timeset;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
mythread.cpp
#include "mythread.h"
#include<QPainter>
#include<allparameter.h>
#include<QBrush>
#include<QPen>
MyThread::MyThread(QObject *parent) : QObject(parent)
{
}
void MyThread::DrawImage()
{
switch(state)
{
//贪吃蛇往上边吃
case 0:
if(((rects).left()==newrect.left())&&(rects.top()-g_width==newrect.top()))
{
//吃掉食物
rects.push_back(newrect);
// 产生不与蛇重叠的新食物
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rects.push_back(QRect((rects.left()),(rects.top())-g_width,g_length,g_width));
rects.removeAt(0);
}
break;
//往左吃
case 1:
if(((rects).left()-g_length==newrect.left())&&(rects.top()==newrect.top()))
{
rects.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rects.push_back(QRect((rects.left())-g_length,(rects.top()),g_length,g_width));
rects.removeAt(0);
}
break;
//往下吃
case 2:
if(((rects).left()==newrect.left())&&(rects.top()+g_width==newrect.top()))
{
rects.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rects.push_back(QRect((rects.left()),(rects.top())+g_width,g_length,g_width));
rects.removeAt(0);
}
break;
//往右吃
case 3:
if(((rects).left()+g_length==newrect.left())&&(rects.top()==newrect.top()))
{
rects.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rects.push_back(QRect((rects.left())+g_length,(rects.top()),g_length,g_width));
rects.removeAt(0);
}
break;
}
//将第一位删除
// rects.removeAt(0);
//判断另一条蛇
switch(statefight)
{
//往下吃
case 0:
if(((rectsfight).left()==newrect.left())&&(rectsfight.top()-g_width==newrect.top()))
{
rectsfight.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rectsfight.push_back(QRect((rectsfight.left()),(rectsfight.top())-g_width,g_length,g_width));
rectsfight.removeAt(0);
}
break;
//往往左吃
case 1:
if(((rectsfight).left()-g_length==newrect.left())&&(rectsfight.top()==newrect.top()))
{
rectsfight.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rectsfight.push_back(QRect((rectsfight.left())-g_length,(rectsfight.top()),g_length,g_width));
rectsfight.removeAt(0);
}
break;
//往上吃
case 2:
if(((rectsfight).left()==newrect.left())&&(rectsfight.top()+g_width==newrect.top()))
{
rectsfight.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rectsfight.push_back(QRect((rectsfight.left()),(rectsfight.top())+g_width,g_length,g_width));
rectsfight.removeAt(0);
}
break;
//往右吃
case 3:
if(((rectsfight).left()+g_length==newrect.left())&&(rectsfight.top()==newrect.top()))
{
rectsfight.push_back(newrect);
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
else
{
rectsfight.push_back(QRect((rectsfight.left())+g_length,(rectsfight.top()),g_length,g_width));
rectsfight.removeAt(0);
}
break;
}
//判断碰撞
if(
//第一条
((rects).left()<=begin-g_length)//碰到左边
||((rects).left()>=(begin+g_rows*g_length)) //碰到右边
||((rects).top()<=begin-g_width)//碰到上边
||((rects).top()>=(begin+g_width*g_lines)) //碰到下边
//第二条
||((rectsfight).left()<=begin-g_length)
||((rectsfight).left()>=(begin+g_rows*g_length))
||((rectsfight).top()<=begin-g_width)
||((rectsfight).top()>=(begin+g_width*g_lines))
)
{
//发出碰撞信号
emit Touch();
//清除两条蛇
rects.clear();
rectsfight.clear();
//生成新的地图
rects.push_back(QRect(begin+g_length*(g_rows/4),begin+g_width*(g_lines/4),g_length,g_width));
rectsfight.push_back(QRect(begin+g_length*(g_rows*3/4),begin+g_width*(g_lines*3/4),g_length,g_width));
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
}
//重新生成地图
image=QImage(begin*2+g_length*g_rows,begin+(g_width+3)*g_lines,QImage::Format_ARGB32);
QPainter p(&image);
QPen pen;
p.setPen(pen);
QVector<QLine>lines;
for(int i=0;i<=g_lines;i++)
{
lines.push_back(QLine(begin,begin+g_width*i,begin+g_rows*g_length,begin+g_width*i));
}
for(int i=0;i<=g_rows;i++)
{
lines.push_back(QLine(begin+g_length*i,begin,begin+g_length*i,begin+g_width*g_lines));
}
p.drawLines(lines);
QBrush brush;
brush.setColor(Qt::black);
brush.setStyle(Qt::SolidPattern);
p.setBrush(brush);
p.drawRects(rects);
brush.setColor(Qt::yellow);
p.setBrush(brush);
p.drawRects(rectsfight);
brush.setColor(Qt::red);
p.setBrush(brush);
p.drawRect(newrect);
//触发更新地图信号
emit UpdateImage(image);
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
#include<QPen>
#include<QBrush>
#include<allparameter.h>
#include<QMessageBox>
QVector<QRect>rects;
QVector<QRect>rectsfight;
QRect newrect;
int state=0,statefight=0;
int begin={20,20};
int g_length=20,g_width=20,g_lines=21,g_rows=21;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
//界面初始化
ui->setupUi(this);
//调整界面尺寸
resize(begin*2+g_length*g_rows,begin+(g_width+3)*g_lines);
//调整控件位置
ui->pushButton->move((begin+g_length*(g_rows/2-1))-ui->pushButton->width()-ui->label->width(),begin+(g_width+1)*g_lines);
ui->label->move((begin+g_length*(g_rows/2))-ui->label->width()-2,begin+(g_width+1)*g_lines);
ui->lineEdit->move((begin+g_length*(g_rows/2)),begin+(g_width+1)*g_lines+2);
ui->pushButton_2->move((begin+g_length*(g_rows/2+1))+ui->lineEdit->width(),begin+(g_width+1)*g_lines);
//设置编辑框内容和大小
ui->lineEdit->setText("300");
ui->lineEdit->resize(40,20);
//获取编辑框中的时间,将时间初始化
timeset=ui->lineEdit->text().toInt();
//初始化随机数
srand((unsigned)time(NULL));
//设置窗口无边框
setWindowFlags(Qt::FramelessWindowHint|windowFlags());
//添加两条蛇
rects.push_back(QRect(begin+g_length*(g_rows/4),begin+g_width*(g_lines/4),g_length,g_width));
rectsfight.push_back(QRect(begin+g_length*(g_rows*3/4),begin+g_width*(g_lines*3/4),g_length,g_width));
//随机生成食物
bool con=1;
int a,b;
while(con)
{
a=rand()%(g_rows);
b=rand()%(g_lines);
if(!(rects.contains(QRect(begin+g_length*a,begin+g_width*b,g_length,g_width))))
con=0;
}
newrect=QRect(begin+g_length*a,begin+g_width*b,g_length,g_width);
//初始化定时器
time_1=new QTimer(this);
//初始化线程
MyT=new MyThread;
thread=new QThread(this);
MyT->moveToThread(thread);
thread->start();
//定时器时间到了之后,线程处理图像
connect(time_1,&QTimer::timeout,MyT,&MyThread::DrawImage);
//线程中发出更新图片后,主窗口更新画面
connect(MyT,&MyThread::UpdateImage,this,&Widget::dealUpdateImage);
//关闭窗口时,关闭线程
connect(this,&Widget::destroyed,this,&Widget::closeThread);
//当线程发出碰撞信号后,发出提示
connect(MyT,&MyThread::Touch,this,
[=]()
{
time_1->stop();
QMessageBox message;
message.information(this,"提示","你输了");
}
);
Paint();
}
//析构函数
Widget::~Widget()
{
delete ui;
}
//关闭线程
void Widget::closeThread()
{
thread->quit();
thread->wait();
}
//按键事件
void Widget::on_pushButton_clicked()
{
//读取时间
timeset=ui->lineEdit->text().toInt();
//打开或关闭定时器
if(time_1->isActive()==false)
{
time_1->start(timeset);
}
else
{
time_1->stop();
}
}
//画图事件
void Widget::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawImage(0,0,image);
}
//更新画面
void Widget::dealUpdateImage(QImage temp)
{
image=temp;
update();
}
//按键判断 wasd ijkl
void Widget::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
case 87: state=0;break;
case 65: state=1;break;
case 83: state=2;break;
case 68: state=3;break;
case 73: statefight=0;break;
case 74: statefight=1;break;
case 75: statefight=2;break;
case 76: statefight=3;break;
}
}
//退出按钮
void Widget::on_pushButton_2_clicked()
{
closeThread();
close();
}
//画背景
void Widget::Paint()
{
image=QImage(500,500,QImage::Format_ARGB32);
QPainter p(&image);
QPen pen;
p.setPen(pen);
QVector<QLine>lines;
for(int i=0;i<=g_lines;i++)
{
lines.push_back(QLine(begin,begin+g_width*i,begin+g_rows*g_length,begin+g_width*i));
}
for(int i=0;i<=g_rows;i++)
{
lines.push_back(QLine(begin+g_length*i,begin,begin+g_length*i,begin+g_width*g_lines));
}
p.drawLines(lines);
QBrush brush;
brush.setColor(Qt::black);
brush.setStyle(Qt::SolidPattern);
p.setBrush(brush);
p.drawRects(rects);
brush.setColor(Qt::yellow);
p.setBrush(brush);
p.drawRects(rectsfight);
brush.setColor(Qt::red);
p.setBrush(brush);
p.drawRect(newrect);
update();
}
界面文件
https://images2017.cnblogs.com/blog/1300117/201801/1300117-20180112231423769-1357513827.png
应该是有不错的C++基础的 牛逼了老铁 高手在民间啊 厉害大神 不错,不错 两条要怎么操作啊、 aila852 发表于 2018-1-17 11:33
两条要怎么操作啊、
wasd 和 ijkl
页:
[1]