基于QT的贪吃蛇(打包成可以运行在安卓系统下的apk文件)

基于QT的贪吃蛇(打包成可以运行在安卓系统下的apk文件)

写在前面:
1.QT程序下的安卓开发。可以将QT的代码编译成apk文件。
2.在QT上开发安卓,需要搭建环境。记得需要下几件东西,相当麻烦。可以搜索其他文章了解
3.QT上开发安卓,需要注意的是,界面布局问题。否则移植到安卓设备上后界面比例很难看

先看看截图

在这里插入图片描述

全部代码(本人的Qt环境是 QT5.9.3)

qtsnake.h文件



#ifndef QTSNAKE_H
#define QTSNAKE_H
#include<QPainter>
#include<QList>
#include<QTimer>
#include<QKeyEvent>
#include<QRectF>//矩形类
#include<QPen>
#include<QBrush>
#include<QDebug>
#include<QTime>
#include <QWidget>
#include<QFrame>
#include<QPushButton>
#include<QMessageBox>

namespace Ui {
class QtSnake;
}

class QtSnake : public QWidget
{
    Q_OBJECT

public:
    explicit QtSnake(QWidget *parent = 0);
    ~QtSnake();
protected:
    void paintEvent(QPaintEvent *);//绘图事件
    //void keyPressEvent(QKeyEvent *);//鼠标点击事件
private:
    void addTopRectF();//向上按
    void addLeftRectF();//向左按
    void addDownRectF();//向下按
    void addRightRectF();//向右按
    bool snakeStrike();//蛇撞到自己
    void deleteLastRectF();
    void gameEnd();//游戏结束

    enum Move{Up,Down,Left,Right};//移动的方向
  private slots:
    void timeOut();
    void rewardTimeOut();
    void btn_start_fun();
     void btn_up_fun();
     void btn_down_fun();
     void btn_left_fun();
     void btn_right_fun();
     void btn_about_fun();

private:
    //Ui::QtSnake *ui;

    QList<QRectF>snake;//蛇本体
    int snakeNodeWidth = 20;// 蛇的每一节都是正方形的格子边长为10
    int snakeNodeHeight = 20;
    QTimer*timer;
    QTimer*rewardTimer;
    int time =100;
    int moveFlag =Up;
    bool gameOver =false;
    bool gameStart = false;
    QList<QRectF>rewardNode;//奖励节点
    //void Painter();
    //bool eventFilter(QObject *watched, QEvent *event);
    QPushButton*btn_start;
    QPushButton*btn_up;
    QPushButton*btn_down;
    QPushButton*btn_left;
    QPushButton*btn_right;
    QPushButton*btn_about;
};

#endif // QTSNAKE_H

qtsnake.cpp文件


#include "qtsnake.h"


QtSnake::QtSnake(QWidget *parent) :
        QWidget(parent)

{
    this->setFixedSize(400,800);
    this->setWindowTitle("山寨版贪吃蛇");
    //设置窗口为黑色
    //setStyleSheet("QWidget{background:black}");
    snake.append(QRectF(200,550,snakeNodeWidth,snakeNodeHeight));
    addTopRectF();
    addTopRectF();
    //生成第一个奖励节点(食物)
    rewardNode.append(QRectF(200,400,snakeNodeWidth,snakeNodeHeight));
    btn_start=new QPushButton("开始游戏",this);

    connect(btn_start,SIGNAL(clicked()),this,SLOT(btn_start_fun()));
    btn_up =new QPushButton("上",this);
    //btn_up->move(this->width()/4,this->height()*39/48);

    connect(btn_up,SIGNAL(clicked()),this,SLOT(btn_up_fun()));
    btn_left =new QPushButton("左",this);

    connect(btn_left,SIGNAL(clicked()),this,SLOT(btn_left_fun()));
    btn_down =new QPushButton("下",this);

    connect(btn_down,SIGNAL(clicked()),this,SLOT(btn_down_fun()));
    btn_right =new QPushButton("右",this);

    connect(btn_right,SIGNAL(clicked()),this,SLOT(btn_right_fun()));
    btn_about =new QPushButton("关于",this);

    connect(btn_about,SIGNAL(clicked()),this,SLOT(btn_about_fun()));
    timer = new QTimer;
    connect(timer,SIGNAL(timeout()),this,SLOT(timeOut()));
    rewardTimer = new QTimer;
    connect(rewardTimer,SIGNAL(timeout()),this,SLOT(rewardTimeOut()));

}

