【问题标题】:Drawing tetrominos (Tetris pieces)绘图 tetrominos(俄罗斯方块)
【发布时间】:2018-06-06 03:14:09
【问题描述】:

我在创建/绘制 tetrominos(俄罗斯方块)时遇到问题,我在 C++ 中使用 SFML 有哪些选择?

我尝试使用 switch 语句将它们绘制为凸形并给它们编号,但由于 L 和 J 形状是凹形的,所以这不起作用。

 ConvexShape blocks;
    blocks.setTexture(&tile);

             // block generation and shape
    default_random_engine randomGenerator(time(0));
    uniform_int_distribution<int> blocktype(0,6);
    int n = blocktype(randomGenerator);
    switch (n)
    {
        case (0): blocks.setPointCount(4);
                  blocks.setPoint(0,Vector2f(0.0f,0.0f));
                  blocks.setPoint(1,Vector2f(18.0f,0.0f));
                  blocks.setPoint(2,Vector2f(18.0f,72.0f));
                  blocks.setPoint(3,Vector2f(0.0f,72.0f));
                  break;
        case (1): blocks.setPointCount(4);
                  blocks.setPoint(0,Vector2f(0.0f,0.0f));
                  blocks.setPoint(1,Vector2f(36.0f,0.0f));
                  blocks.setPoint(2,Vector2f(36.0f,36.0f));
                  blocks.setPoint(3,Vector2f(0.0f,36.0f));
                  break;
        case (2): blocks.setPointCount(8);
                  blocks.setPoint(0,Vector2f(0.0f,0.0f));
                  blocks.setPoint(1,Vector2f(18.0f,0.0f));
                  blocks.setPoint(2,Vector2f(18.0f,18.0f));
                  blocks.setPoint(3,Vector2f(36.0f,18.0f));
                  blocks.setPoint(4,Vector2f(36.0f,36.0f));
                  blocks.setPoint(5,Vector2f(18.0f,36.0f));
                  blocks.setPoint(6,Vector2f(18.0f,54.0f));
                  blocks.setPoint(7,Vector2f(0.0f,54.0f));
                  break;
        case (3): blocks.setPointCount(8);
                  blocks.setPoint(0,Vector2f(0.0f,0.0f));
                  blocks.setPoint(1,Vector2f(18.0f,0.0f));
                  blocks.setPoint(2,Vector2f(18.0f,18.0f));
                  blocks.setPoint(3,Vector2f(36.0f,18.0f));
                  blocks.setPoint(4,Vector2f(36.0f,54.0f));
                  blocks.setPoint(5,Vector2f(18.0f,54.0f));
                  blocks.setPoint(6,Vector2f(18.0f,36.0f));
                  blocks.setPoint(7,Vector2f(0.0f,36.0f));
                  break;
        case (4): blocks.setPointCount(8);
                  blocks.setPoint(0,Vector2f(0.0f,18.0f));
                  blocks.setPoint(1,Vector2f(18.0f,18.0f));
                  blocks.setPoint(2,Vector2f(18.0f,0.0f));
                  blocks.setPoint(3,Vector2f(36.0f,0.0f));
                  blocks.setPoint(4,Vector2f(36.0f,36.0f));
                  blocks.setPoint(5,Vector2f(18.0f,36.0f));
                  blocks.setPoint(6,Vector2f(18.0f,54.0f));
                  blocks.setPoint(7,Vector2f(0.0f,54.0f));
                  break;
        case (5): blocks.setPointCount(6);
                  blocks.setPoint(0,Vector2f(0.0f,54.0f));
                  blocks.setPoint(1,Vector2f(0.0f,0.0f));
                  blocks.setPoint(2,Vector2f(18.0f,0.0f));
                  blocks.setPoint(3,Vector2f(18.0f,40.0f));
                  blocks.setPoint(4,Vector2f(36.0f,36.0f));
                  blocks.setPoint(5,Vector2f(36.0f,54.0f));
                  break;
        case (6): blocks.setPointCount(6);
                  blocks.setPoint(0,Vector2f(0.0f,0.0f));
                  blocks.setPoint(1,Vector2f(54.0f,0.0f));
                  blocks.setPoint(2,Vector2f(54.0f,18.0f));
                  blocks.setPoint(3,Vector2f(36.0f,18.0f));
                  blocks.setPoint(4,Vector2f(36.0f,36.0f));
                  blocks.setPoint(5,Vector2f(18.0f,36.0f));
                  break;
    }

