No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置

  1. 删掉基础图标
  2. 新建assets、scenes、scripts文件夹

俄罗斯方块的每种方块都是由四个小方块组成的,很适合放在网格地图中

比如网格地图是宽10列,高20行

要实现网格的对齐和下落

Node2D节点
  1. 新建一个Node2D

  2. 添加2个TileMapLayer

  3. 一个命名为Board,另一个命名为Active

  4. 给Board新建一个图块库

  5. 图块大小为32乘32

  6. 下方打开TileSet

  7. 添加图块

  8. 选择TileMap和第八个灰色的图块

  9. 选择矩形

  10. 画一个12乘22的网格

  11. 再用鼠标右键点击,划掉中间的部分

Node2D脚本

添加脚本,将其添加到scripts文件夹里

main.gd 复制代码
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将方块的形状和位置显示到游戏画面中。
相关推荐
翻滚吧键盘6 分钟前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
重庆小透明15 分钟前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存
lang2015092821 分钟前
Reactor操作符的共享与复用
java
秃了也弱了。25 分钟前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
TTc_31 分钟前
@Transactional事务注解的批量回滚机制
java·事务
乆夨(jiuze)1 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~1 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中1 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
wei_shuo1 小时前
飞算 JavaAI 开发助手:深度学习驱动下的 Java 全链路智能开发新范式
java·开发语言·飞算javaai
然我1 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html