QT-贪吃小游戏


一、演示效果

在这里插入图片描述

二、关键程序

#include "Snake.h"
#include "Food.h"
#include "Stone.h"
#include "Mushroom.h"
#include "Ai.h"
#include "Game.h"
#include "Util.h"
#include "SnakeUnit.h"
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QTimer>
#include <QDebug>
#include <typeinfo.h>
#include <stdlib.h>
#include <QDesktopWidget>

extern Game *g;
QGraphicsScene *sc;
QTimer *timer;

Snake::Snake()
{
   

}

Snake::Snake(QGraphicsScene *s, QString nam, int l)
{
   
    sc = s;
    length = l;
    size = 6;
    alive = false;
    direction = "right";
    score = 1;
    count = 0;    
    speed = size+2;
    name = nam;
    type = "me";

    //snake body
    int startX = Util::screenWidth()/2;
    int startY = Util::screenHeight()/2;
    color = Util::randomSnakeColor();
    pic = ":/images/snakeUnit"+QString::number(color)+".png";
    for(int i=0; i<length; i++){
   
        SnakeUnit *e = new SnakeUnit(name, this);
        if(i==0){
   
            e->setPixmap(QPixmap(":/images/snakeUnit"+QString::number(color)+"Head.png"));
            e->setTransformOriginPoint(e->pixmap().width()/2, e->pixmap().height()/2);
        }
        else{
              
             e->setPixmap(QPixmap(pic));
             e->setZValue(-100);            
        }
        e->setPos(startX-i*size, startY);
        s->addItem(e);
        body.append(e);       
    }
    body[0]->setRotation(90);

    //boundary
    boundary = new QGraphicsEllipseItem(0, 0, 100, 100);
    boundary->setPen(QPen(Qt::transparent));
    boundary->setZValue(-1);
    s->addItem(boundary);

    //snake name
    info = new QGraphicsTextItem();
    info->setFont(QFont("calibri", 9));
    info->setPlainText(name);
    info->setDefaultTextColor(Qt::white);
    info->setPos(startX+10, startY+10);
    s->addItem(info);

    //move timer
    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), this, SLOT(move()));
    timer->start(100);
}

void Snake::move()
{
   

    if(g->snake->alive == true){
   

        //move snake
        for(int i = body.size()-1; i>=0; i--){
   

            //body
            if(i != 0){
   
                body[i]->setX(body[i-1]->x());
                body[i]->setY(body[i-1]->y());               
            }

            //head
            else{
   
                    //move according to direction
                    if(direction == "right"){
   
                        body[0]->setX(body[0]->x()+speed);
                    }

                    else if(direction == "left"){
   
                         body[0]->setX(body[0]->x()-speed);
                    }

                    else if(direction == "up"){
   
                        body[0]->setY(body[0]->y()-speed);
                    }

                    else if(direction == "down"){
   
                        body[0]->setY(body[0]->y()+speed);
                    }

                }

        }

        //move boundary
        boundary->setX(body[0]->x()-boundary->rect().width()/2);
        boundary->setY(body[0]->y()-boundary->rect().height()/2);

        //move snake name
        info->setX(body[0]->x()+10);
        info->setY(body[0]->y()+10);

        //acc according to ai type
        if(type == "normal"){
   
            //change direction randomly with low attack level
            changeRandomDirection(1);
        }

        else if(type == "chipku"){
   
             avoidThreat();

            //change direction randomly according to attack level
            changeRandomDirection(g->attackLevel);
        }

        else if(type == "courage"){
   
            //move away from threat if present
            avoidThreat();

            //change direction randomly with low attack level
            changeRandomDirection(1);
        }

        else if(type == "paytu"){
   

            avoidThreat();

            //eat nearby food
            QList<QGraphicsItem *> food_items = boundary->collidingItems();
            for(int i=0; i<food_items.size(); i++){
   
                if(typeid(*(food_items[i])) == typeid(Food) || (typeid(*(food_items[i])) == typeid(Mushroom))){
   
                    //if food has minimum life of 2 seconds
                    Food *f = (Food*)food_items[i];
                    if(f->life > 1){
   
                        QString d = Util::giveDirection(body[0]->x(), body[0]->y(), f->x(), f->y());
                        if(d != Util::oppositeDirection(direction)){
   
                            changeDirection(d);
                            qDebug()<<"Food";
                        }
                    }
                }
            }
        }

        //check collssion
        QList<QGraphicsItem *> colliding_items = body[0]->collidingItems();
        for(int i=0; i<colliding_items.size(); i++){
   

            //food
            if(typeid(*(colliding_items[i])) == typeid(Food)){
   

                body[0]->scene()->removeItem(colliding_items[i]);
                delete colliding_items[i];                
                count+=2;

                //update length at each 10 score
                if(count > 10){
   
                    score++;
                    count = 0;
                    g->updateScore();

                    //append one unit
                    SnakeUnit *e = new SnakeUnit(name, this);
                    e->setPixmap(QPixmap(pic));
                    e->setPos(-100,-100);
                    body[0]->scene()->addItem(e);
                    body.append(e);
                }
            }

            // Mushroom
            else if(typeid(*(colliding_items[i])) == typeid(Mushroom)){
   
                g->scene->removeItem(colliding_items[i]);
                delete colliding_items[i];
                count+=5;
                g->updateScore();
            }

            //stone
            else if(typeid(*(colliding_items[i])) == typeid(Stone)){
                  
                destroy();
                break;
            }

            //other snake
            else if(typeid(*(colliding_items[i])) == typeid(SnakeUnit) && ((SnakeUnit*)colliding_items[i])->parent != this){
   
                qDebug()<<"Collission " + name + " : " + ((SnakeUnit*)colliding_items[i])->name;
                destroy();
                break;
            }

        }

        //check screen-bounds
        if(body[0]->x() > sc->width()) body[0]->setX(0);
        else if(body[0]->x() < 0) body[0]->setX(sc->width());
        else if(body[0]->y() < 0) body[0]->setY(sc->height());
        else if(body[0]->y() > sc->height()) body[0]->setY(0);
     }
}

