如何使用此代码设置重力? [英] How can I set gravity using this code?

查看:170
本文介绍了如何使用此代码设置重力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一个游戏,并坚持重力.....在下面的代码中,一个矩形代表一个播放器,当我向上按键,它在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);
}
}


解决方案

您的代码可以工作,但有一个显着的问题:




  • 您的初始位置为350。

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


  • 但是,你的代码保持播放器不脱离屏幕( y> = 350-1 )基本上解决到检查 y > = 349 ,因此您的排名将永久重置为350.




要解决此问题,只需删除 -1 或将> = c>> 。






虽然你的方法应该工作应用),你应该重新思考你的策略和存储一个速度除了一个位置。我最近写了以下示例代码。这不是完美的,但它应该教你几个基础的跳跃和运行游戏(不一定是做这样的事情的唯一方法):




  • 允许玩家跳跃。

  • 应用重力。

  • 允许玩家根据持续时间键。



  #include< SFML / Graphics.hpp> ; 

int main(int argc,char ** argv){
sf :: RenderWindow window;
sf ::事件事件;

sf :: RectangleShape box(sf :: Vector2f(32,32));
box.setFillColor(sf :: Color :: White);
box.setOrigin(16,32);

box.setPosition(320,240);

window.create(sf :: VideoMode(640,480),跳框[光标键+空格]);
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(false);

//玩家位置
sf :: Vector2f pos(320,240);

//播放器速度(每帧)
sf :: Vector2f vel(0,0);

//重力(每帧)
sf :: Vector2f gravity(0,.5f);

//最大下降速度
const float maxfall = 5;

//运行加速
const float runacc = .25f;

//最大运行速度
const float maxrun = 2.5f;

//跳加速度
const float jumpacc = -1;

//在
中加速的帧数const unsigned char jumpframes = 10;

//计算你仍然可以加速的帧数
unsigned char jumpcounter = 0;

// inputs
bool left = false;
bool right = false;
bool jump = false;

while(window.isOpen()){
while(window.pollEvent(event)){
switch(event.type){
case sf :: Event :: KeyPressed:
case sf :: Event :: KeyReleased:
switch(event.key.code){
case sf :: Keyboard :: Escape:
window。关();
break;
case sf :: Keyboard :: Left:
left = event.type == sf :: Event :: KeyPressed;
break;
case sf :: Keyboard :: Right:
right = event.type == sf :: Event :: KeyPressed;
break;
case sf :: Keyboard :: Space:
jump = event.type == sf :: Event :: KeyPressed;
break;
}
break;
case sf :: Event :: Closed:
window.close();
break;
}
}

//逻辑更新开始

//首先,应用速度
pos + = vel;

//确定玩家是否在地面上
const bool onground = pos.y> = 480;

//现在更新速度...
// ...更新重力
vel + =重力;

// ... capping gravity
if(vel.y> maxfall)
vel.y = maxfall;

if(left){//向左移动
vel.x - = runacc;
}
else if(right){//向右移动
vel.x + = runacc;
}
else {//不再运行了;减慢每个帧
vel.x * = 0.9;
}

//跳跃
if(jump){
if(onground){//在地上
vel.y + = jumpacc * 2;
jumpcounter = jumpframes;
}
else if(jumpcounter> 0){//空中的前几个帧
vel.y + = jumpacc;
jumpcounter--;
}
}
else {//跳转键释放,停止加速
jumpcounter = 0;
}

//检查与地面的碰撞
if(pos.y> 480){
vel.y = 0;
pos.y = 480;
}

//检查与左边界的碰撞
if(pos.x< 16){
vel.x = 0;
pos.x = 16;
}
else if(pos.x> 624){
vel.x = 0;
pos.x = 624;
}


//逻辑更新结束

更新位置
box.setPosition(pos);

window.clear();
window.draw(box);
window.display();
}
return 0;
}


I am trying to make a game and am stuck on gravity..... In the following code a rectangle stands for a player and when I press up key it moves in y-axis but when I activate gravity on it (i.e resetting its previous position) it does not animate (i.e. It does not jumps) instead it just stays in its position. I am using SFML library of C++ and that's a game development tool. Please Help!

