俄罗斯方块棋子旋转算法

2023-12-31

表示和旋转俄罗斯方块游戏棋子的最佳算法(和解释)是什么?我总是发现片段轮换和表示方案令人困惑。

大多数俄罗斯方块游戏似乎在每次旋转时都使用天真的“重新制作块数组”:

http://www.codeplex.com/Project/ProjectDirectory.aspx?ProjectSearchText=俄罗斯方块 http://www.codeplex.com/Project/ProjectDirectory.aspx?ProjectSearchText=tetris

然而,有些使用预先构建的编码数字和位移来表示每个部分:

http://www.codeplex.com/wintris http://www.codeplex.com/wintris

有没有一种方法可以使用数学来做到这一点(不确定这是否适用于基于单元的电路板)?


当我试图弄清楚旋转如何适用于我的俄罗斯方块游戏时,这是我在堆栈溢出上发现的第一个问题。尽管这个问题很老了,但我认为我的输入将帮助其他人尝试通过算法解决这个问题。首先,我不同意对每个部分进行硬编码和旋转会更容易。 Gamecat的答案是正确的,但我想详细说明一下。以下是我在 Java 中解决旋转问题的步骤。

  1. 对于每个形状,确定其原点在哪里。我使用了图中的点这一页 http://tetris.wikia.com/wiki/SRS分配我的原点。请记住,根据您的实现,您可能必须在用户每次移动该块时修改原点。

  2. 旋转假设原点位于点 (0,0),因此您必须先平移每个块,然后才能旋转它。例如,假设您的原点当前位于点 (4, 5)。这意味着在旋转形状之前,每个块必须在 x 坐标中平移 -4,在 y 坐标中平移 -5,以相对于 (0,0)。

  3. 在Java中,典型的坐标平面从左上角的点(0,0)开始,然后向右和向下增加。为了在我的实现中补偿这一点,我在旋转之前将每个点乘以 -1。

  4. 以下是我用来计算逆时针旋转后新的 x 和 y 坐标的公式。有关这方面的更多信息,我会查看维基百科页面旋转矩阵 http://en.wikipedia.org/wiki/Rotation_matrix。 x' 和 y' 是新坐标:

    x' = x * cos(PI/2) - y * sin(PI/2) 且 y' = x * sin(PI/2) + y * cos(PI/2) 。

  5. 对于最后一步,我只是以相反的顺序执行步骤 2 和 3。所以我再次将结果乘以-1,然后将块转换回原来的坐标。

以下是对我有用的代码(Java),以了解如何用您的语言执行此操作:

public synchronized void rotateLeft(){

    Point[] rotatedCoordinates = new Point[MAX_COORDINATES];

    for(int i = 0; i < MAX_COORDINATES; i++){

        // Translates current coordinate to be relative to (0,0)
        Point translationCoordinate = new Point(coordinates[i].x - origin.x, coordinates[i].y - origin.y);

        // Java coordinates start at 0 and increase as a point moves down, so
        // multiply by -1 to reverse
        translationCoordinate.y *= -1;

        // Clone coordinates, so I can use translation coordinates
        // in upcoming calculation
        rotatedCoordinates[i] = (Point)translationCoordinate.clone();

        // May need to round results after rotation
        rotatedCoordinates[i].x = (int)Math.round(translationCoordinate.x * Math.cos(Math.PI/2) - translationCoordinate.y * Math.sin(Math.PI/2)); 
        rotatedCoordinates[i].y = (int)Math.round(translationCoordinate.x * Math.sin(Math.PI/2) + translationCoordinate.y * Math.cos(Math.PI/2));

        // Multiply y-coordinate by -1 again
        rotatedCoordinates[i].y *= -1;

        // Translate to get new coordinates relative to
        // original origin
        rotatedCoordinates[i].x += origin.x;
        rotatedCoordinates[i].y += origin.y;

        // Erase the old coordinates by making them black
        matrix.fillCell(coordinates[i].x, coordinates[i].y, Color.black);

    }
    // Set new coordinates to be drawn on screen
    setCoordinates(rotatedCoordinates.clone());
}

此方法是将形状向左旋转所需的全部方法,结果比为每个形状定义每次旋转要小得多(取决于您的语言)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

