项目二 贪吃蛇

start.h

#ifndef START_H
#define START_H

#include <QWidget>
#include <QPushButton>
#include "widget.h"

class start : public QWidget
{
    Q_OBJECT

public:
    explicit start(QWidget *parent = nullptr);

signals:

public slots:
    void changeWin();

private:
    QPushButton b;
    Widget sub;

protected:
    void paintEvent(QPaintEvent*);
};

#endif // START_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QStackedWidget>
#include <QPaintEvent>
#include <QKeyEvent>
#include <QPainter>
#include <QDebug>
#include <QIcon>
#include <QTimer>
#include <QPushButton>
#include <QLineEdit>
#include <QGridLayout>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

    void layout();
    void game();
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);
    void paintEvent(QPaintEvent *);
    void init();    //初始化
    void start();    //开始游戏
    void move(int len);    //蛇身的行动逻辑
    void food();    //食物的生成与获得判定
    void is_dead();    //死亡判定

private slots:
    void auto_move();    //蛇的自动行动

private:    
    QPainter Painter;
    QTimer *timer;

    QImage image_background;
    QImage image_character1;
    QImage image_character2;
    QImage image_character3;
    QImage image_character4;
    QImage image_sword;
    QImage image_gold;

    int w;    //画面的宽度
    int h;    //画面的高度
    int speed;    //刷新一次画面所需要的时间

    int StartX;    //蛇头的横坐标
    int StartY;    //蛇头的纵坐标

    int X[1000];    //每个蛇身的横坐标
    int Y[1000];    //每个蛇身的纵坐标

    int LastX[1000];    //每个蛇身的前驱的横坐标
    int LastY[1000];    //每个蛇身的前驱的纵坐标

    int len = 0;    //蛇的总长度
    int flag = 1;    //判断是否开始
    int dead_flag = 0;    //判断蛇是否死亡

    int step=50;    //地图每一格的边长

    char dir;    //当前蛇的前进方向
    char next_dir;    //下一时刻蛇的前进方向
    int dir_flag = 0;    //判断是否转向

    int food_x;    //食物横坐标
    int food_y;    //食物纵坐标
    int food_flag = 0;    //判断场上是否有食物
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include "start.h"
#include <QApplication>
#include <QtMultimedia/QMediaPlayer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    start w;
    w.show();
    return a.exec();
}

start.cpp

#include "start.h"
#include <QPainter>
#include <QSound>

start::start(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("开始界面");

    b.setParent(this);
    b.setGeometry(250,200,400,150);
    b.setStyleSheet("QPushButton{border-image:url(:/Images/start.png);border-radius:5px;}");

    QSound *sound=new QSound(":/Images/bgm.wav",this);
    sound->setLoops(-1);
    sound->play();

    this->setFixedSize(900,600);
    connect(&b,&QPushButton::released,this,&start::changeWin);
}

void start::changeWin()
{
    sub.show();
    this->hide();
}
void start::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.drawPixmap(0,0,width(),height(),QPixmap(":/Images/background.jpg"));
}

widget.cpp

#include "widget.h"
#include <QMainWindow>
#include <QMessageBox>
#include <QSound>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(QString("贪吃蛇   当前得分:%1").arg(0));

    this -> setFixedSize(1200,800);

    image_character1.load(":/Images/LV1.png");
    image_character2.load(":/Images/LV2.png");
    image_character3.load(":/Images/LV3.png");
    image_character4.load(":/Images/LV4.png");
    image_sword.load(":/Images/sword.png");
    image_gold.load(":/Images/gold.png");
    image_background.load(":/Images/background.jpg");

    image_character1 = image_character1.scaled(step,step);
    image_character2 = image_character2.scaled(step,step);
    image_character3 = image_character3.scaled(step,step);
    image_character4 = image_character4.scaled(step,step);
    image_sword = image_sword.scaled(step,step);
    image_gold = image_gold.scaled(step,step);
    image_background = image_background.scaled(1200,800);
}

Widget::~Widget(){}

void Widget::auto_move()    //蛇的自动行动
{
    if(dir_flag==1)
    {
        dir = next_dir;
        dir_flag=0;
    }
    switch(dir)
    {
        case 'u': StartY-=step; if(StartY<0) StartY = h-step; break;
        case 'd': StartY+=step; if(StartY>h-step) StartY = 0; break;
        case 'l': StartX-=step; if(StartX<0) StartX = w-step; break;
        case 'r': StartX+=step; if(StartX>w-step) StartX = 0; break;
    }
    move(len);
    is_dead();
    food();
    update();
}

