向游戏添加其他实体会导致玩家移动得更慢

时间:2016-05-03 20:55:52

标签: game-physics sfml entities timedelta

警告:大帖,小问题

我试图使用SFML 2.3.2制作游戏,事情进展顺利。我有移动平台,一个可移动,跳跃,碰撞的玩家角色(尽管是一个盒子)。而且我也会根据时间的推移移动距离,而不是根据锁定的帧速率,但似乎我搞砸了。

问题:

我添加的实体越多(我的玩家角色碰撞和移动平台的框)玩家移动越慢,他跳越低,尽管使用(deltaTime *移动速度)计算(移动平台似乎是一致的)但在他们的动作中,无论实体的数量如何)

这是我迄今为止所做的最大项目,所以我会尽力提供所有相关信息。

首先,我将展示项目中所有文件的结构,这样,如果我需要的代码,我就可以问我"嘿,那里有什么?"。除此之外,我将复制我认为与此问题相关的代码。哪个是引擎代码(一个基本的代码),Player和VelocityModule

项目文件:

.h =仅限头文件

.cpp =仅限源文件

.h / .cpp =标题和源文件

Dutchtilities:

  • DutchFunctions.h /的.cpp
  • ExternalInclusion.h
  • gameHeaders.h
  • sheepPointer.h

实体:

  • Entity.h /的.cpp
  • MovingPlatform.h /的.cpp
  • Player.h /的.cpp
  • Quadrangle.h /的.cpp
  • EntityPack.h(所有其他实体标头的集合)

模块:

  • module.h中/的.cpp
  • TransformModule.h /的.cpp
  • HitboxModule.h /的.cpp
  • DrawModule.h /的.cpp
  • VelocityModule.h /的.cpp
  • ModulePack.h(所有其他模块标题的集合)

系统:

  • Engine.h /的.cpp
  • Level.h /的.cpp
  • Reader.h /的.cpp

我认为问题集中在VelocityModule及其更新方式

相关代码:

Engine.h

#ifndef ENGINE_H
#define ENGINE_H

// Forward Declaration
class Level;
#include "Reader.h"

class Engine
{
public:

    // Functions - System
    bool            update();
    void            initWindow();

    // Functions - Time
    sf::Time        getLastFrameTime();
    void            resetLastFrameTime();

    // Functions - Camera
    void            updateCamera();
    void            setCameraTransform( TransformModule* transform );
    void            setCameraOffset( sf::Vector2f &offset );
    void            setCameraOffset( float x, float y );
    sf::Vector2f    getCameraOffset();

    // Functions - Window
    void            setWindowName( const std::string &name );
    void            setWindowDimensions( sf::Vector2u &widthHeight );
    void            setWindowDimensions( unsigned width, unsigned height );
    sf::Vector2u    getWindowDimensions();

    // Functions - Levels
    void            loadLevel( Level* level );

    // Variables - Camera
    sf::View                camera;

    // Variables - Time
    sf::Clock               clock;
    sf::Time                deltaTime;

    // Variables - Window
    sf::RenderWindow        window;

    // Variables - Reader
    Reader                  fileReader;

    // Structors
    Engine();


protected:

    // Variables - Level
    Level*                      m_level;

    // Variables - Camera
    sheepPtr<TransformModule>   m_cameraTarget;
    sf::Vector2f                m_cameraOffset;

    // Variables - Time
    float                       m_frameTime;

    // Variables - Window
    sf::Event                   m_eventHandler;
    std::string                 m_windowName;
    sf::Vector2u                m_windowDimensions;

    // Variables - Game Loop
    bool                        m_paused;
};

#endif

引擎包含3个我认为重要的功能:

  • update()这是主要的游戏循环
  • getLastFrameTime()
  • resetLastFrameTime()

引擎::更新()

bool    Engine::update()
{
    this->resetLastFrameTime();

    bool isRunning = true;

    // if the window is open...
    if( this->window.isOpen() )
    {
        // Shortcuts
        Level &level = *(this->m_level);


        // LOOK AT WINDOW EVENTS ////////////////////////////////////////////////////////////////////////////////////////////////

        // Keyboard Events
        while( window.pollEvent( this->m_eventHandler ) )
        {
            // Stop program when X is pressed
            switch( this->m_eventHandler.type )
            {
            case sf::Event::Closed:
                this->window.close();
                isRunning = false;
                break;
            }
            // Pause/Resume game when escape is pressed
            if( this->m_eventHandler.type == sf::Event::KeyReleased &&
                this->m_eventHandler.key.code == sf::Keyboard::Escape)
            {
                this->m_paused = !m_paused;
                std::string line = (m_paused) ? "Game has paused\n" : "Game has unpaused\n";
                std::cout << line;
            }
        }

        // The main game loop
        if( this->window.hasFocus() &&
            m_paused == false )
        {
            // UPDATE ENTITY HITBOXES ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.hitboxUpdateEntities();
            // APPLY VELOCITIES TO TRANSFORMS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.updateVelocities();
            // DETECT COLLISIONS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.resetCollisionLists();
            level.createCollisionLists();
            // APPLY EFFECTS ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.updateEntities();
            // ADJUST FOR COLLISION ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.adjustHitboxes();
            // DRAW STUFF /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            level.updateDraws();


            this->updateCamera();
            this->window.display();
            this->window.clear();
        }
    }
    // Otherwise the window has closed
    else
        isRunning = false;

    return isRunning;
}

引擎:: getLastFrameTime()

sf::Time        Engine::getLastFrameTime()
{
    return this->deltaTime;
}