俄罗斯方块棋子旋转算法 的相关文章

  • 如何在Scala中实现尾递归快速排序

    我写了一个递归版本 def quickSort T xs List T p T T gt Boolean List T xs match case Nil gt Nil case gt val x xs head val left righ
  • C 中的菱形数组排序

    我有以下 C 语言作业 我基本上需要一种方法而不是解决方案 我们有一个 13 x 13 的数组 在数组中 我们有一个需要考虑的菱形形状 该菱形之外的所有内容都初始化为 1 不重要 下面的 5 x 5 数组示例 x x 1 x x x 2 2
  • Exposé 布局算法

    我正在制作一些项目 其布局类似于 Mac OS X 在 Expos 中对窗口所做的操作 它适应项目的长宽比和可用区域的长宽比 基本上 可用区域分为行和列 每个单元格 行和列的交集 中放置一个项目 这些项目必须保持其纵横比 此处width h
  • 32 位数字中 1 的数量

    我正在寻找一种在 32 位数字中包含 1 数量的方法 之间不使用循环 任何人都可以帮助我并向我提供代码或算法吗 这样做 提前致谢 See Integer bitCount int http java sun com javase 6 doc
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 快速求解子集和

    考虑这种解决子集和问题的方法 def subset summing to zero activities subsets 0 for activity cost in activities iteritems old subsets sub
  • 使用主方法求解 T(n) = 2T(n/2) + n/log n 和 T(n) = 4T(n/2) + n/log n 之间的差异

    我最近偶然发现了一个资源 其中 2T n 2 n log ntypeMM 宣布复发无法解决 我接受它作为一个引理 直到今天 另一种资源被证明是矛盾的 在某种意义上 根据资源 下面的链接 其中的 Q7 和 Q18 是建议 分别在问题中的1和2
  • 检索受“rowspan”影响的行的列索引的最有效方法是什么?

    考虑下表 table thead tr th th th A th th B th th C th tr thead tbody tr th 1 th td Apples td td Oranges td td Pears td tr tb
  • 如何从一组重叠的圆计算多边形集?

    这个问题是一些计算细节的扩展这个问题 https stackoverflow com questions 1667310 combined area of overlapping circles 假设有一组 可能重叠的 圆 并且希望计算这组
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我
  • 如何将无向图转换为 DAG?

    The 维基页面 http en wikipedia org wiki Directed acyclic graph Relation to other kinds of graphs says 任何无向图都可以通过为其顶点选择总顺序并将每
  • 图中的后边

    I m having a hard time understanding Tarjan s algorithm for articulation points I m currently following this tutorial he
  • 固定大小集以包含给定集的最大数量

    我有大约 1000 组尺寸 1 4 1 3 3 5 6 4 5 6 7 5 25 42 67 100 是否有可能找到包含最大数量的给定集合的大小为 20 的集合 检查每一个100 80 20 集 效率低下 我不太确定这是 NP 完全的 考虑
  • 最慢的计算复杂度(Big-O)

    在这些算法中 我知道 Alg1 是最快的 因为它是 n 平方的 接下来是 Alg4 因为它是 n 的立方 然后 Alg2 可能是最慢的 因为它是 2 n 这应该具有非常差的性能 然而Alg3和Alg5在我的阅读速度方面还没有遇到过 这两种算
  • 寻找将集合映射到整数的双射函数

    对于任意两个序列 a b 其中 a a1 a2 an 且 b b1 b2 bn 0a b具有相同的元素 而不关心它们的顺序 例如 如果 a 1 1 2 3 b 2 1 3 1 c 3 2 1 3 则 f a f b f a f b 我知道有
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • URL路径相似度/字符串相似度算法

    我的问题是我需要比较 URL 路径并推断它们是否相似 下面我提供了要处理的示例数据 GROUP 1 robots txt GROUP 2 bot html GROUP 3 phpMyAdmin 2 5 6 rc1 scripts setup
  • 包围一组点的多边形

    我有一组 S 点 2D 由 x 和 y 定义 我想找到 P 包围该组所有点的最小 含义 具有最少数量的点 多边形 P 是S 有没有已知的算法来计算这个 我在这个领域缺乏文化令人惊讶 感谢您的帮助 对于这个问题有很多算法 它被称为 最小边界框
  • 7 张牌扑克手牌评估器

    有谁知道评估 7 张牌扑克牌的快速算法吗 这比简单地暴力检查 7 张牌中每 21 个 5 张牌的组合更有效 Cheers Pete 我写了一篇JavaScript 核心评估方法仅使用位操作 因此速度非常快 考虑到这一点 查看 21 种组合还
  • 生成所有多集大小为 n 的分区的算法

    我一直在试图找出一种方法来生成多重集的所有不同的大小为 n 的分区 但到目前为止却空手而归 首先让我展示一下我想要实现的目标 假设我们有一个输入向量uint32 t std vector

