C++ 如何使用此代码设置重力?

C++ 如何使用此代码设置重力?,c++,sfml,C++,Sfml,我正试图做一个游戏,却被地心引力困住了。。。。。在下面的代码中,一个矩形代表一个玩家,当我按下向上键时,它在y轴上移动,但当我在其上激活重力(即重置其先前位置)时,它不会动画(即,它不会跳跃),而只是停留在其位置。我使用的是C++的SFML库,这是一个游戏开发工具。请帮忙 #include <SFML/Graphics.hpp> int main(){ sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Gravity");

我正试图做一个游戏,却被地心引力困住了。。。。。在下面的代码中,一个矩形代表一个玩家,当我按下向上键时,它在y轴上移动,但当我在其上激活重力(即重置其先前位置)时,它不会动画(即,它不会跳跃),而只是停留在其位置。我使用的是C++的SFML库,这是一个游戏开发工具。请帮忙

#include <SFML/Graphics.hpp>

int main(){
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Gravity");


sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(100, 100));
rectangle.setFillColor(sf::Color::Black);
rectangle.setPosition(sf::Vector2f(10, 350));

while(window.isOpen())
{
    sf::Event Event;
    while(window.pollEvent(Event))
    {
        if(Event.type == sf::Event::Closed)
        {
            window.close();
        }
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        rectangle.move(0, -1);
    }
    if(rectangle.getPosition().y >= 350-1)
    {
        rectangle.setPosition(0, 350);
    }
    window.display();
    window.clear(sf::Color::Cyan);
    window.draw(rectangle);
}
}
#包括
int main(){
渲染窗口(sf::视频模式(80060032),“重力”);
sf::矩形形状的矩形;
矩形.setSize(sf::Vector2f(100100));
矩形.setFillColor(sf::Color::Black);
矩形。设置位置(sf::Vector2f(10350));
while(window.isOpen())
{
sf::事件;
while(window.pollEvent(事件))
{
如果(Event.type==sf::Event::Closed)
{
window.close();
}
}
如果(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
矩形。移动(0,-1);
}
if(rectangle.getPosition().y>=350-1)
{
矩形。设置位置(0350);
}
window.display();
窗口。清除(sf::颜色::青色);
窗口。绘制(矩形);
}
}

理论上,您的代码可以工作,但有一个重要问题:

  • 你的初始位置是350

  • 现在你的“跳跃代码”(允许玩家无限期飞行!)触发,你的位置改为349

  • 但是,您阻止播放机从屏幕上掉下来的代码(
    y>=350-1
    )基本上解析为检查
    y>=349
    ,这将是真的,因此您的位置将永久重置为350

要解决此问题,只需删除
-1
或将
=
运算符替换为


虽然你的方法应该有效(一旦应用了上述修正),但你应该重新考虑你的策略,并在位置之外存储速度。我最近编写了以下示例代码。这远不是完美的,但它应该教会你一些跳跃和跑步游戏的基本知识(不一定是做这些事情的唯一方法):

  • 允许玩家跳跃
  • 施加重力
  • 允许玩家根据他按住钥匙的时间来确定跳跃高度
#包括
int main(int argc,字符**argv){
sf::RenderWindow窗口;
sf::事件;
矩形盒(sf::Vector2f(32,32));
box.setFillColor(sf::Color::White);
框。设定原点(16,32);
设置位置(320240);
创建(sf::VideoMode(640480),“跳转框[光标键+空格]”;
设置帧率限制(60);
window.setVerticalSyncEnabled(false);
//球员位置
矢量2F位置(320240);
//播放器速度(每帧)
向量2f级(0,0);
//重力(每帧)
重力矢量2f(0.5f);
//最大下降速度
常量浮点最大值=5;
//跑步加速
常量浮点runacc=.25f;
//最大运行速度
常量浮点最大运行=2.5f;
//跳跃加速度
常量浮动跳线ACC=-1;
//要在中加速的帧数
const unsigned char jumpframes=10;
//计算仍可以加速的帧数
无符号字符跳线计数器=0;
//投入
布尔左=假;
布尔右=假;
布尔跳跃=假;
while(window.isOpen()){
while(window.pollEvent(事件)){
开关(事件类型){
案例sf::事件::按键:
案例sf::Event::KeyReleased:
开关(事件、键、代码){
案例sf::键盘::转义:
window.close();
打破
案例sf::键盘::左:
left=event.type==sf::event::KeyPressed;
打破
案例sf::键盘::右:
右=event.type==sf::event::KeyPressed;
打破
案例sf::键盘::空间:
jump=event.type==sf::event::KeyPressed;
打破
}
打破
案例sf::事件::已结束:
window.close();
打破
}
}
//逻辑更新启动
//首先,应用速度
pos+=vel;
//确定球员是否在地面上
const bool onground=pos.y>=480;
//现在更新速度为。。。
//…更新重力
vel+=重力;
//…盖帽重力
如果(y级>最大下降)
y级=最大落差;
如果(左){//向左运行
x级-=runacc;
}
如果(右){//向右跑
等级x+=runacc;
}
else{//不再运行;降低每帧的速度
x级*=0.9;
}
//跳跃
如果(跳转){
如果(在地面上){//
y级+=跳线附件*2;
跳线计数器=跳线帧;
}
如果(jumpcounter>0){//空中的前几帧
y级+=跳线ACC;
跳转计数器--;
}
}
否则{//释放跳跃键,停止加速
跳线计数器=0;
}
//检查是否与地面发生碰撞
如果(位置y>480){
y级=0;
位置y=480;
}
//检查是否与左边框发生碰撞
如果(位置x<16){
x级=0;
位置x=16;
}
否则,如果(位置x>624){
x级=0;
位置x=624;
}
//逻辑更新结束
//更新职位
设置位置(pos);
window.clear();
窗.画(框);
window.display();
}
返回0;
}

+1我误解了这一点,以为帽子是球员落地时戴的。我需要睡觉。