2011-03-15 149 views
4

我刚刚接触Java,并且发现了创建Java Tetris游戏的好教程。为什么要创建一个新的对象 - Java Tetris教程

我没有一个导师或导师帮我这个 - 我一直在寻找一个年龄段:( 所以目前IM自学Java和PHP :)

反正继承人的网站,我发现:http://zetcode.com/tutorials/javagamestutorial/tetris/我不明白在Shape.java类节目的

一种方法:

public Shape rotateLeft() 
{ 
if (pieceShape == Tetrominoes.SquareShape) 
    return this; 

Shape result = new Shape(); 
result.pieceShape = pieceShape; 

for (int i = 0; i < 4; ++i) { 
    result.setX(i, y(i)); 
    result.setY(i, -x(i)); 
} 
return result; 
} 

为什么我们需要创建一个新的对象Shape result = new Shape();如果已经可以获得当前片FR om pieceShape变量?

+0

其中是pieceShape声明?也许它使用的是其他部分的代码... – Heisenbug 2011-03-15 10:00:43

回答

5

看起来命名在本教程中有点误导。名为Shape的班级代表掉落的单个项目。 Tetrominoesenum似乎在描述它的项目是哪一种(即它是“形状”!)。

因此,您发布的代码会创建一个新的项目并指定其形状。

rotateRight()rotateLeft()方法不改变本身的形状,使tryMove()的方法来检查,如果此举是合法的,忽略它,如果它不是(例如,如果你旋转项目入墙) 。当移动不被允许时,tryMove()只保留旧值(包括旧的Shape实例)。如果rotateLeft()/rotateRight()修改了Shape那么它将不得不撤消该操作,这会使代码复杂化。

此外,还有与此代码的一些吹毛求疵:

  • 我会打电话的TetrominoesTetromino,作为enum类型在单数通常命名为(因为你经常引用元素: Tetromino.SquareShape
  • 我想补充有关具体每个Tetromino坐标成enum,有效地将他们大部分来自setShape()方法逻辑添加到它的信息。
  • Board类混合逻辑和演示文稿,它应该分开(使测试更容易)。

    例如,Board类可以实现没有任何图形的所有逻辑(即,不引用来自java.awtjavax.swing的任何内容)。然后你会写一个BoardPanel,描绘Board的状态并与用户交互,调用合适的Board方法。

+0

谢谢堆!!!我没有想到得到一个回答这个快!!!这说明了很多!谢谢谢谢谢谢:) – VisualFire 2011-03-15 10:23:02

3

您发布的方法返回一个向左旋转的形状。如果你没有创建一个新的Shape,原来的形状,这个类的一个领域,并在其他地方使用,将被旋转。

在正方形的情况下,向左旋转时不变,仍可以返回原来的形状。

+0

谢谢你kgiannakakis,你的答案很简单,直接点 - 为什么不能检查2接受的答案:( – VisualFire 2011-03-15 10:24:32

0

没有在本教程彻底地看着我要说的是:由于Shape似乎代表了一个单独的项目,rotateLeft()可能是Shape一个实例方法它也可能是确定到位旋转项,即不返回一个旋转的副本,但改变块的当前形状的坐标。创建一个新的项目将落下意味着创建一个新的Shape与默认的方向。

0

看起来作者并没有改变rotateLeft()中的Shape,因为它可能不被接受为有效的移动。在Board内部TAdapter类呼叫tryMove()并且只设置当前Shape(变量curShape),如果它是可接受的。如果在检查之前发生了变异,则无效时必须将其恢复。该方法可能应该被命名为rotatedLeftCopy()以指示它不改变状态。或者应该事先执行检查,然后rotateLeft()可以安全地更改Shape

+0

mutate?即时通讯尚未亲 - 我想在不久的将来,我会学习这种变异技术。我仍然必须感谢你的回答:) – VisualFire 2011-03-15 10:26:20

+0

通过mutate我只是表示它正在改变对象的状态。所以在这种情况下设置X和Y变量。编写不可变对象有很多优点(例如'String'是不可变的),所以你不能改变状态。相反,你会发现方法(比如'split()'),它可以用你想要的改变返回对象的一个​​副本。它有时也是一种防御性编程技术,用于返回对象的副本,以便用户不会意外地操作返回它的类的控制之外的内容。 – WhiteFang34 2011-03-15 10:37:54

相关问题