QT-贪吃小游戏

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/332116.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Linux 进程(五)] 程序地址空间深度剖析

文章目录 1、前言2、什么是进程地址空间&#xff1f;3、进程地址空间的划分4、虚拟地址与物理地址的关系5、页表的作用扩展 6、为什么要有地址空间&#xff1f; 1、前言 Linux学习路线比较线性&#xff0c;也比较长&#xff0c;因此一个完整的知识点学习就会分布在两篇文章中&…

zabbix客户端配置及自定义监控

部署zabbix客户机 1.服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 2.服务端和客户端都设置 hosts 解析 cat > /etc/hosts << EOF 172.16.23.16 localhost 172.16.23.17 zbx-server EOF 3.被监控端 //设置 zabbix 的下载源&…

年龄性别预测1:年龄性别数据集说明(含下载地址)

年龄性别预测1&#xff1a;年龄性别数据集说明(含下载地址) 目录 年龄性别预测1&#xff1a;年龄性别数据集说明(含下载地址) 1.前言 2.MegaAge_Asian 3.MORPH 4.IMDB-WIKI 5.数据集下载 6.年龄性别预测和识别(Python/C/Android) 1.前言 本项目将实现年龄性别预测和识…

『 C++ 』红黑树RBTree详解 ( 万字 )

文章目录 &#x1f996; 红黑树概念&#x1f996; 红黑树节点的定义&#x1f996; 红黑树的插入&#x1f996; 数据插入后的调整&#x1f995; 情况一:ucnle存在且为红&#x1f995; 情况二:uncle不存在或uncle存在且为黑&#x1f995; 插入函数代码段(参考)&#x1f995; 旋转…

【C++入门】C++ STL中string常用函数用法总结

目录 前言 1. string使用 2. string的常见构造 3. string类对象的访问及遍历 迭代器遍历&#xff1a; 访问&#xff1a; 4. string类对象的容量操作 4.1 size和length 4.2 clear、empty和capacity 4.3 reserve和resize reserve resize 5. string类对象的修改操作 push_back o…

version-polling一款用于实时检测 web 应用更新的 JavaScript 库

为了解决后端部署之后&#xff0c;如何通知用户系统有新版本&#xff0c;并引导用户刷新页面以加载最新资源的问题。 实现原理 1.使用 Web Worker API 在浏览器后台轮询请求页面&#xff0c;不会影响主线程运行。 2.命中协商缓存&#xff0c;对比本地和服务器请求响应头etag字…

施耐德PLCTM200CE 如何实现远程上传下载程序?

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接PLC一台施耐德TM200CE PLC及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&#xff0…

Unity3D和three.js的比较

一、Unity3D和three.js简介 Unity3D是一款跨平台的游戏引擎,可以用于开发2D和3D游戏。它提供了一个可视化的开发环境,包含了强大的编辑器和工具,使开发者可以方便地创建游戏场景、添加物体、设置物理效果、编写脚本等。Unity3D支持多种平台,包括PC、移动设备、主机等,可以…

HBuilder 创建的 Uui-App项目 如何发布到微信小程序

需提前准备的工具&#xff1a;HBuilder X &#xff0c;微信开发者工具 目录 一、微信小程序账号申请 二、在微信开发者工具中打开服务端口 三、 在HBuilder创建Uni-App项目&#xff0c;并与微信小程序开发工具进行交互预览测试 四、 发布Uni-App项目 五、 微信线上发布运行 …

PXE和kickstart无人值守安装

PXE高效批量网络装机 引言 1.系统装机的引导方式 启动 操作 系统 1.硬盘 2.光驱&#xff08;u盘&#xff09; 3.网络启动 pxe 重装系统&#xff1f; 在已有操作系统 新到货了一台服务器&#xff0c; 装操作系统 系统镜像 u盘 光盘 pe&#xff1a; 小型的 操作系统 在操…

(一)SpringBoot3---尚硅谷总结

示例Demo&#xff1a; 1、我们先来创建一个空工程&#xff1a; 2、我们通过Maven来创建一个Module&#xff1a; JDK版本需要选择17以及以上&#xff0c;如果没有的话你就下载一个&#xff1a; 3、让此Maven项目继承父项目: 所有的Springboot项目都必须继承自spring-boot-start…

【PS】PS设计图欣赏、学习、借鉴

【PS】PS设计图欣赏、学习、借鉴 bilibili萌新PS学习计划&#xff1a;PS教程全套零基础教学视频&#xff08;全套81节全新版本&#xff09;

编译FFmpeg4.3.1 、x264并移植到Android

1、前言 FFmpeg 既是一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件。 2、准备工作 系统&#xff1a;LinuxNDK&#xff1a;android-ndk-r21b-linux-x86_64.zipFFmpeg&#xff1a;ffmpeg-snapshot.tar.bz2x264&#xff1a;x264 3、下载NDK 在linux环境中…

window11环境安装jdk17并配置环境变量

目录 一、下载地址二、安装步骤三、环境变量配置四、环境变量配置是否成功的测试 一、下载地址 https://www.oracle.com/java/technologies/downloads/#jdk17-windows 二、安装步骤 双击已下载的 jdk-17_windows-x64_bin.exe 安装包&#xff0c;点击【下一步】&#xff0c;…

Python-基础篇-类与对象/面向对象程序设计-py脚本

面向对象基础 第一个面向对象 class Cat:def eat(self):print("小猫爱吃鱼")def drink(self):print("小猫要喝水")# 创建猫对象 tom Cat()tom.eat() tom.drink()print(tom)addr id(tom) print("%x" % addr)新建两个猫对象 class Cat:def ea…

Docker安装与启动

Docker概述 Docker是一个快速交付应用、运行应用的技术&#xff1a; 可以将程序及其依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器&#xff0c;各个应用互不干扰启动、移除都可以通过一行命令完成&#xff0c;方便…

力扣精选算法100题——找到字符串中所有字母异位词(滑动窗口专题)

本题链接&#x1f449;找到字符串中所有字母异位词 第一步&#xff1a;了解题意 给定2个字符串s和p&#xff0c;找到s中所有p的变位词的字串&#xff0c;就是p是"abc",在s串中找到与p串相等的字串&#xff0c;可以位置不同&#xff0c;但是字母必须相同&#xff0c;比…

ChatGPT 未来学习手册

原文&#xff1a;Learn ChatGPT: The Future of Learning 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 “学习 ChatGPT”是任何对人工智能在教育中的作用感兴趣的人必读的书。这本开创性的书探讨了 ChatGPT 的潜力&#xff0c;这是一个强大的人工智能平台&#xff0…

macOS向ntfs格式的移动硬盘写数据

最近想把日常拍摄的照片从SD存储卡中转存到闲置的移动硬盘中&#xff0c;但是转存的时候发现&#xff0c;mac只能读我硬盘里的东西&#xff0c;无法将数据写入到移动硬盘中&#xff0c;也无法删除移动硬盘的数据。后来在网上查了许久资料&#xff0c;终于可实现mac对移动硬盘写…

EasyX图形化学习(三)

1.帧率&#xff1a; 即每秒钟界面刷新次数&#xff0c;下面以60帧为例&#xff1a; 1.数据类型 clock_t&#xff1a; 用来保存时间的数据类型。 2.clock( ) 函数&#xff1a; 用于返回程序运行的时间,无需参数。 3.例子&#xff1a; 先定义所需帧率&#xff1a; const …