void Snake::destroy(){
   

    //remove yourself and turn into clouds
    for(int i=0; i<body.size(); i++){
   
        SnakeUnit *s = body[i];
        new Food(sc, 1, 1, s->x(), s->y());
        g->scene->removeItem(s); //remove body from scene
    }
     g->scene->removeItem(info); //remove info from scene
    alive = false;
    g->snakes.removeOne(this);
    Util::removeReservedName(this->name);
    Util::removeReservedColor(this->color);
     g->scene->removeItem(this->boundary);

    //delete ai from memory
    if(type == "ai"){
           
        delete this;
    }

    //add new snake
    g->generateAi(1);
}

void Snake::changeDirection(QString dir){
   
    if(dir=="right" && direction != "left"){
   
        direction = "right";
        body[0]->setRotation(0);
        body[0]->setRotation(90);
    }
    else if(dir=="left" && direction != "right"){
   
        direction = "left";
        body[0]->setRotation(0);
        body[0]->setRotation(-90);
    }
    else if(dir=="up" && direction != "down"){
   
        direction = "up";
        body[0]->setRotation(0);
    }
    else if(dir=="down" && direction != "up"){
   
        direction = "down";
        body[0]->setRotation(0);
        body[0]->setRotation(180);
    }
}

void Snake::changeRandomDirection(int attackLevel){
   
    if(Util::random(0,10) % 2 == 0){
   

        //change direction
        int r = Util::random(0,3+attackLevel);

        if(r==0 && direction != "left"){
   
            changeDirection("right");
        }
        else if(r==1 && direction != "right"){
   
            changeDirection("left");
        }
        else if(r==2 && direction != "down"){
   
            changeDirection("up");
        }
        else if(r==3 && direction != "up"){
   
            changeDirection("down");
        }

        //move towards the player
        else if(r>3){
   
            QString d = Util::giveDirection(body[0]->x(), body[0]->y(), g->snake->body[0]->x(), g->snake->body[0]->y());
            if(direction != Util::oppositeDirection(d)) changeDirection(d);
        }
    }
}

void Snake::avoidThreat(){
   
    bool threat = false;
    int threatPointX, threatPointY;
    QList<QGraphicsItem *> boundary_items = boundary->collidingItems();
    for(int i=0; i<boundary_items.size(); i++){
   
        //if its other's boundary or body
        if(typeid(*(boundary_items[i])) == typeid(QGraphicsEllipseItem) || (typeid(*(boundary_items[i])) == typeid(SnakeUnit)) || (typeid(*(boundary_items[i])) == typeid(Stone))){
   
            threat = true;
            threatPointX = (boundary_items[i])->x();
            threatPointY = (boundary_items[i])->y();
        }
    }
    if(threat == true){
   
        QString d = Util::giveDirection(body[0]->x(), body[0]->y(), threatPointX, threatPointY);
        if(d != Util::oppositeDirection(direction)){
   
            changeDirection(Util::oppositeDirection(d));
            qDebug()<<"Threat kiled";
        }
    }
}


三、下载链接

https://download.csdn.net/download/u013083044/88758860

相关推荐

  1. 贪吃游戏

    2024-01-19 05:22:01       36 阅读
  2. 贪吃游戏

    2024-01-19 05:22:01       27 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-19 05:22:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-19 05:22:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-19 05:22:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-19 05:22:01       20 阅读

热门阅读

  1. GPT-4技术报告的解读(一)

    2024-01-19 05:22:01       30 阅读
  2. 计算机(函数指针实现)

    2024-01-19 05:22:01       29 阅读
  3. 大白话解析LevelDB: VersionEdit

    2024-01-19 05:22:01       33 阅读
  4. HBASE学习一:原理架构详解

    2024-01-19 05:22:01       33 阅读
  5. C语言:被5整除问题

    2024-01-19 05:22:01       36 阅读
  6. RV1106移植心得

    2024-01-19 05:22:01       38 阅读
  7. linux修改文件名的三种方法有哪些

    2024-01-19 05:22:01       31 阅读
  8. Android 13 - Media框架(26)- MPEG4Extractor

    2024-01-19 05:22:01       30 阅读
  9. Python Web开发:构建高效、可扩展的Web应用

    2024-01-19 05:22:01       29 阅读
  10. qss的使用

    2024-01-19 05:22:01       34 阅读
  11. Python列表append()函数使用详解

    2024-01-19 05:22:01       32 阅读