目录
How does SFML implement a camera?
Manipulating cameras with sf::View
Preface
● 在这一章中,我们将讨论摄像机和OpenGL,以及如何利用它们为我们带来好处。我们将深入讨论摄像机的主题,但是关于OpenGL,我们只简单提到了它在SFML中的集成。OpenGL API太大,本书无法涵盖,更不用说一章了。如果你不知道如何编写OpenGL代码,或者不希望使用OpenGL,那么跳过本章的最后一部分就可以了。另一方面,如果您想知道OpenGL如何帮助您,请查看本章的第二部分提供的内容。
在本章中,我们将介绍以下主题:
- 什么是相机?
- 使用sf :: View操作相机
- 什么是OpenGL?
- 在SFML中使用OpenGL
What is a camera?
● 在游戏的开发中, 很少不用到摄像机的时候。它们是任何游戏必不可少的一部分。本质上,相机是空间中的一个点,通过它你可以看到游戏世界。在2D和3D空间中,有更多与摄像机相关的参数,但是在这一章中,我们将只关注SFML所能提供的。
在开始代码之前,让我们先了解一些事实。由于SFML主要用于2D游戏,所以camera类只使用正交投影。在这个投影中,每个物体看起来似乎并没有透视上的增大; 正如你可能已经猜到的,另一种选择是透视投影,它实际上根据人眼的物理特性改变了物体在屏幕上的显示方式(物体在远处看起来更小,等等)。然而,这个投影主要用于3D游戏,它不属于2D游戏。这里有一个小小的比较:
在2D 游戏中使用透视投影没有多大意义,因为sprite的image 会distorted。这就是为什么SFML不提供使用它的原因。但是,我们总是可以用OpenGL创建一个自定义摄像机,这是我们将在本章后面讨论的主题。
When should we use a camera?
● 我们不一定非要操作摄像机。如果一款游戏只有一个屏幕(例如一款三人行棋游戏),那么修改相机就没有意义了,因为它总是在棋盘的中央是静止的。其他的例子可能包括浏览主菜单——同样,相机的位置是静止的,因此不需要做任何事情。
但是,假设我们正在制作角色扮演游戏(RPG),并且有一个值得探索的大世界。在这种情况下,我们会很容易地想要实现一个摄像机,要么与我们的角色一起移动,要么与之相关。大多数平台游戏的工作方式都是相同的,即使它们拥有不同的关卡。基本上 只要有关卡的游戏 我们都需要使用摄像机
现在我们已经了解了相机的基本概念,让我们来看看如何实现它。
How does SFML implement a camera?
● 如果我们想修改每个sf :: Window实例附带的默认摄像头,我们必须用 sf :: View类 处理。
View类的行为与典型的相机完全一样,通过一组参数限制玩家在世界上所能看到的东西。 这就是我们创建和使用View的方式:
sf::RenderWindow window(sf::VideoMode(482, 180), "Bad Squares!"); //创建窗口代码
auto wSize = window.getSize();
sf::View view(sf::FloatRect(0, 0, wSize.x, wSize.y));
// Initialize view
window.setView(view);
View类的构造函数接受一个FloatRect参数,该参数设置所想看到的视图区域。如果我们有一个更大的可视区域 那么区域中的内容就会缩降以至窗口可以容纳的下 ,反之亦然。在本例中,该区域与窗口大小匹配,因此不会改变对象的渲染方式。
最后,当我们在View中配置了所有内容时,我们需要通过调用RenderWindow :: setView()来告诉窗口使用它。这会拷贝视图到渲染窗口对象中 所以我们不用保存原始视图 之前我们对纹理也是这样类似处理的.
Manipulating cameras with sf::View
● 可以说,View类最重要的特性是它能够改变视图区域的中心。默认情况下,view的中心是view区域的中心,这意味着,如果我们的视图区域大小为( 640,480 ),视图的中心将是( 320,240 )。这使得渲染对象的位置(0;0)出现在左上角。这与使用SFML窗口的默认视图时的行为相同。要 修改 视图的中心,我们可以调用 View::setCenter ( ) 或 View : : Move ( );下面是一个例子:
sf::RenderWindow window(sf::VideoMode(482, 180), "Bad Squares!"); //创建窗口代码
auto wSize = window.getSize();
sf::View view(sf::FloatRect(0, 0, wSize.x, wSize.y)); // 获得 view 区域
//视图以世界点(0; 0)为中心
view.setCenter