qt 坦克大战游戏 GUI绘制

关于本章节中使用的图形绘制类,如QGraphicsView、QGraphicsScene等的详细使用说明请参见我的另一篇文章:

《图形绘制QGraphicsView、QGraphicsScene、QGraphicsItem、Qt GUI-CSDN博客》

本文将模仿坦克大战游戏,目前只绘制出一辆坦克,并能发射炮弹

源代码下载地址:https://download.csdn.net/download/zhouhui1982/88784330

main.cpp文件中代码

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QKeyEvent>
#include <QTimer>

//坦克类对象,构建坦克主体
class Tank : public QGraphicsRectItem {
public:
    Tank() {
        // 坦克身体
        setRect(0, 0, 30, 50);
        setBrush(Qt::blue);

        // 炮塔
        turret = new QGraphicsRectItem(10, -20, 10, 30);
        turret->setParentItem(this);

        // 设置炮塔颜色
        turret->setBrush(Qt::red);
    }

    //重写键盘事件,判断上下左右、空格按钮
    void keyPressEvent(QKeyEvent *event) override {
        // Handle key presses to control the tank
        switch (event->key()) {
        case Qt::Key_Left:
            moveBy(-10, 0);
            break;
        case Qt::Key_Right:
            moveBy(10, 0);
            break;
        case Qt::Key_Up:
            moveBy(0, -10);
            break;
        case Qt::Key_Down:
            moveBy(0, 10);
            break;
        case Qt::Key_Space: //如果是空格键,发射炮弹
            //绘制第一发炮弹
            QGraphicsEllipseItem *bulletItem = new QGraphicsEllipseItem(0, 0, 5, 10);
            bulletItem->setPos(mapToScene(12, -50));
            bulletItem->setBrush(Qt::red);
            scene()->addItem(bulletItem);

            //记录第一发炮弹位置
            QPointF pos = bulletItem->pos();

            //每隔500ms,发射下一发炮弹,看着像连续的动画效果
            QTimer::singleShot(500, [=]() {
                //移除第一发炮弹
                scene()->removeItem(bulletItem);

                //绘制第二发炮弹
                QGraphicsEllipseItem *bulletItem1 = new QGraphicsEllipseItem(0, 0, 5, 10);
                bulletItem1->setPos(pos.x(), pos.y() - 30);
                bulletItem1->setBrush(Qt::red);
                scene()->addItem(bulletItem1);

                QTimer::singleShot(500, [=]() {
                    //移除第二发炮弹
                    scene()->removeItem(bulletItem1);

                    //绘制第三发炮弹
                    QGraphicsEllipseItem *bulletItem2 = new QGraphicsEllipseItem(0, 0, 5, 10);
                    bulletItem2->setPos(pos.x(), pos.y() - 80);
                    bulletItem2->setBrush(Qt::red);
                    scene()->addItem(bulletItem2);

                    QTimer::singleShot(500, [=]() {
                        //移除第三发炮弹
                        scene()->removeItem(bulletItem2);
                    });
                });
            });

            break;
//        default:
//            break;
        }
    }
private:
    QGraphicsRectItem *turret; // 炮塔

};

//绘制主画布
class TankGame : public QGraphicsView {
public:
    TankGame() {
        scene = new QGraphicsScene(this); // 2D 图形 画布
        setScene(scene);

        //创建tank实例
        tank = new Tank();
        //加载tank实例到画布
        scene->addItem(tank);

        //抗锯齿渲染 减少图形边缘的锯齿状效果 使得图形看起来更加清晰和平滑
        setRenderHint(QPainter::Antialiasing);
        //平滑的像素变换渲染 用于对图片进行变换(如旋转、缩放等)时保持图片的平滑性
        setRenderHint(QPainter::SmoothPixmapTransform);
        //边界框发生变化时进行更新
        setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
        //高质量抗锯齿渲染 与上边的代码类似 但是这个设置更加强调图形的质量而不是性能
        setRenderHint(QPainter::HighQualityAntialiasing);
        //设置了 画布 的大小为 800x600 像素
        setFixedSize(800, 600);

    }

//画布的键盘事件,调用tank类中的键盘事件
protected:
    void keyPressEvent(QKeyEvent *event) override {
        // Forward key events to the tank
        tank->keyPressEvent(event);
    }

private:
    QGraphicsScene *scene; //画布实例
    Tank *tank; //坦克实例
};

//主函数
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //声明画布
    TankGame tankGame;
    //显示画布
    tankGame.show();

    return a.exec();
}
 

tank.pro文件中代码

QT -= core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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 it uses 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

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
 

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

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

相关文章

应急消防应用步入“繁花”时代,卓翼智能消防无人机顺势而行大有可为

近日&#xff0c;北京卓翼智能科技有限公司&#xff08;以下简称“卓翼智能”&#xff09;宣布完成超亿元B轮融资&#xff0c;融资金额高达2.5亿元。这个“智能无人系统”黑马品牌&#xff0c;凭什么出圈&#xff1f;重点发力在哪些领域呢&#xff1f;今天&#xff0c;带你走进…

Spring Boot使用AOP

一、为什么需要面向切面编程&#xff1f; 面向对象编程&#xff08;OOP&#xff09;的好处是显而易见的&#xff0c;缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候&#xff0c;例如日志记录、性能监控等&#xff0c;如果采用面向对象编程的方法&…

【C语言】socket编程接收问题

一、recv()函数接收到的返回值为0表示对端已经关闭 在TCP套接字编程中&#xff0c;通过recv()函数接收到的返回值为0通常表示对端已经关闭了套接字的发送部分。这是因为TCP是一个基于连接的协议&#xff0c;其中有定义明确的连接建立和终止流程&#xff1b;当对端调用close()或…

matlab appdesigner系列-仪器仪表1-圆形仪表、半圆形仪表、90度仪表、线性仪表

圆形仪表、半圆形仪表、90度仪表、线性仪表&#xff0c;是4种仪表的不同样式。 示例&#xff1a;用滑块&#xff0c;来调整仪表 操作步骤&#xff1a; 1&#xff09;将圆形仪表、半圆形仪表、90度仪表、线性仪表、滑块拖拽到画布上 2&#xff09;设置滑块的回调函数 changin…

MySQL 覆盖索引

目录 一、什么是索引 二、索引的有哪些种类&#xff1f; 三、InnoDB的不同的索引组织结构是怎样的呢&#xff1f; 四、什么是覆盖索引 五、如何使用是覆盖索引&#xff1f; 六、如何确定数据库成功使用了覆盖索引呢 总结&#xff1a; 一、什么是索引 索引&#xff08;在 …

JVM篇:垃圾回收算法

标记清除 通过遍历GC Root后得到不再被引用的对象&#xff0c;对没被引用的对象做一个标记处理&#xff0c;然后对其进行清除。 优点&#xff1a;速度快 缺点&#xff1a;会产生内存碎片&#xff0c;可能会导致空闲的内存足够保存对象&#xff0c;但由于不连续而保存失败。 标…

阿里云部署配置幻兽帕鲁Palworld联机服务器详细教程

阿里云作为国内领先的云计算服务提供商&#xff0c;为企业和个人提供了丰富的云服务。本文将为大家详细介绍如何在阿里云上配置幻兽帕鲁Palworld联机服务器&#xff0c;以便与更多玩家共同体验游戏的乐趣。 第一步&#xff1a;登录服务器创建页 1、进入幻兽帕鲁联机服务快速部…

vue3添加pinia

概述&#xff1a;Pinia 是一个专为 Vue.js 开发的状态管理库。Vue.js 是一个流行的 JavaScript 框架&#xff0c;用于构建用户界面。Pinia 旨在提供一个简单、灵活且性能高效的状态管理方案&#xff0c;使开发者能够更容易地管理应用的状态。 以下是 Pinia 的一些特点和概念&a…

技术变革下职业危机

方向一&#xff1a;技术变革 1.人工智能&#xff08;AI&#xff09;&#xff1a;AI技术的快速发展正在改变各个行业。AI在医疗诊断、金融分析、客户服务以及物流管理等方面都有广泛应用&#xff0c;提高了效率和准确性。但同时也引发了一些道德和道德问题&#xff0c;比如隐私…

###C语言程序设计-----C语言学习(4)#

