1. 环境准备
-安装 SFML:
你可以从 SFML 官网 下载适合你操作系统的版本。
按照安装说明配置 SFML 库到你的开发环境。
第一步
如您所知,几乎所有 SFML 应用程序都以最小线框开始:
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(320, 480), "The Game!");
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
window.close();
}
window.clear(Color::White);
window.display();
}
return 0;
}
接下来,我们创建一个 sprite 来表示游戏中形状的各种元素,并为其分配一个名为 tiles.png 的纹理文件。纹理文件本身位于路径X:\dev\SFML_Tutorial\images\
.纹理由 8 个多色方块组成,一个接一个地水平站立。每个此类正方形的大小为 18×18 像素。
以下是将此纹理加载到程序中的代码:
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(320, 480), "The Game!");
Texture texture;
texture.loadFromFile("X:\\dev\\SFML_Tutorial\\images\\tiles.png");
Sprite sprite(texture);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
// 用户点击“X”关闭窗口
if (event.type == Event::Closed)
window.close();
}
// 设置背景颜色-白色
window.clear(Color::White);
window.draw(sprite);
window.display();
}
return 0;
}
如果我们编译并运行我们的项目,我们会看到以下内容:
现在,我们需要从整个 sprite 中选择一个单独的正方形,以便我们可以使用它来构建所需的俄罗斯方块形状。为此,请使用 setTextureRect() 方法:
// …
texture.loadFromFile("X:\\dev\\SFML_Tutorial\\images\\tiles.png");
Sprite sprite(texture);
// 切割一个18x18像素的正方形
sprite.setTextureRect(IntRect(0, 0, 18, 18));
// …
我们得到以下内容:
使用俄罗斯方块图形
问题如下:“我们如何以编程方式表示我们的数字?让我们仔细看看我们的数据。从维基百科中,您可以了解到我们的图形被称为四分体骨牌,因为每个图形都由 4 个方格组成。俄罗斯方块总共使用了 7 个这样的四元组小雕像:
因此,将它们描述为具有 7 行(根据形状数量)和 4 列定义每个特定形状形状的整数二维数组是非常合乎逻辑的。另一个问题出现了:“我们如何塑造?
您将在下面找到答案:
值得注意的是,我们不在乎绘制正方形的顺序。唯一重要的是,正方形是否被绘制。因此,一组(5,3,4,6)和一组(3,5,6,6)可以与第一个具有(3,5,4,6)相匹配。
场景也可以表示为整数field[m][n],其中m是场景的高度,n是场景的宽度。将这些元素添加到我们的代码中:
#include <SFML/Graphics.hpp>
using namespace sf;
const int M = 20;
const int N = 10;
int field[M][N] = { 0 };
int figures[7][4]=
{
1,3,5,7, // I
2,4,5,7, // S
3,5,4,6, // Z
3,5,4,7, // T
2,3,5,7, // L
3,5,7,6, // J
2,3,4,5, // O
};
场景中的四边形映射
现在,让我们试着在场景上展示我们的图形。要做到这一点,首先需要创建一个point结构,它将表示一个整数坐标点+两个辅助数组a[]和b[]:
int figures[7][4]=
{
1,3,5,7, // I
2,4,5,7, // Z
3,5,4,6, // S
3,5,4,7, // T
2,3,5,7, // L
3,5,7,6, // J
2,3,4,5, // O
};
struct Point
{
int x, y;
} a[4],b[4];
然后,在第一个FOR循环中,我们将每个单独的块的“局部”坐标转换为“全局”,然后在第二个FOR循环中,我们将所有这些都显示在游戏场景中。请注意,单个块的大小为18×18像素:
// …
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
window.close();
}
int n = 3;
for (int i = 0; i < 4; i++)
{
a[i].x = figures[n][i] % 2;
a[i].y = figures[n][i] / 2;
}
window.clear(Color::White);
for (int i = 0; i < 4; i++)
{
sprite.setPosition(a[i].x * 18, a[i].y * 18);
window.draw(sprite);
}
window.display();
}
return 0;
}
结果如下: