SFML sf::View::move 反复无常
SFML sf::View::move inconstancy
更新:
我无法找出确切的问题,但我做了一个对我来说足够好的修复:每当玩家的 X 值小于屏幕宽度的一半时,我只需使用 sf::View::setCenter()
.
所以我正在重新创建 Zelda II 以帮助更好地学习 SFML,这样我就可以根据 Zelda II 制作自己的游戏。问题是屏幕滚动,由于某种原因,如果 link 离开墙并启动相机跟随他,然后向墙移动,相机将不会一直回到墙的尽头,出现在 scene/room 尽头的另一面墙上。这可以进行多次,以保持所述摄像头块离墙更远。这种情况发生在场景的两边,我有理由相信这与我试图使游戏框架独立有关,这是我的问题的附带 GIF 以帮助理解:
我的相机功能:
void Game::camera() {
if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) {
this->view.move(int(this->player.getVar('v') * this->player.dt * this->player.dtM), 0);
}
}
player.getVar()
是我用来获取玩家 x 位置和 x 速度的临时函数,使用参数 'x' returns 玩家 x 位置和 'v' returns x速度。 WIDTH
等于 256
,sceneWidth
等于 767
,这是我用于背景宽度的图像。 dt
和dtM
是我前面提到的帧独立的变量,这个就是减速度:
sf::Clock sclock;
float dt = 0;
float dtM = 60;
int frame = 0;
void updateTime() {
dt = sclock.restart().asSeconds();
frame += 1 * dt * dtM;
}
updateTime()
每帧都会调用,所以 dt
也会每帧更新一次。 frame
只是 Link 动画的帧计数器,与问题无关。屏幕上移动和呈现的所有内容分别乘以 dt
和 dtM
。
玩家的移动和摄像机的移动之间存在明显的不匹配......你没有显示移动玩家的代码,但如果我猜你没有投射到 int
那里的移动,就像您在 view.move
通话中所做的那样。如果您设置相机的绝对位置,那不会有问题,但是当您不断移动它时,小偏移量会累积每一帧,从而导致您的问题。
上的一个可能的解决方案是跳过转换,这是不必要的,因为 sf::View::move
接受浮点数作为参数。
void Game::camera() {
if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) {
this->view.move(this->player.getVar('v') * this->player.dt * this->player.dtM, 0);
}
}
或者更好的是,不使用view.move
而是直接设置相机每一帧的位置。类似于:
void Game::camera() {
if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) {
this->view.setCenter(this->player.getVar('x'), this->view.getCenter().y);
}
}
更新:
我无法找出确切的问题,但我做了一个对我来说足够好的修复:每当玩家的 X 值小于屏幕宽度的一半时,我只需使用 sf::View::setCenter()
.
所以我正在重新创建 Zelda II 以帮助更好地学习 SFML,这样我就可以根据 Zelda II 制作自己的游戏。问题是屏幕滚动,由于某种原因,如果 link 离开墙并启动相机跟随他,然后向墙移动,相机将不会一直回到墙的尽头,出现在 scene/room 尽头的另一面墙上。这可以进行多次,以保持所述摄像头块离墙更远。这种情况发生在场景的两边,我有理由相信这与我试图使游戏框架独立有关,这是我的问题的附带 GIF 以帮助理解:
我的相机功能:
void Game::camera() {
if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) {
this->view.move(int(this->player.getVar('v') * this->player.dt * this->player.dtM), 0);
}
}
player.getVar()
是我用来获取玩家 x 位置和 x 速度的临时函数,使用参数 'x' returns 玩家 x 位置和 'v' returns x速度。 WIDTH
等于 256
,sceneWidth
等于 767
,这是我用于背景宽度的图像。 dt
和dtM
是我前面提到的帧独立的变量,这个就是减速度:
sf::Clock sclock;
float dt = 0;
float dtM = 60;
int frame = 0;
void updateTime() {
dt = sclock.restart().asSeconds();
frame += 1 * dt * dtM;
}
updateTime()
每帧都会调用,所以 dt
也会每帧更新一次。 frame
只是 Link 动画的帧计数器,与问题无关。屏幕上移动和呈现的所有内容分别乘以 dt
和 dtM
。
玩家的移动和摄像机的移动之间存在明显的不匹配......你没有显示移动玩家的代码,但如果我猜你没有投射到 int
那里的移动,就像您在 view.move
通话中所做的那样。如果您设置相机的绝对位置,那不会有问题,但是当您不断移动它时,小偏移量会累积每一帧,从而导致您的问题。
上的一个可能的解决方案是跳过转换,这是不必要的,因为
sf::View::move
接受浮点数作为参数。void Game::camera() { if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) { this->view.move(this->player.getVar('v') * this->player.dt * this->player.dtM, 0); } }
或者更好的是,不使用
view.move
而是直接设置相机每一帧的位置。类似于:void Game::camera() { if (this->player.getVar('x') >= this->WIDTH / 2 and this->player.getVar('x') < this->sceneWidth - this->WIDTH / 2) { this->view.setCenter(this->player.getVar('x'), this->view.getCenter().y); } }