前言&#xff1a;感谢老铁的浏览&#xff0c;希望老铁可以一键三连加个关注&#xff0c;您的支持和鼓励是我前进的动力&#xff0c;后续会分享更多学习编程的内容。现在开始今天的内容&#xff1a; 一. 主干知识的学习 1.字符型数据 &#xff08;1&#xff09;字符型常量 字…

HCS-华为云Stack-FusionSphere

HCS-华为云Stack-FusionSphere FusionSphere是华为面向多行业客户推出的云操作系统解决方案。 FusionSphere基于开放的OpenStack架构&#xff0c;并针对企业云计算数据中心场景进行设计和优化&#xff0c;提供了强大的虚拟化功能和资源池管理能力、丰富的云基础服务组件和工具…

实体关系抽取与属性补全的技术浅析

目录 前言1. 实体关系抽取2 实体关系抽取的方法2.1 基于模板的方法2.2 基于监督学习的关系抽取2.3 基于深度学习的关系抽取2.4 基于预训练语言模型的关系抽取 3 属性补全3.1 属性补全任务简介3.1 抽取式属性补全3.2 生成式属性补全 4 未来发展趋势结语 前言 在信息爆炸时代&am…

[网鼎杯 2018]Fakebook1

join一个用户后&#xff0c;点进去发现是这样的 查看这个页面的源代码&#xff0c;发现一个base64编码后的字串 decode之后就是我们join新用户时填入的blog网址 那我们是不是可以通过填入存储flag的地址&#xff0c;从而回显出来呢&#xff1f;当然&#xff0c;先按照常规sqli…

【Go】深入理解 Go map:赋值和扩容迁移 ①

文章目录 map底层实现hmapbmap map hash冲突了怎么办&#xff1f; map扩容触发扩容时机扩容小结为什么map扩容选择增量&#xff08;渐进式扩容&#xff09;&#xff1f;迁移是逐步进行的。那如果在途中又要扩容了&#xff0c;怎么办&#xff1f; map翻倍扩容原理 map写入数据内…

LC每日一题记录 2861. 最大合金数

题干 思路 所有合金都需要由同一台机器制造&#xff0c;因此我们可以枚举使用哪一台机器来制造合金。 对于每一台机器&#xff0c;我们可以使用二分查找的方法找出最大的整数 xxx&#xff0c;使得我们可以使用这台机器制造 xxx 份合金。找出所有 xxx 中的最大值即为答案。 代…

【HTML 基础】文档结构

文章目录 1.<!DOCTYPE>2. <html>3. <head>4. <body>总结 HTML 文档的结构是构建网页的基础&#xff0c;通过合理使用标签&#xff0c;我们能够清晰地定义文档的各个部分。在这篇博客中&#xff0c;我们将介绍 HTML 文档的基本结构&#xff0c;包括 <…

桥接模式解析

桥接模式 意图 将抽象与其实现相分离&#xff0c;使得两者可以独立变化。 解释 案例&#xff1a;考虑武器有不同的特效&#xff0c;你想让不同的武器可以有不同的特效&#xff0c;你应该怎么做&#xff1f; 为每个武器创建不同的副本使得有不同的特效&#xff0c;还是你只单独…

wifi模块esp8266如何连接路由器访问天气

1.直接上AT指令&#xff0c;测试过可用 注意回车换行&#xff0c;所有指令都有&#xff0c;有一些特殊的不需要&#xff0c;但是基本上都需要。下面的指令都需要回车换行。/r/n [2024-01-27 02:47:23.374] TX&#xff1a;AT[2024-01-27 02:47:23.392] RX&#xff1a;ATOK[2024-…

简单介绍----微服务和Spring Cloud

微服务和SpringCloud 1.什么是微服务&#xff1f; 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务负责实现特定的业务功能&#xff0c;并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活&#xff08;不同的微服务可以使用不同的开…

ProRes与YUV有什么关系?ProRes还是H264/H265?

苹果的ProRes是一种视频或图片文件的编码格式。它包含ProRes 4444 XQ、ProRes 4444 、 ProRes 422 HQ、ProRes 422、ProRes 422 LT、ProRes Proxy这6种编码和ProRes RAW这种原始文件的存储格式。 我们知道&#xff0c;1920*1080的24p&#xff0c;8bit位深的RGB或者YUV444视频&…