No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置
- 删掉基础图标
- 新建assets、scenes、scripts文件夹
![![[Pasted image 20250111005741.png]]](https://i-blog.csdnimg.cn/direct/3eb998b4e7ab4b86889464ec54942d67.png)
俄罗斯方块的每种方块都是由四个小方块组成的,很适合放在网格地图中
比如网格地图是宽10列,高20行
要实现网格的对齐和下落
Node2D节点
-
新建一个Node2D
![![[Pasted image 20250111005728.png]]](https://i-blog.csdnimg.cn/direct/e9ce3fdfeac2496881152735810517f7.png)
-
添加2个TileMapLayer
![![[Pasted image 20250111005843.png]]](https://i-blog.csdnimg.cn/direct/bfa8f04b7ff843ea98ace0cbaff8345e.png)
-
一个命名为Board,另一个命名为Active
![![[Pasted image 20250111010034.png]]](https://i-blog.csdnimg.cn/direct/d9d57f0c961647aba306618681e6bf8c.png)
-
给Board新建一个图块库
![![[Pasted image 20250111010029.png]]](https://i-blog.csdnimg.cn/direct/84b69282229b4cfcaf52cb5a64d66b13.png)
-
图块大小为32乘32
![![[Pasted image 20250111010209.png]]](https://i-blog.csdnimg.cn/direct/6f3498d089094e53b96ea58de4b4dba1.png)
-
下方打开TileSet
![![[Pasted image 20250111010239.png]]](https://i-blog.csdnimg.cn/direct/3b6a15175abe47b791fb8369b1a80a69.png)
-
添加图块
![![[Pasted image 20250111010529.png]]](https://i-blog.csdnimg.cn/direct/49f653a4396f4d16a2d9049a94802751.png)
-
选择TileMap和第八个灰色的图块
![![[Pasted image 20250111010747.png]]](https://i-blog.csdnimg.cn/direct/de0df5d054e74d71bba9aa99fd49fea2.png)
-
选择矩形
![![[Pasted image 20250111010827.png]]](https://i-blog.csdnimg.cn/direct/957544dce5ba42a89cce0dad0bd64819.png)
-
画一个12乘22的网格
![![[Pasted image 20250111011052.png]]](https://i-blog.csdnimg.cn/direct/b7f41969963f48e5abb1ba9d72278507.png)
-
再用鼠标右键点击,划掉中间的部分
![![[Pasted image 20250111011215.png]]](https://i-blog.csdnimg.cn/direct/26161f5fe39342d99f5e3a56a0de7236.png)
Node2D脚本
添加脚本,将其添加到scripts文件夹里
extends Node2D # 此脚本扩展自Node2D,作为游戏的主节点# 定义 I 型俄罗斯方块的所有旋转状态,每种状态由方块相对原点的坐标组成
var i_tetromino: Array = [[Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1), Vector2i(3, 1)], # 0 degrees[Vector2i(2, 0), Vector2i(2, 1), Vector2i(2, 2), Vector2i(2, 3)], # 90 degrees[Vector2i(0, 2), Vector2i(1, 2), Vector2i(2, 2), Vector2i(3, 2)], # 180 degrees[Vector2i(1, 0), Vector2i(1, 1), Vector2i(1, 2), Vector2i(1, 3)] # 270 degrees
]# 定义 T 型俄罗斯方块的所有旋转状态
var t_tetromino: Array = [[Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1)], # 0 degrees[Vector2i(1, 0), Vector2i(1, 1), Vector2i(2, 1), Vector2i(1, 2)], # 90 degrees[Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1), Vector2i(1, 2)], # 180 degrees[Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(1, 2)] # 270 degrees
]# 定义 O 型俄罗斯方块的所有旋转状态(所有旋转状态相同)
var o_tetromino: Array = [[Vector2i(0, 0), Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1)], # All rotations are the same[Vector2i(0, 0), Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1)], # All rotations are the same[Vector2i(0, 0), Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1)], # All rotations are the same[Vector2i(0, 0), Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1)] # All rotations are the same
]# 定义 Z 型俄罗斯方块的所有旋转状态
var z_tetromino: Array = [[Vector2i(0, 0), Vector2i(1, 0), Vector2i(1, 1), Vector2i(2, 1)], # 0 degrees[Vector2i(2, 0), Vector2i(1, 1), Vector2i(2, 1), Vector2i(1, 2)], # 90 degrees[Vector2i(0, 1), Vector2i(1, 1), Vector2i(1, 2), Vector2i(2, 2)], # 180 degrees[Vector2i(1, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(0, 2)] # 270 degrees
]# 定义 S 型俄罗斯方块的所有旋转状态
var s_tetromino: Array = [[Vector2i(1, 0), Vector2i(2, 0), Vector2i(0, 1), Vector2i(1, 1)], # 0 degrees[Vector2i(1, 0), Vector2i(1, 1), Vector2i(2, 1), Vector2i(2, 2)], # 90 degrees[Vector2i(1, 1), Vector2i(2, 1), Vector2i(0, 2), Vector2i(1, 2)], # 180 degrees[Vector2i(0, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(1, 2)] # 270 degrees
]# 定义 L 型俄罗斯方块的所有旋转状态
var l_tetromino: Array = [[Vector2i(2, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1)], # 0 degrees[Vector2i(1, 0), Vector2i(1, 1), Vector2i(1, 2), Vector2i(2, 2)], # 90 degrees[Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1), Vector2i(0, 2)], # 180 degrees[Vector2i(0, 0), Vector2i(1, 0), Vector2i(1, 1), Vector2i(1, 2)] # 270 degrees
]# 定义 J 型俄罗斯方块的所有旋转状态
var j_tetromino: Array = [[Vector2i(0, 0), Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1)], # 0 degrees[Vector2i(1, 0), Vector2i(2, 0), Vector2i(1, 1), Vector2i(1, 2)], # 90 degrees[Vector2i(0, 1), Vector2i(1, 1), Vector2i(2, 1), Vector2i(2, 2)], # 180 degrees[Vector2i(1, 0), Vector2i(1, 1), Vector2i(0, 2), Vector2i(1, 2)] # 270 degrees
]# 将所有俄罗斯方块的数组存入 tetrominoes 数组
var tetrominoes: Array = [i_tetromino, t_tetromino, o_tetromino, z_tetromino, s_tetromino, l_tetromino, j_tetromino]# 创建所有方块的副本用于重置
var all_tetrominoes: Array = tetrominoes.duplicate()# 设置游戏区域的列数和行数
const COLS: int = 10
const ROWS: int = 20# 定义初始方块生成的起始位置
const START_POSITION: Vector2i = Vector2i(5, 1)
# 当前方块的位置
var current_position: Vector2i# 当前和下一个方块的形状及旋转角度
var cunrrent_tetromino_type: Array
var next_tetromino_type: Array
# 当前旋转状态
var rotation_index: int = 0
# 当前方块的形态
var active_tetromino: Array = []# Tile ID 和图块信息
var tile_id: int = 0
var piece_atlas: Vector2i
var next_piece_atlas: Vector2i# 连接节点
@onready var board_layer: TileMapLayer = $Board
@onready var active_layer: TileMapLayer = $Active# 准备函数,在游戏开始时调用
func _ready() -> void:start_new_game()# 开始新的游戏
func start_new_game() -> void:# 随机选择一个方块类型cunrrent_tetromino_type = choose_tetromino()# 计算方块在 Tileset 中的图块索引piece_atlas = Vector2i(all_tetrominoes.find(cunrrent_tetromino_type), 0)# 初始化方块的位置和显示initialize_tetromino()# 随机选择一个方块类型
func choose_tetromino() -> Array:var selected_tetromino: Array# 如果当前类型池不为空if not tetrominoes.is_empty():# 打乱类型池顺序tetrominoes.shuffle()# 取出第一个类型selected_tetromino = tetrominoes.pop_front()else:# 重置类型池tetrominoes = all_tetrominoes.duplicate()tetrominoes.shuffle()selected_tetromino = tetrominoes.pop_front()return selected_tetromino# 初始化当前方块
func initialize_tetromino() -> void:# 将当前方块的位置设置为起始位置(通常在游戏顶部中央)current_position = START_POSITION# 获取当前方块在当前旋转状态下的形态active_tetromino = cunrrent_tetromino_type[rotation_index]# 渲染当前方块到网格层(显示方块)render_tetromino(active_tetromino, current_position, piece_atlas)# 渲染俄罗斯方块到指定位置
func render_tetromino(tetromino: Array, position: Vector2i, atlas: Vector2i) -> void:# 遍历当前方块的所有方块单元(每个单元以 Vector2i 表示)for block in tetromino:# 使用方块的全局位置(初始位置加单元偏移量)设置网格层的对应单元# - position + block: 当前单元格在网格中的全局位置# - tile_id: 当前方块的唯一标识符,用于区分不同类型的方块# - atlas: 方块对应的图块信息,用于绘制特定样式board_layer.set_cell(position + block, tile_id, atlas)
这段代码定义了一个俄罗斯方块游戏的基础框架,用于管理游戏中的方块数据、游戏区域以及方块的生成和显示逻辑。
核心思想
- 方块表示与旋转: 每种俄罗斯方块由其所有可能的旋转状态定义(0°、90°、180°、270°),这些状态通过
Vector2i表示的相对坐标来描述。 - 动态方块池管理: 使用一个池子管理可用的方块类型,每次随机从池中取出一个方块,当池为空时重新填充并随机打乱顺序。
- 游戏区域: 游戏区域被定义为一个网格,玩家的目标是控制方块在网格内移动、旋转,并最终填满一行消除得分。
- 图块渲染: 使用
TileMapLayer将方块的形状和位置显示到游戏画面中。
![![[Pasted image 20250111103600.png]]](https://i-blog.csdnimg.cn/direct/d7a058f313754ad38d1f89053980575f.png)
相关文章:
No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置
删掉基础图标新建assets、scenes、scripts文件夹 俄罗斯方块的每种方块都是由四个小方块组成的,很适合放在网格地图中 比如网格地图是宽10列,高20行 要实现网格的对齐和下落 Node2D节点 新建一个Node2D 添加2个TileMapLayer 一个命名为Board&…...
SSM框架探秘:Spring 整合 SpringMVC 框架
搭建和测试 SpringMVC 的开发环境: web.xml 元素顺序: 在 web.xml 中配置 DisPatcherServlet 前端控制器: <!-- 配置前端控制器 --> <servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>…...
2025.1.20——二、buuctf BUU UPLOAD COURSE 1 1 文件上传
题目来源:buuctf BUU UPLOAD COURSE 1 1 目录 一、打开靶机,查看信息 二、解题思路 step 1:上传一句话木马.php文件康康回显 step 2:蚁剑连接 三、小结 一、打开靶机,查看信息 这里提示到了文件会被上传到./uplo…...
【架构面试】三、高可用高性能架构设计
高可用高性能架构设计 面试要点引入:架构原理、分布式技术等是面试必考领域,高可用高性能需求考察频繁。面试常通过询问系统架构设计来考察能力,讲解架构设计过程就是证明系统高可用的过程,其中涉及SLA指标。SLA指标详解 定义与衡…...
11.渲染管线——光栅化阶段
光栅化阶段是渲染管线中的一个关键步骤,负责将3D模型转换成屏幕上的2D像素。用通俗易懂的方式来解释: 通俗解释:光栅化就像把3D模型“投影”到2D屏幕上 想象你是一个画家,正在把3D场景画到2D画布上: 3D模型到2D屏幕的…...
【数据分享】1929-2024年全球站点的逐月平均能见度(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标!说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2024年全球气象站点…...
二叉树的深度
二叉树深度的定义: 二叉树的深度(高度)是指从根节点到最远叶子节点的最长路径上的节点数。例如,一个只有根节点的二叉树,其深度为1;如果根节点有两个子节点,且每个子节点又分别有两个子节点&…...
MySQL命令及用法(精华版)
目录 DDL(数据定义语言) 数据库操作 表操作 DML(数据操作语言) DQL(数据查询语言) 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查询 DCL(数据控制语言) 用户…...
R语言学习笔记之高效数据操作
一、概要 数据操作是R语言的一大优势,用户可以利用基本包或者拓展包在R语言中进行复杂的数据操作,包括排序、更新、分组汇总等。R数据操作包:data.table和tidyfst两个扩展包。 data.table是当前R中处理数据最快的工具,可以实现快…...
将 OneLake 数据索引到 Elasticsearch - 第二部分
作者:来自 Elastic Gustavo Llermaly 及 Jeffrey Rengifo 本文分为两部分,第二部分介绍如何使用自定义连接器将 OneLake 数据索引并搜索到 Elastic 中。 在本文中,我们将利用第 1 部分中学到的知识来创建 OneLake 自定义 Elasticsearch 连接器…...
Linux——冯 • 诺依曼体系结构
目录 一、冯•诺依曼体系结构原理二、内存提高冯•诺依曼体系结构效率的方法三、当用QQ和朋友聊天时数据的流动过程四、关于冯诺依曼五、总结 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系 流程&#…...
Java进阶(一)
目录 一.Java注解 什么是注解? 内置注解 元注解 二.对象克隆 什么是对象克隆? 为什么用到对象克隆 三.浅克隆深克隆 一.Java注解 什么是注解? java中注解(Annotation)又称java标注,是一种特殊的注释。 可以添加在包,类&…...
appium自动化环境搭建
一、appium介绍 appium介绍 appium是一个开源工具、支持跨平台、用于自动化ios、安卓手机和windows桌面平台上面的原生、移动web和混合应用,支持多种编程语言(python,java,Ruby,Javascript、PHP等) 原生应用和混合应用…...
Qt 5.14.2 学习记录 —— 이십 QFile和多线程
文章目录 1、QFile1、打开2、读写3、关闭4、程序5、其它功能 2、多线程1、演示2、锁 3、条件变量和信号量 1、QFile Qt有自己的一套文件体系,不过Qt也可以使用C,C,Linux的文件操作。使用Qt的文件体系和Qt自己的一些类型更好配合。 管理写入读…...
積分方程與簡單的泛函分析7.希爾伯特-施密特定理
1)def函數叫作"由核生成的(有源的)" 定义: 设 是定义在区域上的核函数。 对于函数,若存在函数使得, 则称函数是“由核生成的(有源的)”。 这里的直观理解是: 函数的“来源”可以通过核函数 与另一个函数的积分运算得到。 在积分方程理论中,这种表述常…...
使用vitepress搭建自己的博客项目
一、介绍can-vitepress-blog 什么是CAN BLOG CAN BLOG是基于vitepress二开的个人博客系统,他能够方便使用者快速构建自己的博客文章,无需繁琐的配置和复杂的代码编写。 CAN BLOG以antdv为UI设计基础,简洁大方,界面友好…...
开始步入达梦中级dba
分析内存使用需要的方法之一 disql /nolog conn sysdba/sysdbaselect value from v$parameter where nameMEMORY_LEAK_CHECK; SP_SET_PARA_VALUE(0,MEMORY_LEAK_CHECK,1); select * from V$MEM_REGINFO; select * from V$MEM_HEAP;...
如何在docker中的mysql容器内执行命令与执行SQL文件
通过 docker ps -a 查询当前运行的容器,找到想执行命令的容器名称。 docker ps -a若想执行sql文件,则将sql文件放入当前文件夹下后将项目内的 SQL 文件拷贝到 mysql 容器内部的 root下。 sudo docker cp /root/enterprise.sql mysql:/root/然后进入 my…...
S4 HANA更改Tax base Amount的字段控制
本文主要介绍在S4 HANA OP中Tax base Amount的字段控制相关设置。具体请参照如下内容: 1. 更改Tax base Amount的字段控制 以上配置用于控制FB60/FB65/FB70/FB75/MIRO的页签“Tax”界面是否可以修改“Tax base Amount”, 如果勾选Change 表示可以修改T…...
Linux权限有关
文章目录 一、添加普通用户二、Xshell下命令行的知识三、 Linux和Windows操作系统四、再探指令和Linux权限五、用户相关用户切换: 今天我们学习与Linux有关的权限等内容,以及一些零碎知识帮助我们理解Linux的系统和Xshell的原理。 本篇是在Xshell环境下执行的。 一…...
弧形导轨精度等级适配策略
弧形导轨是用于实现曲线运动的线性导向装置,广泛应用于自动化设备、机器人、医疗机械等领域。弧形导轨作为机械传动中的核心部件,其精度等级直接影响设备性能与稳定性。从精密加工到重型机械,不同场景对导轨的制造精度、运行精度及耐磨性要求…...
ai赋能开发:让快马平台智能生成mpu6050手势识别代码
最近在做一个基于MPU6050传感器的手势识别项目,发现用传统方式开发效率太低,于是尝试了InsCode(快马)平台的AI辅助开发功能。整个过程让我深刻体会到,AI如何改变硬件开发的效率瓶颈。 数据采集模块的智能生成 当我输入"用Arduino持续读取…...
记录一次 反射引起的Metaspace OOM 的完整排查
一、问题背景线上某个 Spring Boot 服务偶发出现:java.lang.OutOfMemoryError: MetaspaceJVM 参数中已经限制:-XX:MetaspaceSize512m -XX:MaxMetaspaceSize512m但监控显示:Metaspace used ≈ 370MB Metaspace committed ≈ 508MB看起来仍…...
3月31日(AI审批+技术岗位情况+知识获取方法)
如何用 AI 分类器替代人工审批 Claude 每执行一个命令、每改一个文件,都要你点一次“同意”。用户 93% 的操作都会批准。也就是说,这个“安全审批”环节,绝大多数时候只是一个条件反射。 告警疲劳:100 条告警里只有 7 条需要关注…...
如何突破Cursor AI试用限制:3种方法重新获得Pro功能
如何突破Cursor AI试用限制:3种方法重新获得Pro功能 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial…...
iperf3网络性能测试工具完全指南:从安装到企业级应用
iperf3网络性能测试工具完全指南:从安装到企业级应用 【免费下载链接】iperf3-win-builds iperf3 binaries for Windows. Benchmark your network limits. 项目地址: https://gitcode.com/gh_mirrors/ip/iperf3-win-builds 在当今数字化时代,网络…...
Phi-4-mini-reasoning惊艳效果:自动识别题目所属数学分支并推荐解法策略
Phi-4-mini-reasoning惊艳效果:自动识别题目所属数学分支并推荐解法策略 1. 模型介绍 Phi-4-mini-reasoning是微软推出的3.8B参数轻量级开源模型,专为数学推理、逻辑推导和多步解题等强逻辑任务设计。这个模型主打"小参数、强推理、长上下文、低延…...
Segment-and-Track-Anything实战案例:从街景到细胞的全场景应用
Segment-and-Track-Anything实战案例:从街景到细胞的全场景应用 【免费下载链接】Segment-and-Track-Anything An open-source project dedicated to tracking and segmenting any objects in videos, either automatically or interactively. The primary algorith…...
避开这5个坑!用MediaRecorder+Vue3实现高兼容性语音输入
Vue3MediaRecorder实战:5个关键技巧打造高兼容语音输入方案 在移动优先的时代,语音输入已成为提升用户体验的重要交互方式。但当你兴奋地在Vue3项目中集成MediaRecorder API时,可能会遇到iOS设备上的静默失败、Android机型上的格式兼容性问题…...
手把手教你学Simulink——基于Simulink的无差拍控制三相整流器高精度电流跟踪
目录 手把手教你学Simulink ——基于Simulink的无差拍控制三相整流器高精度电流跟踪 一、问题背景 二、系统建模与控制原理 1. 三相整流器拓扑 2. dq 轴数学模型(同步旋转坐标系) 3. 无差拍控制律推导 三、整体控制架构 四、Simulink 建模步骤 第一步:搭建三相整流…...