void QtSnake::btn_start_fun()
{
    if(!gameStart && !gameOver) {
        timer->start(time);
        rewardTimer->start(time*30);
        gameStart = true;
    } else if(gameOver&&gameStart) {
        timer->start(time);
        rewardTimer->start(time*30);
        //gameStart = true;
    }
    /*timer->start(time);
    rewardTimer->start(time*30);
    gameStart=true;*/

}
void QtSnake::btn_up_fun()
{
    if(moveFlag !=Down) {
        moveFlag =Up;
    }

}
void QtSnake::btn_left_fun()
{
    if(moveFlag != Right) {
        moveFlag = Left;
    }
}
void QtSnake::btn_down_fun()
{
    if(moveFlag !=Up) {
        moveFlag = Down;
    }
}
void QtSnake::btn_right_fun()
{
    if(moveFlag !=Left) {
        moveFlag = Right;
    }
}
void QtSnake::btn_about_fun()
{
   QMessageBox::information(this,"开发者信息","完成日期:2020/02/21\n名称:山寨版贪吃蛇\n作者:Edison\n开发工具:QT5.9.3\n",QMessageBox::Ok|QMessageBox::Cancel,QMessageBox::Ok);
}
//界面刷新
void QtSnake::timeOut()
{
    int  flag =1;
    for(int i =0;i<rewardNode.length();i++)
    {
        if(rewardNode.at(i).contains(snake.at(0).topLeft()
                                     +QPointF(snakeNodeWidth/2,snakeNodeHeight/2))) {
            if(rewardNode.at(i).width()>snakeNodeWidth) {//大食物
                flag+=2;

            }
            flag++;//正常食物
            rewardNode.removeAt(i);
            break;
        }

    }
    while(flag--){
        switch(moveFlag) {
        case Up:
            addTopRectF();
            break;
        case Down:
            addDownRectF();
            break;
        case Left:
            addLeftRectF();
            break;
        case Right:
            addRightRectF();
            break;
        default:
            break;
        }
    }
    deleteLastRectF();
    update();
}
// 随机食物生成
void QtSnake::rewardTimeOut()
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    if(rewardNode.length() > 5) {
        rewardNode.removeAt(qrand()%5);
    }
    rewardNode.append(QRectF(qrand()%(this->width()*17/20)+this->width()/20,qrand()%(this->height()*3/4-(this->width()/20))+this->width()/20,snakeNodeWidth,snakeNodeHeight));
    if(qrand()%5 == 3) {
        rewardNode.append(QRectF(qrand()%(this->width()*17/20)+this->width()/20,qrand()%(this->height()*3/4-(this->width()))+this->width(),snakeNodeWidth*2,snakeNodeHeight*2));
    }
}
//向上移动吃食物增加蛇身体
void QtSnake::addTopRectF()
{
    snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(0,-snakeNodeHeight),snake.at(0).topRight()));

}
//向下
void QtSnake::addDownRectF()
{
    snake.insert(0,QRectF(snake.at(0).bottomLeft(),snake.at(0).bottomRight()+QPointF(0,snakeNodeHeight)));
}
//向左
void QtSnake::addLeftRectF()
{
    snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(-snakeNodeWidth,0),snake.at(0).bottomLeft()));
}
//向右
void QtSnake::addRightRectF()
{
    snake.insert(0,QRectF(snake.at(0).topRight(),snake.at(0).bottomRight()+QPointF(snakeNodeWidth,0)));
}
//绘图事件
void QtSnake::paintEvent(QPaintEvent *event)
{
    btn_start->move(this->width()*95/400,this->height()*21/24);
    btn_about->move(this->width()*75/100,this->height()*20/24);
    btn_right->move(this->width()/2,this->height()*21/24);
    btn_left->move(this->width()/80,this->height()*21/24);
    btn_down->move(this->width()/4,this->height()*45/48);
    btn_up->move(this->width()/4,this->height()*39/48);
    QPainter painter(this);//创建画家对象
    QPen pen;//创建画笔对象(一般用来绘制轮廓)
    QBrush brush;//创建笔刷对象(一般用来填充)
    QFont font("方正舒体",12,QFont::ExtraLight,false);//字体样式
    //反锯齿(这种就要记住如何使用)
    painter.setRenderHint(QPainter::Antialiasing);
    pen.setColor(Qt::black);//设置画笔颜色
    brush.setColor(Qt::black);//设置笔刷颜色
    brush.setStyle(Qt::SolidPattern);//填充模式
    painter.setPen(pen);
    painter.setBrush(brush);
    painter.drawRect(QRect(this->width()/20,this->width()/20,this->width()*9/10,this->height()*3/4));//画矩形方框
    pen.setColor(Qt::green);//设置画笔颜色
    brush.setColor(Qt::black);//设置笔刷颜色
    painter.setPen(pen);
    painter.setBrush(brush);
    //画蛇
    for(int i =0;i<snake.length();i++)
    {
        if(i == 0) {
            painter.drawEllipse(snake.at(i));
        } else {
            painter.drawRect(snake.at(i));
        }
    }
    brush.setColor(Qt::red);
    painter.setBrush(brush);
    //画食物
    for(int i=0;i<rewardNode.length();i++)
    {
        painter.drawEllipse(rewardNode.at(i)); //画椭圆
    }
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.setFont(font);
    painter.drawText(this->width()*9/200,this->width()*9/200,QString("当前分数: ")+QString("%1").arg(snake.length()));
    if(snakeStrike()||(snake.at(0).x()-snakeNodeWidth <this->width()/20-snakeNodeWidth*3/4)//向左边撞墙
            ||(snake.at(0).x()+snakeNodeWidth*2 > this->width()*9/10+snakeNodeWidth*2)//向右边撞墙
            ||(snake.at(0).y()+snakeNodeHeight*2 > this->height()*3/4+2*snakeNodeHeight)//向下撞墙
            ||(snake.at(0).y()-snakeNodeHeight < this->width()/20-snakeNodeWidth)){//向上撞墙
        gameEnd();
        painter.setFont(font);
        painter.drawText((this->width()-40)/2,(this->height()-30)/2,QString("GAME OVER!"));
    }
    QWidget::paintEvent(event);
}

// 删除蛇本体最后一个数据
void QtSnake::deleteLastRectF()
{
    snake.removeLast();
}
//判断蛇是否与身体相撞
bool QtSnake::snakeStrike()
{
    for(int i=0;i<snake.length();i++)
    {
        for(int j =i+1;j<snake.length();j++)
        {
            if(snake.at(i) == snake.at(j)) {
                return true;
            }
        }
    }
    return false;
}
// 游戏结束
void QtSnake::gameEnd()
{
    timer->stop();
    rewardTimer->stop();
    gameOver = true;
}
QtSnake::~QtSnake()
{
    //delete ui;
}

代码还有很多不足之处,就是边缘撞墙死亡的可能有点小bug,因为我是按照固定尺寸设计单个格子大小的,但是不影响使用。主要是设计思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值