当前位置: 首页 > news >正文

200行C++代码写一个Qt俄罗斯方块小游戏

小小演示一下:

大体思路:

 其实很早就想写一个俄罗斯方块了,但是一想到那么多方块还要变形,还要判断落地什么的就脑壳疼。直到现在才写出来。

俄罗斯方块这个小游戏的小难点其实就一个,就是方块的变形,看似每个方块的变形都不一样,找不到共同点,实现起来比较麻烦,不过只要有了思路其实还是可以的。

方块变形:

俄罗斯方块实际上是只有五种(其中有两种“L”形和“Z”形每种有两种对称的)。

每个方块以及变形的样子我都放下面了。

咋一看好像看不出共同点,不过也确实没有啥共同点,实际上我们不需要有共同点,我们只需要知道每个方块变形都是怎么变的。

上面看不出来我们再换个形式。

我们知道,方块变形的本质实际上是旋转,而旋转我们是绕着某个中心点去旋转的,因此我们只需要记录每个方块的中心点以及不同形态时的每个小方块对于中心点的相对位置。

除了正方形怎么变形都一样,其他方块的变形情况都在下面,中心点我加重了颜色。

可以看得出来,方块的每个小方块的位置都可以通过与中心点的相对坐标来获取。

要变换姿势的时候,只要有中心点的坐标,就可以切换姿势。

下面是不同方块不同姿势的不同小方块与中心点的相对位置关系,套了个四维数组写起来好费劲

//第一层选择方块种类,第二层选择方块形态,第三层装小方块,//第四层装每个小方块对于中心点坐标的相对位置用于变换姿势vector<vector<vector<vector<int>>>>mode{{{{1,0},{1,1},{0,0},{0,1}}},								//方形{{{2,0},{1,0},{0,0},{-1,0}},{{0,-1},{0,0},{0,1},{0,2}}},	//长条形{{{1,0},{1,-1},{0,-1},{-1,-1}},{{1,-1},{1,0},{1,1},{0,1}},	//L形1{{1,1},{0,1},{-1,1},{-1,0}},{{0,-1},{-1,-1},{-1,0},{-1,1}}},{{{1,0},{1,1},{0,1},{-1,1}},{{1,-1},{1,1},{1,0},{0,-1}},	//L形2{{0,1},{-1,0},{-1,1},{-1,-1}},{{1,-1},{0,-1},{-1,-1},{-1,0}}},{{{1,0},{0,0},{0,1},{-1,0}},{{0,-1},{0,0},{0,1},{-1,0}},	//凸形{{1,0},{0,0},{0,-1},{-1,0}},{{1,0},{0,0},{0,-1},{0,1}}},{{{1,-1},{0,-1},{0,0},{-1,0}},{{1,0},{1,1},{0,0},{0,-1}}},	//Z形1{{{1,1},{0,0},{0,1},{-1,0}},{{1,-1},{1,0},{0,0},{0,1}}}		//Z形2};

 下面是换姿势的代码:

其中 whichOne是选择哪一种方块,index是选择方块的哪一种姿势