void Widget::food()    //食物的生成与获得判定
{
    int rand_x;
    int rand_y;

    if(StartX==food_x && StartY==food_y)
    {
        food_flag = 0;
        len++;
        if(len-1==15 || len-1==30 || len-1==45)
        {
            QSound *sound=new QSound(":/Images/levelup.wav",this);
            sound->setLoops(1);
            sound->play();
        }
        setWindowTitle(QString("贪吃蛇   当前得分:%1").arg(len-1));
    }

    while(food_flag==0)
    {
        int break_flag = 0;
        rand_x = qrand()%(w/step)*step;
        rand_y = qrand()%(h/step)*step;
        if(rand_x==StartX && rand_y==StartY) continue;
        for(int i=1; i<=len; i++)
        {
            if(rand_x==X[i] && rand_y==Y[i])
            {
                break_flag = 1;
                break;
            }
        }
        if(break_flag) continue;
        food_x = rand_x;
        food_y = rand_y;
        food_flag = 1;
    }
}

void Widget::start()    //开始游戏
{
    flag = 1;
    dead_flag = 0;
}

void Widget::is_dead()    //死亡判定
{
    for(int i=1; i<=len-1; i++)
    {
        if(StartX==X[i] && StartY==Y[i])
        {
            timer -> stop();
            dead_flag = 1;
            int re = QMessageBox::information(this,"游戏结束!","您最终的得分为"+QString::number(len-1)+"。\n点击确认键重新开始游戏!",QMessageBox::Yes);
            if(re==QMessageBox::Yes)
            {
                this -> start();
                setWindowTitle(QString("贪吃蛇   当前得分:%1").arg(0));
            }
        }
    }
}

void Widget::game()
{
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(auto_move()));
    timer -> start(speed);
}

void Widget::init()    //初始化
{
    speed = 239;

    w = width();
    h = height();

    StartX = 6*step;
    StartY = 4*step;

    game();
    food();

    dir = 'r';
    len = 1;

    LastX[0] = StartX;
    LastY[0] = StartY;
}

void Widget::move(int len)    //蛇身的行动逻辑
{
    for(int i=1; i<=len; i++)
    {
        LastX[i] = X[i];
        LastY[i] = Y[i];
        X[i] = LastX[i-1];
        Y[i] = LastY[i-1];
    }
    LastX[0] = StartX;
    LastY[0] = StartY;
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    if(event->key()==Qt::Key_Left && dir!='r' && dir_flag==0)
    {
        next_dir = 'l';
        dir_flag=1;
        if(dir=='l' && dead_flag==0)    //长按加速
        {
            timer -> stop();
            timer -> start(speed/12);
        }
    }
    if(event->key()==Qt::Key_Right && dir!='l' && dir_flag==0)
    {
        next_dir = 'r';
        dir_flag=1;
        if(dir=='r' && dead_flag==0)
        {
            timer -> stop();
            timer -> start(speed/12);
        }
    }
    if(event->key()==Qt::Key_Up && dir!='d' && dir_flag==0)
    {
        next_dir = 'u';
        dir_flag=1;
        if(dir=='u' && dead_flag==0)
        {
            timer -> stop();
            timer -> start(speed/12);
        }
    }
    if(event->key()==Qt::Key_Down && dir!='u' && dir_flag==0)
    {
        next_dir = 'd';
        dir_flag=1;
        if(dir=='d' && dead_flag==0)
        {
            timer -> stop();
            timer -> start(speed/12);
        }
    }

    update();
}

void Widget::keyReleaseEvent(QKeyEvent *event)    //停止长按,变回原速度
{
    if((event->key()==Qt::Key_Left || event->key()==Qt::Key_Right || event->key()==Qt::Key_Up || event->key()==Qt::Key_Down) && dead_flag==0)
    {
        timer -> stop();
        timer -> start(speed);
    }
}

void Widget::paintEvent(QPaintEvent *)
{
    QPen Pen(Qt::DotLine);
    Pen.setColor(Qt::blue);

    Painter.begin(this);
    Painter.drawImage(QPoint(0,0),image_background);
    Painter.end();

    for (int i=step;i<this->rect().width();i=i+step)
    {
        Painter.begin(this);
        Painter.setPen(Pen);
        Painter.drawLine(QPoint(i,0),QPoint(i,this->rect().height()));
        Painter.end();
    }

    for (int j=step;j<this->rect().height();j=j+step)
    {
        Painter.begin(this);
        Painter.setPen(Pen);
        Painter.drawLine(QPoint(0,j),QPoint(this->rect().width(),j));
        Painter.end();
    }

    if(flag==1)
    {
        init();
        flag = 0;
    }

    Painter.begin(this);
    if(len-1<15)
    {
        Painter.drawImage(QPoint(StartX,StartY),image_character1);
    }
    else if(len-1<30)
    {
        Painter.drawImage(QPoint(StartX,StartY),image_character2);
    }
    else if(len-1<45)
    {
        Painter.drawImage(QPoint(StartX,StartY),image_character3);
    }
    else
    {
        Painter.drawImage(QPoint(StartX,StartY),image_character4);
    }
    for(int i=1; i<=len-1; i++)
    {
        Painter.drawImage(QPoint(X[i],Y[i]),image_sword);
    }
    Painter.drawImage(QPoint(food_x,food_y),image_gold);
    Painter.end();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值