引擎:: resetLastFrameTime()

void            Engine::resetLastFrameTime()
{
    this->deltaTime = clock.getElapsedTime();
    this->clock.restart();
}

Player.h

#ifndef PLAYER_H
#define PLAYER_H

class Player : public Entity
{
public:

    void virtual update() final;
    void virtual hitboxUpdate() final;

    short health;
    float movementSpeed;
    float jumpingPower;

    Player();
    ~Player();


private:

    // Modules
    sheepPtr<TransformModule>   transform;
    sheepPtr<DrawModule>        draw;
    sheepPtr<HitboxModule>      collisionHitbox;
    sheepPtr<HitboxModule>      jumpHitbox;
    sheepPtr<VelocityModule>    velocity;

    bool m_grounded;
};

#endif // PLAYER_H

我认为重要的功能:

  • hitboxUpdate()

播放器:: hitboxUpdate()

void Player::hitboxUpdate()
{

    // Calculate the distance the player will move this update
    float distance = (this->movementSpeed * this->m_pEngine->getLastFrameTime().asSeconds() );


    // Jumping (Up)
    if( sf::Keyboard::isKeyPressed(sf::Keyboard::Space) &&
        this->m_grounded == true)
    {
        this->velocity->addVelocity( sf::Vector2f( 0, -(this->jumpingPower) ));
    }
    // Left
    if( sf::Keyboard::isKeyPressed(sf::Keyboard::A) )
        this->velocity->addVelocity( sf::Vector2f( -distance, 0 ));
    // Right
    else if( sf::Keyboard::isKeyPressed(sf::Keyboard::D) )
        this->velocity->addVelocity( sf::Vector2f( distance, 0 ));
}

VelocityModule.h

#ifndef VELOCITYMODULE_H
#define VELOCITYMODULE_H

class VelocityModule : public Module
{
public:
    // Functions - System
    void            update();

    // Functions - Velocity
    void            addVelocity( sf::Vector2f &velocity);
    sf::Vector2f    getVelocity();
    void            setVelocity( sf::Vector2f velocity );
    void            applyVelocity();
    void            setMaxVelocity( float maxVelocity );
    float           getMaxVelocity();
    void            setMinVelocity( float minVelovity );
    float           getMinVelocity();


    // Functions - Drag
    void            setDrag( float dragForce );
    float           getDrag();
    void            setApplyDrag( bool trueOrFalse );
    bool            getApplyDrag();

    // Functions - Gravity
    void            setGravity( float gravity );
    float           getGravity();
    void            setApplyGravity( bool trueOrFalse );
    bool            getApplyGravity();

    // Functions - Transform
    void                setTargetTransform( TransformModule* transform );
    TransformModule*    getTargetTransform();

    // Structors
    VelocityModule();
    ~VelocityModule();

private:
    // Variables - Velocity
    sf::Vector2f            m_velocity;
    float                   m_minVelocity;
    float                   m_maxVelocity;


    // Variables - Drag
    float                   m_dragForce;
    bool                    m_applyingDrag;
    static const float      MAX_DRAG;
    static const float      MIN_DRAG;

    // Variables - Gravity
    float                   m_gravityForce;
    bool                    m_applyingGravity;

    // Variables - Transform
    sheepPtr<TransformModule> m_targetTransform;

};

#endif // VELOCITYMODULE_H

VelocityModule函数我相信是相关的:

  • 更新()
  • addVelocity()
  • applyVelocity()

    void VelocityModule :: update() {

    // Shortcut frametime
    float seconds = this->m_pParentEntity->getLinkedEngine()->getLastFrameTime().asSeconds();
    
    
    // Apply Gravity, if it's enabled
    this->m_velocity.y += ( this->m_applyingGravity ) ? (this->m_gravityForce * seconds) : 0 ;
    // Apply drag, if it's enabled
    this->m_velocity *= ( this->m_applyingDrag ) ? pow( 1 - (m_dragForce/100), seconds ) : 1 ;
    
    // Shortcutting via calculations
    sf::Vector2f absoluteVelocity = sf::Vector2f(abs(this->m_velocity.x), abs(this->m_velocity.y));
    float maxFrameVel = this->m_maxVelocity * seconds;
    float minFrameVel = this->m_minVelocity * seconds;
    
    // Change velocities according to maximum and minimum barriers
    this->m_velocity.x = ( absoluteVelocity.x < minFrameVel ) ? 0 :
                         ( absoluteVelocity.x > maxFrameVel && m_velocity.x < 0 ) ? -maxFrameVel :
                         ( absoluteVelocity.x > maxFrameVel && m_velocity.x > 0 ) ? maxFrameVel :
                          m_velocity.x;
    
    this->m_velocity.y = ( absoluteVelocity.y < minFrameVel ) ? 0 :
                         ( absoluteVelocity.y > maxFrameVel && m_velocity.y < 0 ) ? -maxFrameVel :
                         ( absoluteVelocity.y > maxFrameVel && m_velocity.y > 0 ) ? maxFrameVel :
                          m_velocity.y;
    
    
    this->applyVelocity();
    

    }

VelocityModule :: addVelocity()

void            VelocityModule::addVelocity( sf::Vector2f &velocity)
{
    this->m_velocity += velocity;
}

VelocityModule :: applyVelocity()

void            VelocityModule::applyVelocity()
{
    if( m_targetTransform.ptr != nullptr )
    {
        // Shortcutting
        this->m_targetTransform->move( this->m_velocity );
    }
}

0 个答案:

没有答案