//切换模式
vector<vector<int>> block::changeMode(){if (whichOne == 0) return coordinate;vector<vector<int>>res;index++;index %= (mode[whichOne].size());for (auto& m : mode[whichOne][index]) {//根据中心坐标和缓存的模式关系来获取切换模式之后的方块坐标res.push_back({ center[0] - m[0],center[1] - m[1] });}//没有直接切换,而是返回新坐标return res;
}

 在获取新姿势的小方块坐标之后没有马上更新,而是返回出去了,因为可能变形之后会不符合要求,例如下面的例子:

 变形之后把返回的新坐标返回,我们再用一个函数去检测新坐标是否合法,合法再去修改当前方块的具体坐标,检测函数也很简单:

//检测移动是否合法
int Tetris::checkMove(vector<vector<int>>temp){for (auto& c : temp) {if (c[1] < 0 || c[1] >= 10) return -1;      //左右越界返回-1;if (cache[c[0]][c[1]] == 1) return 0;       //遇到落地方块返回0;}//一切合法返回1return 1;
}

 返回1就是移动合法,我们修改坐标,返回-1就是移动不合法,我们什么也不改。

还剩一个返回-1,就是移动后遇到了已经落地的方块,这时候在调用这个检测函数的函数之中还需要做个判断。

如果是因此下落而造成的移动,那么检测获取-1则将方块的坐标的位置更新对应在缓存中的位置为1,然后生成新方块。

而其他情况,例如是左右移动或是变换姿势而造成的碰到落地方块则是和-1一样不做处理。

否则会有这样的问题:

落地判断:

用Qt来绘图,我向来都是用二维数组来缓存界面,然后通过相应的位置的不同元素来绘制不同的图案。

在这个俄罗斯方块中,我的写法是缓存中的元素一共只有两种情况,0和1,0表示什么都没有,不需要绘制,而1表示已经落地的方块。

那么正在下落的方块呢,缓存里不用存一下吗。我的做法是不需要,等等会说明原因。

因此我们正在下落的方块的坐标我是拿另一个二维数组存起来的。

每次下落时只需要做个判断,我们正在下落的方块之中,只要有一个小方块在下落之后在缓存中对应的位置元素为1,就表示接触到了已经落地的方块,那么当前方块也会变成他们的一部分,然后更新缓存,并且重新生成新的方块。

这里有个小问题,就是在游戏的一开始缓存是全为0的,还没有落地的方块,因此我们上述的判断在游戏的一开始不会触发,解法有两种,一种是多一层判断,如果方块最下面的小方块已经到了界面最下面的地方(对应缓存中的下标为0),那么也算落地。

第二种解法是我的做法,就是直接在缓存下标为0的位置先给铺一层落地的方块也就是1。

消除检测:

消除检测很容易,界面缓存中的元素只有0或1,分别用来表示什么都没有以及已经落地的方块,如果缓存中有一行的元素之和等于10,那么就表示本行塞满了,可以消除。

缓存中下标为0的行在最下面,也就是下标越大,代表的位置就在界面的越上方。

如果检测到了某一行可以消除,那么我们可以直接把这一行从缓存之中直接删除,然后从缓存的尾部再添加上一个长度为10,元素为0的数组即可。

关于消除还有最后一个问题,那就是一个方块落下,可能消除的不止一行,因此我们像上述那样操作,应该从下标较大的地方开始往下标较小的地方遍历寻找,否则可能会漏掉。

并且我们可以想象的到,一个方块落地之后,如果可以消除,那么可以消除的那一行方块一定是在刚落地方块所在的行,因此每次检测的时候,我们只需要检测落地方块的每个小方块所在的行即可。

//检测是否能清除一行方块
void Tetris::clearBlocks(){set<int>s;vector<int>v;//获取方块的y轴,因为能清除方块的话,行数一定在方块的y轴之中for (auto& c : curBlock.coordinate) {if (accumulate(cache[c[0]].begin(), cache[c[0]].end(), 0) == 10) s.insert(c[0]);}//从大到小去清除一整行的界面缓存for (int i : s) v.insert(v.begin(), i);for (int i : v) {score++;                                //得分增加//删除一行方块后再后面补上一行.cache.erase(cache.begin() + i);cache.push_back(vector<int>(10, 0));}
}

代码获取:

完整的项目文件我已经上传到了CSDN,可以直接免费下载,也可以关注我的公众号“折途想要敲代码”回复关键词“qt俄罗斯方块”免费获取、

相关文章:

200行C++代码写一个Qt俄罗斯方块小游戏

小小演示一下&#xff1a; 大体思路&#xff1a; 其实很早就想写一个俄罗斯方块了&#xff0c;但是一想到那么多方块还要变形&#xff0c;还要判断落地什么的就脑壳疼。直到现在才写出来。 俄罗斯方块这个小游戏的小难点其实就一个&#xff0c;就是方块的变形&#xff0c;看似…...

蓝桥杯每日一题20223.9.26

4407. 扫雷 - AcWing题库 题目描述 分析 此题目使用map等都会超时&#xff0c;所以我们可以巧妙的使用哈希模拟散列表&#xff0c;哈希表初始化为-1首先将地雷读入哈希表&#xff0c;找到地雷的坐标在哈希表中对应的下标&#xff0c;如果没有则此地雷的位置第一次出现&#…...

查看基站后台信息

查看基站后台信息 电脑配置固定ip: 192.168.1.99: 打开“网络和共享中心”&#xff0c;选择更改适配器设置&#xff1a; 右键“本地连接”&#xff0c;选择属性 基站网线直连电脑网口 Telnet 登录基站 打开dos窗口 windows键R”&#xff0c;输入cmd&#xff0c;点确定&…...

关于坐标的旋转变换和坐标系的旋转变换

不管是坐标的旋转变换还是坐标系下的旋转变换&#xff0c;只和旋转的顺时针和逆时针有关。然坐标系间的顺时针和逆时针是根据当前坐标系在目标坐标系下的相对位置确定。 一。逆时针旋转belta角度的公式 二。顺时针旋转belta角度的公式 三。坐标的旋转变换 1.坐标的旋转变换相…...

2023.9.19 关于 数据链路层 和 DNS 协议 基本知识

目录 数据链路层 MTU DNS 协议 补充 DHCP协议 数据链路层 基本概念&#xff1a; 考虑相邻两个节点之间的传输&#xff08;通过 网线 / 光纤 / 无线 直接相连的两个设备&#xff09;以太网协议 规定了 数据链路层 和 物理层 的内容 IP地址 与 mac地址 的相互配合 IP地址 描…...

如何保证接口幂等性

简介 接口幂等性就是说用户使用相同的参数请求同一个接口无论是一次还是多次都应该是一样的。不会因为多次的点击产生不同效果。 举个栗子&#xff1a;一个用户在手机APP上提200块钱&#xff0c;然后一不小心点击了两次&#xff0c;那么就应该只提取出200块钱&#xff0c;不应…...

搭建智能桥梁,Amazon CodeWhisperer助您轻松编程

零&#xff1a;前言 随着时间的推移&#xff0c;人工智能技术以惊人的速度向前发展&#xff0c;正掀起着全新的编程范式革命。不仅仅局限于代码生成&#xff0c;智能编程助手等创新应用也进一步提升了开发效率和代码质量&#xff0c;极大地推动着软件开发领域的快速繁荣。 当前…...

数组和指针笔试题解析之【指针】

目录 &#x1f342;笔试题1&#xff1a; &#x1f342;笔试题2&#xff1a; &#x1f342;笔试题3&#xff1a; &#x1f342;笔试题4&#xff1a; &#x1f342;笔试题5&#xff1a; &#x1f342;笔试题6&#xff1a; &#x1f342;笔试题7&#xff1a; &#x1f342;笔试题…...

【Linux】之Centos7卸载KVM虚拟化服务

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…...

智能电力运维系统:数字化转型在电力行业的关键应用

随着信息技术、人工智能等的飞速发展&#xff0c;数字化改造已成为各行各业的重要发展趋势。在电力行业中&#xff0c;智能电力运维系统是数字化转型的关键应用之一。 力安科技智能电力运维系统是一种集自动化、智能化、云计算、物联网等先进技术于一体的电力运维管理解决方…...

eslint报错:no-empty-source

问题&#xff1a; 提交代码时&#xff0c;eslint校验没有通过&#xff0c;报错 esc[2m183:9esc[22m esc[31mesc[31m✖esc[39m Unexpected empty source esc[2mno-empty-sourceesc[22m 1 problem (esc[31m1 erroresc[39m, esc[33m0 warnings esc[39m) 原因&#xff1a; …...

图论17(Leetcode864.获取所有钥匙的最短路径)

用二进制表示获得的钥匙&#xff0c;假设n钥匙个数 000000000代表没有钥匙&#xff0c;0000000001代表有idx为1的钥匙&#xff0c;0000000011代表有idx1&#xff0c;2的钥匙 &#xff08;这方法巧妙又复杂.. 代码&#xff1a; class Solution {static int[][] dirs {{-1,0}…...

vue 脚手架 入门 记录

vue 脚手架 入门 记录 以管理员身份运行PowerShell执行&#xff1a;get-ExecutionPolicy&#xff0c;回复Restricted&#xff0c;表示状态是禁止的 3.执行&#xff1a;set-ExecutionPolicy RemoteSigned 4.选择Y 注意&#xff1a;一定要以管理员的身份运行PowerShell&#xff…...

汽车租赁系统演示租车小程序H5开发

一款适合汽车租赁业务的程序系统&#xff0c;支持在线支付、一键续租、在线签名。 为了方便用户端方便租车和查看已租车辆的信息和费用&#xff0c;支持上门取车和到店取车两种模式&#xff0c;支持待付款、待取车、待还车、订单管理、已完成、全部订单等订单状态查看和处理功…...

【MySQL】 MySQL 更新数据机制

MySQL 更新数据机制 一、问题描述 假设我们有这样一张表&#xff0c;且包含一条记录&#xff1a; CREATE TABLE mytest ( id int(11) NOT NULL, c1 int(11) DEFAULT NULL, c2 int(11) DEFAULT NULL, c3 int(11) DEFAULT NULL, PRIMARY KEY (id), KEY c1 (c1), KEY c2 (c2) 包…...

批次管理在MES管理系统中有哪些应用

在制造企业中&#xff0c;批次管理是一项至关重要的管理方法&#xff0c;它贯穿于企业的整个生产过程中。特别是在流程制造行业中&#xff0c;如药品、食品等行业&#xff0c;批次管理显得尤为重要。这些行业的产品通常需要进行严格的质量控制和追踪&#xff0c;以便在问题发生…...

python命名规范

一、概述 以前写python代码没有个代码&#xff0c;写出的代码一点也不规范 二、命名规范 2.1类的命名规范 总是使用首字母大写单词串。如MyClass、ClassName。内部类可以使用额外的前导下划线。 2.2函数和方法的命名规范 小写下划线&#xff0c;如method_name。 2.3函数…...

Redis学习笔记--002

Redis的JAVA客户端 文章目录 Redis的JAVA客户端一、Redis的Java客户端的种类二、Jedis2.1、使用步骤2.2、Jedis连接池 三、[SpringDataRedis](https://spring.io/projects/spring-data-redis)3.1、介绍3.2、RedisTemplate3.3、SpringDataRedis使用步骤3.4、SpringDataRedis的序…...

Visual Stdio 2019 win10 64bit下 无法找到 资源编译器DLL,请确认路径是否正确,和无法下载 win10SDK_10.0

上面的2个原因 第一个原因是因为安装时候&#xff0c;漏掉勾选 vistual stdio sdk 和 windows 通用c运行时 其中的一项目 第2个原因是没有安装 sdk...

设计模式:中介者模式(C++实现)

在中介者模式中&#xff0c;中介者对象负责协调多个对象之间的交互&#xff0c;将对象之间的耦合度降低。 #include <iostream> #include <string> #include <vector>class Colleague;// 中介者接口 class Mediator { public:virtual void sendMessage(Coll…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...