Java俄罗斯方块 - 思考方块旋转问题

10

我正在制作俄罗斯方块游戏,并试图思考如何旋转方块。

它们是在一个单独的块上旋转吗?还是应该变形...即交换位置?

enter image description here

我想要实现的方式有点像硬编码...就像(伪代码):

if (rotateRight()) {

    if (Piece == "T") {
        if (Piece.getCurrRotation() == down (aka.. 180 degrees))
          move each Tile in Piece from the down rotation to the left rotation... each coordinate would be pre-specified for a given condition... aka lot's of hardcoding
     }
    if (Piece == "L") { etc...

     }
}
if (rotateLeft()) {
     perform same checks for the Left...
}

但是,为了弄清楚当前方块所处的旋转状态(每个方块有4种可能的旋转状态)和

然后,根据该方块设置新的硬编码坐标

我需要为每个方块都这样做...这似乎不是正确的思考方式。

还有其他想法吗?


2
你需要知道每个块相对于其他块的位置吗? - Chris Cooper
1
我不知道你的代码有多少是伪代码,但在Java中,变量不以大写字母开头 - 你也不应该使用“==”来比较字符串。 - kba
1
为什么不在你的Piece类中添加一个rotate方法,然后为每个子Piece类实现该方法,并从控制器中调用它。这样可以避免使用大型类似于switch语句的结构。 - Robin
2
我会预先计算所有28个部分(7个部分,4个旋转),然后将它们保存在一个4个成员的数组中。如果您向左旋转,则从数组计数器中减去一个(当然要循环),右旋转则相反。 - Kylar
2
为什么不呢?只有28个。这是一个非常小的数字,预先计算它们可能会节省你整体时间,以及许多复杂的数学计算。 - Kylar
显示剩余6条评论
6个回答

1
我可能会为每个PieceType对象创建1-4个方向对象。每个方向对象将定义实际块的位置(相对于某个中心点)。例如:
PieceType "L":

    Orientation 1:
    #
    #
    ##

    Orientation 2:
    ###
    #

    Orientation 3:
    ##
     #
     #

    Orientation 4:
      #
    ###

PieceType "I":

    Orientation 1:
    #
    #
    #
    #

    Orientation 2:
    ####

每个PieceType还可以保存有关每种可能的“方向更改”(即旋转)所需空间的信息。这些都是静态信息,因此在游戏中实际上无需移动块。只需更改Piece的方向,让方向对象告诉您块的位置即可。

这个问题是...在运行时,游戏调用Piece类的int[] getShape(String shape) {方法,例如,如果(shape == "L") { pieceCoordinates = new int[] {0, 1, 0, 2, 1, 2, 2, 2}; `,它将在棋盘上设置这些点。如果我预先计算每个方向,如何将它们设置到棋盘上需要的位置? - user3871
1
@Growler 如果你已经将每个方向保存为一组坐标对(x,y),那么你只需要将当前的方块坐标添加到这些坐标中即可。 - kba
1
你还需要考虑旋转中心。仅仅存储形状是不够的。想象一下如何将“PieceType I”从“Orientation 1”旋转到“Orientation 2”,然后再旋转回来。 - gaborsch
这是一个很好的观点。因为我会围绕一个轴旋转...所以方向1(直立)不会与其第三次旋转时一样。 - user3871
@Growler:你需要相对于某个中心点存储块的位置。 - COME FROM

1
如果您将碎片存储为矩阵,则可以使用通用函数旋转矩阵。假设您想将[[1, 1, 1], [0, 0, 0], [0, 0, 0]]向左旋转90度 -> [[1,0,0], [1,0,0], [1,0,0]]。这有帮助吗?

1
您有两种选择(取决于您如何存储形状):
  • 在运行时进行旋转(将形状点保留在矩阵中,并围绕中心旋转),并重新定位您的形状块。
  • 为形状存储4个(或对于旋转不变形状,2个甚至1个)相位,并仅增加/减少形状所处的相位。

在第一个版本中,您需要计算运行时间,找到形状的中心等。

在第二个版本中,您需要进行预先计算,并硬编码形状。

我认为第二种方法更好,因为您有固定数量的块和固定数量的相位。但这取决于您。


1
那个示例代码看起来像是一场噩梦。另一种简单的方法是将棋盘视为固定数量的单元格,然后将每个“旋转”视为计算每个棋子位置应该移动多少的方法,然后重新安置棋子并让它们自己绘制,因此从棋子的角度来看,它们只被告知:“好的,你现在在A5。”如果您看一下第一个示例,新位置仅仅是其与中心的当前偏移量和所需旋转方向的函数。这种方法的最好之处在于您不需要运行大量可怕的case语句,并创建完全不可持续的神对象代码。

能否举个快速的例子? - user3871
当然。方块总是有中心部分吗?(你的两个例子都有)。 (我玩过几次俄罗斯方块,但不多... :))... - Rob
我认为他们不需要。 - user3871
@Growler 嗯,旋转发生在一个轴上,所以即使你那里没有方块,也必须有一个暗示的中心,对吧?所以你是说你可以有一个像第一个一样只有1和4存在的方块? - Rob

0

在我看来,最简单的方法不是旋转或变换块,而是记住每个状态下块的形状(正常、旋转90度、旋转180度、旋转270度)


0
我建议您将一个形状定义为相对于单个旋转点的点。然后,您可以使用一些矩阵代数,将简单的旋转应用3次以得到相对于中心点的其他布局。
旋转是指取消当前显示游戏中的当前点,切换到下一个旋转,然后重新应用新点到显示游戏中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接