吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3670|回复: 7
收起左侧

[其他原创] QT实现两条贪吃蛇

[复制链接]
夏日已末 发表于 2018-1-16 23:47
最终效果图


刚学qt两个礼拜,代码编的比较差,望各位看官海涵。
代码如下:
02_Snake.pro
[C++] 纯文本查看 复制代码
#-------------------------------------------------[/backcolor]#
# 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
[C++] 纯文本查看 复制代码
#ifndef ALLPARAMETER_H
#define ALLPARAMETER_H


extern QVector<QRect>  rects; //存放第一条蛇
extern QVector<QRect>  rectsfight;//存放第二条蛇
extern QRect newrect;  //存放食物
//两条蛇的方向状态标志
extern int state,statefight;
extern int begin[2];
//方框长度和高度,列数,行数
extern int g_length,g_width,g_lines,g_rows;



#endif // ALLPARAMETER_H


mythread.h
[C++] 纯文本查看 复制代码
#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
[C++] 纯文本查看 复制代码
#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
[C++] 纯文本查看 复制代码
#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}


mythread.cpp
[C++] 纯文本查看 复制代码
#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[rects.size()-1]).left()==newrect.left())&&(rects[rects.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                          con=0;
                   }
                    newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
           }
        else
        {
              rects.push_back(QRect((rects[rects.size()-1].left()),(rects[rects.size()-1].top())-g_width,g_length,g_width));
              rects.removeAt(0);
        }

        break;
   //往左吃
    case 1: 
        if(((rects[rects.size()-1]).left()-g_length==newrect.left())&&(rects[rects.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                  con=0;
           }
                 newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
           }
        else
        {
            rects.push_back(QRect((rects[rects.size()-1].left())-g_length,(rects[rects.size()-1].top()),g_length,g_width));
            rects.removeAt(0);
        }

        break;
    //往下吃
    case 2:
        if(((rects[rects.size()-1]).left()==newrect.left())&&(rects[rects.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                  con=0;
           }
                 newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
           }
        else
        {
            rects.push_back(QRect((rects[rects.size()-1].left()),(rects[rects.size()-1].top())+g_width,g_length,g_width));
                rects.removeAt(0);
        }

        break;
        //往右吃
    case 3:
        if(((rects[rects.size()-1]).left()+g_length==newrect.left())&&(rects[rects.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                  con=0;
           }
                 newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
           }
        else
        {
            rects.push_back(QRect((rects[rects.size()-1].left())+g_length,(rects[rects.size()-1].top()),g_length,g_width));
                rects.removeAt(0);
        }

        break;
     }
    //将第一位删除
   // rects.removeAt(0);


    //判断另一条蛇
    switch(statefight)
         {
        //往下吃
         case 0:
             if(((rectsfight[rectsfight.size()-1]).left()==newrect.left())&&(rectsfight[rectsfight.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                       con=0;
                }
                      newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
                }
             else
             {
                 rectsfight.push_back(QRect((rectsfight[rectsfight.size()-1].left()),(rectsfight[rectsfight.size()-1].top())-g_width,g_length,g_width));
                 rectsfight.removeAt(0);
             }

             break;
             //往往左吃
         case 1:
             if(((rectsfight[rectsfight.size()-1]).left()-g_length==newrect.left())&&(rectsfight[rectsfight.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                       con=0;
                }
                      newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
                }
             else
             {
                 rectsfight.push_back(QRect((rectsfight[rectsfight.size()-1].left())-g_length,(rectsfight[rectsfight.size()-1].top()),g_length,g_width));
                 rectsfight.removeAt(0);
             }

             break;
             //往上吃
         case 2:
             if(((rectsfight[rectsfight.size()-1]).left()==newrect.left())&&(rectsfight[rectsfight.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                       con=0;
                }
                      newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
                }
             else
             {
                rectsfight.push_back(QRect((rectsfight[rectsfight.size()-1].left()),(rectsfight[rectsfight.size()-1].top())+g_width,g_length,g_width));
                rectsfight.removeAt(0);
             }

             break;
             //往右吃
         case 3:
             if(((rectsfight[rectsfight.size()-1]).left()+g_length==newrect.left())&&(rectsfight[rectsfight.size()-1].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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width)))&&!(rectsfight.contains(QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
                                   con=0;
                            }
                              newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
                }
             else
             {
                 rectsfight.push_back(QRect((rectsfight[rectsfight.size()-1].left())+g_length,(rectsfight[rectsfight.size()-1].top()),g_length,g_width));
                 rectsfight.removeAt(0);
             }

             break;
          }



    //判断碰撞
   if(
            //第一条
            ((rects[rects.size()-1]).left()<=begin[0]-g_length)  //碰到左边
            ||((rects[rects.size()-1]).left()>=(begin[0]+g_rows*g_length)) //碰到右边
            ||((rects[rects.size()-1]).top()<=begin[1]-g_width)  //碰到上边
            ||((rects[rects.size()-1]).top()>=(begin[1]+g_width*g_lines)) //碰到下边
            //第二条
            ||((rectsfight[rectsfight.size()-1]).left()<=begin[0]-g_length)
            ||((rectsfight[rectsfight.size()-1]).left()>=(begin[0]+g_rows*g_length))
            ||((rectsfight[rectsfight.size()-1]).top()<=begin[1]-g_width)
            ||((rectsfight[rectsfight.size()-1]).top()>=(begin[1]+g_width*g_lines))
         )
    {

        //发出碰撞信号
       emit Touch();
        //清除两条蛇
        rects.clear();
        rectsfight.clear();
        //生成新的地图
        rects.push_back(QRect(begin[0]+g_length*(g_rows/4),begin[1]+g_width*(g_lines/4),g_length,g_width));
        rectsfight.push_back(QRect(begin[0]+g_length*(g_rows*3/4),begin[1]+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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
               con=0;
        }
         newrect=QRect(begin[0]+g_length*a,begin[1]+g_width*b,g_length,g_width);
   }
    //重新生成地图
    image=QImage(begin[0]*2+g_length*g_rows,begin[1]+(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[0],begin[1]+g_width*i,begin[0]+g_rows*g_length,begin[1]+g_width*i));
    }
    for(int i=0;i<=g_rows;i++)
      {
        lines.push_back(QLine(begin[0]+g_length*i,begin[1],begin[0]+g_length*i,begin[1]+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
[C++] 纯文本查看 复制代码
#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[2]={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[0]*2+g_length*g_rows,begin[1]+(g_width+3)*g_lines);
    //调整控件位置
    ui->pushButton->move((begin[0]+g_length*(g_rows/2-1))-ui->pushButton->width()-ui->label->width(),begin[1]+(g_width+1)*g_lines);
    ui->label->move((begin[0]+g_length*(g_rows/2))-ui->label->width()-2,begin[1]+(g_width+1)*g_lines);
    ui->lineEdit->move((begin[0]+g_length*(g_rows/2)),begin[1]+(g_width+1)*g_lines+2);
    ui->pushButton_2->move((begin[0]+g_length*(g_rows/2+1))+ui->lineEdit->width(),begin[1]+(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[0]+g_length*(g_rows/4),begin[1]+g_width*(g_lines/4),g_length,g_width));
    rectsfight.push_back(QRect(begin[0]+g_length*(g_rows*3/4),begin[1]+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[0]+g_length*a,begin[1]+g_width*b,g_length,g_width))))
           con=0;
    }
     newrect=QRect(begin[0]+g_length*a,begin[1]+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[0],begin[1]+g_width*i,begin[0]+g_rows*g_length,begin[1]+g_width*i));
    }
    for(int i=0;i<=g_rows;i++)
      {
        lines.push_back(QLine(begin[0]+g_length*i,begin[1],begin[0]+g_length*i,begin[1]+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();
}


界面文件

捕获.JPG




捕获.JPG

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
唯有我最酷 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Yang|阳 发表于 2018-1-17 00:19
应该是有不错的C++基础的
吊名想三天 发表于 2018-1-17 00:53 来自手机
wax126 发表于 2018-1-17 01:51 来自手机
szhy007 发表于 2018-1-17 02:03
厉害  大神
kingswb 发表于 2018-1-17 06:51 来自手机
不错,不错
aila852 发表于 2018-1-17 11:33
两条要怎么操作啊、
 楼主| 夏日已末 发表于 2018-1-17 16:47
aila852 发表于 2018-1-17 11:33
两条要怎么操作啊、

wasd 和 ijkl
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 10:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表