随机推荐

  • for循环跳到最后? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我对 Java 相当陌生 但我的 for 循环立即跳到以下代码中的最高可能值 System out println i for i
  • 如何与 Socket.IO 1.x 和 Express 4.x 共享会话?

    如何与 Socket io 1 0 和 Express 4 x 共享会话 我使用 Redis Store 但我相信这应该不重要 我知道我必须使用中间件来查看 cookie 和获取会话 但不知道如何操作 我搜索但找不到任何工作 var Red
  • 检测到重入

    我在设置 Web 浏览器控件的属性时收到 检测到重入 MDA 错误 仅当我调用 SetWindowsHookEx 来挂钩同一线程中的某些拨号盘时 才会发生这种情况 通常 此挂钩代码工作正常 但与 Webbrowser Control 配合使
  • 使用带有 XLSX.js 的 Alasql JavaScript 库导出到 csv 不适用于 Safari。 - Angularjs

    我想在我的应用程序中导出 csv 格式的表数据 我已将 Alasql 库与 XLSX js 一起使用 它适用于所有现代浏览器 Chrome Firefox 但不适用于 Safari None
  • 从 http://xbrl.sec.gov/ 搜索所有埃德加数据

    我需要从 xbrl 站点以 XML 格式或 RSS Feed 形式获取所有 Edgar 搜索数据 这与此链接上的搜索相同http www sec gov edgar searchedgar cik htm http www sec gov
  • svn 无法在文件中设置位置指针

    我遇到了一个 svn 存储库的问题 该存储库到目前为止一直运行良好 我收到错误 svnadmin Can t set position pointer in file repository db revs 0 783 Invalid arg
  • GLSL 片段着色器语法错误

    以下简单的片段着色器代码失败 在日志中留下一条无信息的消息 ERROR 0 1 gl Color syntax error syntax error void main vec4 myOutputColor gl Color gl Frag
  • 如何更改组合框控件中的下拉按钮?

    如何更改下拉按钮ComboBox控件 C Windows 窗体 我有一个自定义按钮 我想在ComboBox而不是默认的下拉按钮 我认为汉斯 帕桑特的解决方案就是这样 从这里 http social msdn microsoft com fo
  • 从 Android Studio 将 Libgdx 游戏导出为可执行 Jar

    好吧 我使用 Libgdx 制作了一个游戏 我打算将它作为一个 Android 应用程序 这就是我使用 Android Studio 的原因 但我想让我没有 Android 手机的朋友尝试一下 该项目已经针对桌面和 Android 设置 因
  • iOS5 中的“应用程序试图以模态方式呈现活动控制器”错误

    我遇到一个错误 导致我的应用程序仅在 iPad 上的 iOS5 下崩溃 当用户点击 uibarbuttonitem 中的项目时 将调用以下代码 void optionSelected NSString option self optionP
  • AppEngine 响应时间差异

    我正在考虑使用 AppEngine 来部署我正在开发的网络应用程序 作为我对 AppEngine 平台调查的一部分 我一直在检查简单请求的响应时间 为此 我编写了一个简单的 PING servlet SuppressWarnings ser
  • R:计算抛硬币的频率

    我正在使用 R 编程语言 我模拟了这个包含 1000 次硬币翻转的数据集 然后我计算了 2 个翻转序列 的数量 Coin lt c H T Results sample Coin 1000 replace TRUE My Data data
  • Node.js 隔离物是什么?为什么他们现在都死了?

    在0 7 0中 实验分离支持 http blog nodejs org 2012 01 16 node v0 7 0 unstable 原文如此 已推出 除了一些模糊的想法之外 我一直不理解这一点 即它们提供了类似线程的功能 但没有线程的问
  • g.i.cs 文件丢失,类不再包含 InitializeComponent 的定义

    我在业余时间开发了一个 UWP 项目 以掌握 UWP MVVM 和 Prism 该项目最初非常经典 没有使用 MVVM 和 Prism 我一直在努力将这两个纳入该项目 我一直依赖着https msdn microsoft com en us
  • 如何在ARKit中使用环境贴图?

    ARKit 2 0 添加了一个名为 AREnvironmentProbeAnchor 的新类 阅读它的说明 似乎 ARKit 可以自动收集环境纹理 立方体贴图 我相信我们现在可以创建一些反映真实环境的虚拟对象 但我仍然不清楚这是如何工作的
  • Swift 包管理器有本地缓存​​吗?

    每次我加载新包时 Xcode 都会从 Github 重新下载所有依赖项 而不是重用我已经为其他项目加载的一些依赖项 例如 我希望当我引用时 package name SwiftyJSON url https github com Swift
  • 如何查找表的当前大小(在内存中)?

    我有一个使用 engine MEMORY 指定的内存表 我可以运行什么命令来了解它当前占用了多少空间 最大尺寸怎么样 SHOW TABLE STATUS LIKE tablename G 其中 tablename 是您要检查的表的名称
  • 如何使用 python 库找到骨架图像中的循环?

    我有很多这样的骨架图像 我如何检测骨架中的循环 是否有 特殊 函数可以执行此操作 或者我应该将其实现为图表 如果只有图形选项 python图形库NetworkX可以帮助我吗 您可以利用骨架的拓扑结构 循环不会有洞 所以我们可以使用scipy
  • Keras ImageDataGenerator:随机变换

    我有兴趣通过随机图像转换来增强我的数据集 我正在使用 Keras图像数据生成器 https keras io preprocessing image imagedatagenerator 并且我在尝试申请时收到以下错误random tran
  • 俄罗斯方块棋子旋转算法

    表示和旋转俄罗斯方块游戏棋子的最佳算法 和解释 是什么 我总是发现片段轮换和表示方案令人困惑 大多数俄罗斯方块游戏似乎在每次旋转时都使用天真的 重新制作块数组 http www codeplex com Project ProjectDir