0

最近我在 C++ 中开始了一个关于 OpenGL 的项目,但我遇到了一个障碍。播放器是一个立方体,尺寸为 32x32,平台尺寸为 32x32。当重力到位时,玩家会按照应有的方式下落,撞击平台,并不断上下弹跳。

无论如何,这是我的 C++ 代码:

播放器.h:

typedef void *(*ccallbackv)(void);
typedef void *(*ccallbackc)(const std::string);

const float g_gravity = 0.52f;

class Player :
    public CBaseObject
{
    // Variables
    int m_health, m_stealth, m_maxHealth, m_maxStamina;
    float jumpForce;
    bool mEnabled;
    ccallbackv* c_damageCallback;
    ccallbackc* c_killedCallback;
    bool m_isOnGround;

    // Movement Variables
    Vector2f velocity;
    BoundingBox2D<float>* m_tilePosition, *m_oldTilePosition;
    GLuint m_texture;
    Level* level;



public:
    Player(void);
    virtual ~Player(void);
    virtual void SetDamageCallbackFunc(ccallbackv* func) { this->c_damageCallback = func; }
    virtual void SetKilledCallbackFunc(ccallbackc* func) { this->c_killedCallback = func; }
    virtual void Kill(CBaseObject* killer = NULL);
    virtual void Reset();
    virtual void Tick();
    virtual void Render();
    virtual void KeyPress(char);
    virtual void Enabled(bool v) { this->mEnabled = v; }
    virtual bool isEnabled() { return this->mEnabled; }
    virtual void Collision();
    virtual bool OnGround(bool r) { if(r != m_isOnGround) { m_isOnGround = r; } return m_isOnGround; }

    virtual void SetLevel(Level* level) { this->level = level; }
    virtual Level* GetLevel() { return level; }

    virtual Vector2f* getPosition(){
        return &this->m_tilePosition->getVector();
    }
    virtual BoundingBox2D<float>* getBoundries() { return this->m_tilePosition; }

    virtual void setPosition(const Vector2f position){
        return this->m_tilePosition->setVector(position);
    }
    virtual bool IsAlive(){
        return m_health > 0;
    }
    virtual bool HasStamina(){
        return m_stealth > 0;
    }
    virtual void SetJumpForce(float force){ this->jumpForce = force; } 
    virtual float getJumpForce() { return this->jumpForce; } 
};

播放器.cpp:

int movement_position = 0;
float old_y = 0;

Player::Player(void)
{
    this->SetTypeString("PLAYER_NON_NPC");
    m_texture = ImportTexture("Player.png");

    this->velocity = Vector2f(0,0);
    this->m_tilePosition = new BoundingBox2D<float>(64,0,32,32);
    this->mEnabled = true;
    this->OnGround(false);
    old_y = -5;

}

Player::~Player(void)
{
}
void Player::Kill(CBaseObject* killer){
    if( this->c_killedCallback != NULL )
        (*this->c_killedCallback)( std::string( "Player was killed by entity " + ( !killer->GetTypeString().empty() ) ? killer->GetTypeString()
        : "unknown."));

    this->m_health = 0;

}
void Player::Reset(){
    this->m_health = 100;
    this->m_stealth = 100;
}
void Player::Tick()
{
    if(!this->mEnabled) return;
    float ticks = std::toFloat(Time::getSystemTicksSeconds());

    m_oldTilePosition = this->m_tilePosition;

    if( GLOBALS::pressedKey == 'd' ){
        velocity.setX(clamp<float>(velocity.getX() + (1.0f / 10000) * ticks, -0.05f, 0.05f));
    }
    else if( GLOBALS::pressedKey == 'a' ){
        velocity.setX(clamp<float>(velocity.getX() - (1.0f / 10000) * ticks, -0.05f, 0.05f));
    }
    else {
        velocity.setX(0);
    }

    this->Collision();


    if( !m_isOnGround OR ( old_y != this->getBoundries()->getY() ) ){
        velocity.addY(clamp<float>(0.0001f * ticks, -0.005f, 0.005f));
    }


    if(m_oldTilePosition != this->m_tilePosition)
        glutPostRedisplay();


    if( ( old_y == this->getBoundries()->getY() ) ) {
        this->m_tilePosition->setY(old_y);
        velocity.setY(0);
    }
    this->m_tilePosition->addVector(this->velocity);
}

void Player::KeyPress(char i){

}
void Player::Collision(){
    if( this->level == NULL ) return;

    float old_yc = 0;

    std::vector<Tile*> mapData = this->level->GetMap();

    OnGround(false);

    for(unsigned int i = 0; i < mapData.size(); ++i){
        BoundingBox2D<float>* source = this->getBoundries();
        BoundingBox2D<float>* mapTile = mapData.at(i)->getBoundries();
        Vector2f mapTileVector = mapTile->getIntersectionDepth(source);
        Vector2f abs = mapTileVector.Absolute();

        if( mapTileVector != Vector2f(0,0) && mapTile->IntersectsWith(source)){

            if( abs.getX() > abs.getY() ){
                if( old_y <= mapTile->top() )
                    OnGround(true);

                if(m_isOnGround){
                    this->getBoundries()->setVector(Vector2f(this->m_tilePosition->getX(), this->m_tilePosition->getY() + mapTileVector.getY()));
                    old_yc = this->getBoundries()->getVector().getY();
                }
            }
        }   
    }

    old_y = old_yc;
}

void Player::Render()
{
    if( this->m_texture == 0x0 ) return;

    glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, this->m_texture);
        glBegin(GL_QUADS);
        ::glTexCoord2f(0.0f, 0.0f); ::glVertex2f(this->m_tilePosition->getX(),this->m_tilePosition->getY());
        ::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(this->m_tilePosition->getX(),this->m_tilePosition->getY() + this->m_tilePosition->getH());
        ::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(this->m_tilePosition->getX() + this->m_tilePosition->getW(),this->m_tilePosition->getY() + this->m_tilePosition->getH());
        ::glTexCoord2f(1.0f, 0.0f); ::glVertex2f(this->m_tilePosition->getX() + this->m_tilePosition->getW(),this->m_tilePosition->getY());
        glEnd();
    glDisable(GL_TEXTURE_2D);

}
4

0 回答 0