#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);
}
}

解决方案

Theoretically your code would work, but there's one significant problem:

  • Your initial position is 350.

  • Now your "jumping code" (which will allow the player to fly indefinitely!) triggers and your position is changed to 349.

  • However, your code keeping the player from dropping off the screen (y >= 350-1) essentially resolves to the check y >= 349, which will be true, so your position is permanently reset to 350.

To solve this, just remove the -1 or replace the >= operator with >.


While your approach should be working (once the fix above is applied), you should rethink your strategy and store a velocity in addition to a position. I've recently written the following example code. It's far from being perfect, but it should teach you a few basics for a jump and run game (not necessarily the only way to do such things):

  • Allow the player to jump.
  • Apply gravity.
  • Allow the player to determine jump height based on how long he holds down a key.

#include <SFML/Graphics.hpp>

int main(int argc, char **argv) {
    sf::RenderWindow window;
    sf::Event event;

    sf::RectangleShape box(sf::Vector2f(32, 32));
    box.setFillColor(sf::Color::White);
    box.setOrigin(16, 32);

    box.setPosition(320, 240);

    window.create(sf::VideoMode(640, 480), "Jumping Box [cursor keys + space]");
    window.setFramerateLimit(60);
    window.setVerticalSyncEnabled(false);

    // player position
    sf::Vector2f pos(320, 240);

    // player velocity (per frame)
    sf::Vector2f vel(0, 0);

    // gravity (per frame)
    sf::Vector2f gravity(0, .5f);

    // max fall velocity
    const float maxfall = 5;

    // run acceleration
    const float runacc = .25f;

    // max run velocity
    const float maxrun = 2.5f;

    // jump acceleration
    const float jumpacc = -1;

    // number of frames to accelerate in
    const unsigned char jumpframes = 10;

    // counts the number of frames where you can still accelerate
    unsigned char jumpcounter = 0;

    // inputs
    bool left = false;
    bool right = false;
    bool jump = false;

    while (window.isOpen()) {
        while (window.pollEvent(event)) {
            switch(event.type) {
            case sf::Event::KeyPressed:
            case sf::Event::KeyReleased:
                switch (event.key.code) {
                case sf::Keyboard::Escape:
                    window.close();
                    break;
                case sf::Keyboard::Left:
                    left = event.type == sf::Event::KeyPressed;
                    break;
                case sf::Keyboard::Right:
                    right = event.type == sf::Event::KeyPressed;
                    break;
                case sf::Keyboard::Space:
                    jump = event.type == sf::Event::KeyPressed;
                    break;
                }
                break;
            case sf::Event::Closed:
                window.close();
                break;
            }
        }

        // logic update start

        // first, apply velocities
        pos += vel;

        // determine whether the player is on the ground
        const bool onground = pos.y >= 480;

        // now update the velocity by...
        // ...updating gravity
        vel += gravity;

        // ...capping gravity
        if (vel.y > maxfall)
            vel.y = maxfall;

        if (left) { // running to the left
            vel.x -= runacc;
        }
        else if (right) { // running to the right
            vel.x += runacc;
        }
        else { // not running anymore; slowing down each frame
            vel.x *= 0.9;
        }

        // jumping
        if (jump) {
            if (onground) { // on the ground
                vel.y += jumpacc * 2;
                jumpcounter = jumpframes;
            }
            else if (jumpcounter > 0) { // first few frames in the air
                vel.y += jumpacc;
                jumpcounter--;
            }
        }
        else { // jump key released, stop acceleration
            jumpcounter = 0;
        }

        // check for collision with the ground
        if (pos.y > 480) {
            vel.y = 0;
            pos.y = 480;
        }

        // check for collision with the left border
        if (pos.x < 16) {
            vel.x = 0;
            pos.x = 16;
        }
        else if (pos.x > 624) {
            vel.x = 0;
            pos.x = 624;
        }


        // logic update end

        // update the position
        box.setPosition(pos);

        window.clear();
        window.draw(box);
        window.display();
    }
    return 0;
}

这篇关于如何使用此代码设置重力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