The L n J shape appear like this.

【问题讨论】:

  • 发布您尝试过的内容以及遇到的问题
  • 是的,请贴出相关代码和switch语句。
  • @AyushGupta 我添加了你要求的东西
  • @MartinSand 在代码中添加了开关
  • @Ayush 根据您的要求更新了帖子

标签: c++ sfml


【解决方案1】:

首先,在使用诸如 SFML 之类的库时,请务必记住,该库可能会为您提供方便的快捷方式(例如 sf::CircleShapesf::RectangleShape),但您不一定非要使用它们,尤其是当它向您展示更灵活的东西时,例如sf::VertexArray

接下来,您还必须记住,从基本原语构建四联体的方法不止一种。

这里最明显的一种是使用三角形或四边形。让我们使用四边形构建 T 形:

sf::VertexArray quads(sf::Quads);

// Left piece
quads.append({{0, 0}, sf::Color::White});
quads.append({{95, 0}, sf::Color::Red});
quads.append({{95, 95}, sf::Color::Green});
quads.append({{0, 95}, sf::Color::Blue});

// Center piece
quads.append({{100, 0}, sf::Color::White});
quads.append({{195, 0}, sf::Color::Red});
quads.append({{195, 95}, sf::Color::Green});
quads.append({{100, 95}, sf::Color::Blue});

// Right piece
quads.append({{200, 0}, sf::Color::White});
quads.append({{295, 0}, sf::Color::Red});
quads.append({{295, 95}, sf::Color::Green});
quads.append({{200, 95}, sf::Color::Blue});

// Bottom piece
quads.append({{100, 100}, sf::Color::White});
quads.append({{195, 100}, sf::Color::Red});
quads.append({{195, 195}, sf::Color::Green});
quads.append({{100, 195}, sf::Color::Blue});

请注意,移动平台不支持sf::Quads,您必须定义三角形而不是四边形。我还故意将四边形的长度/宽度缩短了 5 以留下可见的间隙。

可能更优雅(和高效)的解决方案是使用三角扇。由于 T tetromino 是凹形,因此您必须为您的风扇选择正确的起点,即使形状凹入的点之一。在其他情况下,您可能必须专门为此创建一个新的(不可见的)点,例如在形状内部。

sf::VertexArray triangleFan(sf::TriangleFan);

// Starting point is the bottom left corner of the center piece
triangleFan.append({{100, 100}, sf::Color::White});
triangleFan.append({{0, 100}, sf::Color::Red});
triangleFan.append({{0, 0}, sf::Color::Green});
triangleFan.append({{300, 0}, sf::Color::Blue});
triangleFan.append({{300, 100}, sf::Color::Magenta});
// The next point creates an invisible triangle just to move to the center piece
triangleFan.append({{200, 100}, sf::Color::Black});
triangleFan.append({{200, 200}, sf::Color::Cyan});
triangleFan.append({{100, 200}, sf::Color::Yellow});

分别用{50, 50}{50, 350} 的平移绘制这两个形状会在屏幕上产生两个巨大的四联体:

对于您的情况,您当然必须适当地缩放它们。

如果您仍有问题或想要编译、运行和使用某些东西,我已在 GitHub 上上传了 short example

【讨论】:

  • 非常感谢,但问题是我真的不明白顶点数组是如何工作的,你能解释一下吗?或者,如果您知道一个解释其工作原理的视频,您可以分享一个链接
  • @user9135740 您基本上可以查看任何关于此的 OpenGL(甚至 DirectX)教程。唯一的区别是您实际定义顶点的方式。 Here's an example guide showcasing the various possibilities and how they work. sf::VertexArray 基本上只是一个容器。您也可以改用std::vector&lt;sf::Vertex&gt;。顶点数组还定义了如何解释点列表。
  • 感谢马里奥的帮助,如果有困惑我会再问一遍
  • @Mario Complete off-topic:你到底是如何获得透明头像的?我已经和那个黑色方块战斗了好几个小时了,但我做不到......
  • 如果我改用三边条,如果我调整四边形,它们算作一个还是分开的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多