在平台顶部碰撞时出现问题

时间:2018-04-07 14:23:12

标签: c++ sdl-2 2d-games

跳跃时我遇到了一些碰撞问题,

当玩家跳到盒子上时,它会很奇怪,因为当它保持在盒子的顶部时,它会一直上下移动,我可以看到玩家的跳跃速度不断增加(因此它会下降)并且会减少(所以它会并且重力也是如此。

这就是我的意思:

https://youtu.be/jZikmJPKcOw

代码(我上传了新版本,之前有一个损坏的png错误) http://s000.tinyupload.com/index.php?file_id=07023750129261943350

我复制了代码的重要部分。

struct SPlayer
{
    void            Move();
    void            ApplyBoxCollision();
    float            Width        = 100.0f;
    float            Height        = 100.0f;
    float            XPosition    = (WINDOW_WIDTH * 0.5f) - (Width * 0.5f); //center of the screen
    float           YPosition   = 362;//top of the player
    float           YDesiredPosition = 362; //Player DesiredStart Position on Y axis (it updates every time Player.Yposition changes). So if I press S to jump at the very beginning of the program coming down the player will go to start position
    float           XDesiredPosition = 0;
    float           XPrevDesiredPosition = 0;
    float           YPrevDesiredPosition = 0;
    float            XVelocity    = 160.0f;
    float           YVelocity   = 160.0f;
    float           JumpVelocity = -422.0f;
    float           Gravity = 0;
    EPlayerState    State        = PLAYER_STILL;
    SDL_Texture*    playerTexturewr = nullptr;
    SDL_Texture*    playerTexturewl = nullptr;
    SDL_Texture*    playerTexturejr = nullptr;
    SDL_Texture*    playerTexturejl = nullptr;
    SDL_Texture*    playerTextureclimb = nullptr;
    SDL_Rect        Quad;

};





void HandleEvents(void)

{
    ....

                case SDLK_s:
                {
                    if (Player.OnLadder == false) //Player can jump only if not on ladder

                    {

                        keyS_Down = 1;//key down (it means we are pressing S)
                        keyS_Up = 0;//(Releasing S is disabled)


                        if (spritestill == 2) //was set to 2 when right key is pressed
                        {
                            Player.State = PLAYER_JUMP_RIGHT;

                        }

                        if (spritestill == 1) //was set to 1 when left key is pressed
                            Player.State = PLAYER_JUMP_LEFT;

                        if (Player.State == PLAYER_STILL)
                        {
                            Player.State = PLAYER_JUMP_RIGHT;

                        }

                    }
                    break;
                }

               ......

        else if( Event.type == SDL_KEYUP && Event.key.repeat == 0 )

        {
           ....


                case SDLK_s:
                {

                        keyS_Down = 1; //important: so player keeps jumping also when released (until it jump before being affected by gravity)
                    }
                    break;
                }






void SPlayer::Move()
{
    switch (Player.State)
    {

        case PLAYER_MOVING_LEFT:
            //converting double DeltaTime in float
            Player.XPosition += -Player.XVelocity*(float)DeltaTime;
            break;


        case PLAYER_MOVING_RIGHT:

            Player.XPosition += Player.XVelocity * (float)DeltaTime;
            break;


        case PLAYER_MOVING_UP:

                Player.YPosition += -Player.YVelocity * (float)DeltaTime;
                break;


        case PLAYER_MOVING_DOWN:
                Player.YPosition += +Player.YVelocity * (float)DeltaTime;
                break;
            }

        default:
            break;
    }
}




void Update(void) {

HandleEvents(); //check events every time we update....

    // Calculate the deltatime every time we update....
    NewTime        = SDL_GetTicks(); //time in msecs running since this call
    DeltaTime    = (NewTime - OldTime) / 1000.0; //convert msecs in seconds
    OldTime        = NewTime;.....

.............

if(keyS_Down == 1 ) //it means is true that I pressed S (the jump key)
    {

        Player.Gravity = 1022.0f;
        Player.JumpVelocity = Player.JumpVelocity += Player.Gravity * (float)DeltaTime;
        Player.YPosition += Player.JumpVelocity * (float)DeltaTime;


        if (Player.YPosition >= Player.YDesiredPosition)
        {
            Player.Gravity = 0;
            Player.JumpVelocity = -422.0f;
            Player.YPosition = Player.YDesiredPosition; 
/* every time the player gets down it is set to the current YDesiredPosition that is updated every time except when jumping*/
            keyS_Down = 0;
            Player.State = PLAYER_STILL;
        }

    }

    if (keyS_Down && keyL_Down)
    {
        Player.State = PLAYER_JUMP_LEFT;
        Player.XPosition -= 2.5f; //jump on the left

    }


    if (keyS_Down && keyR_Down)
    {
        Player.State = PLAYER_JUMP_RIGHT;
        Player.XPosition += 2.5f; //jump on the right

    }


    Player.ApplyBoxCollision();





void SPlayer::ApplyBoxCollision()
{

    for( int i = 0; i<2; i++)
       if ((QuadVsQuad(Player.Quad, Block[i].Quad) == true))
    {
        blockCollision = 1;

        Player.XPrevDesiredPosition = Player.XDesiredPosition;
        Player.YPrevDesiredPosition = Player.YDesiredPosition;


        //move back if we have collisions
        switch (Player.State)
        {
            case PLAYER_MOVING_LEFT:
                Player.XPosition += +Player.XVelocity*(float)DeltaTime;
                break;

            case PLAYER_MOVING_RIGHT:
                Player.XPosition += -Player.XVelocity * (float)DeltaTime;
                break;

            case PLAYER_MOVING_UP:
                Player.YPosition += +Player.YVelocity * (float)DeltaTime;
                break;

            case PLAYER_MOVING_DOWN:
                Player.YPosition += -Player.YVelocity * (float)DeltaTime;
                break;

            case PLAYER_JUMP_RIGHT:
                Player.YPosition = Player.YPosition -50; //to get on top of the box
                Player.Gravity = 0;
                Player.JumpVelocity = 0;
                KeyD_Down = 0;
                break;

            case PLAYER_JUMP_LEFT:
                Player.YPosition = Player.YPosition - 50; // top get on top of the box
                Player.Gravity = 0;
                Player.JumpVelocity = 0;
                break;
            default:
                break;
        }

        //update player quad after collision
        Player.Quad = {static_cast<int>(Player.XPosition), static_cast<int>(Player.YPosition) , static_cast<int>(Player.Width), static_cast<int>(Player.Height)};

    }
    else
        blockCollision = 0;




}

0 个答案:

没有答案