简体   繁体   English

C#Monogame:跳跃后“浮动”精灵

[英]C# Monogame: “floating” sprite after jumping

I'm currently working on a 2d platformer using Monogame. 我目前正在使用Monogame进行2d平台游戏。 I can draw a sprite, I can draw a character and level, I can move the character and jump, but when I jump, my character "floats" above the level block in stead of landing on it. 我可以画一个精灵,我可以绘制一个角色和等级,我可以移动角色并跳跃,但是当我跳跃时,我的角色“浮动”在等级块上方而不是降落在它上面。 The left and right collisions work fine, the character is stopped when it should be stopped, but when jumping it doesn't land properly. 左右碰撞工作正常,角色在应该停止时停止,但跳跃时它不能正确着陆。 I have the following code: 我有以下代码:

To check if the player wants to jump, a check is performed to see if the up arrow is pressed. 要检查玩家是否想跳,请执行检查以查看是否按下了向上箭头。

if(state.IsKeyDown(Keys.Up) && hasJumped == false)
{
    jumping = true;
}

After the check for the keypress is done, there's a check to see if the jumping variable is true 在完成按键检查后,检查jumping变量是否为真

if (jumping == true)
{
    jump();
} else if (falling == true && topOfBlock == false)
{
    fall();
}
else
{
    hasJumped = false;
    verticalMovement = 14;
}

Basically jumping checks whether you want to jump, falling checks if the character is falling, topOfBlock checks if the character is on top of a block, hasJumped checks whether a jump is currently in progress (so no double jump is possible) and verticalMovement is the amount of pixels the character jumps/falls per tick. 基本上jumping检查是否要跳跃, falling检查字符是否下降, topOfBlock检查字符是否在块顶部, hasJumped检查当前是否正在进行跳转(因此不能进行双跳)并且verticalMovement是每个刻度字符跳跃/下降的像素数量。

The jump() and fall() method look as follows: jump()fall()方法如下所示:

private void jump()
{
    if (verticalMovement >= 0)
    {
        position.Y -= verticalMovement;
        verticalMovement--;
    } else
    {
        jumping = false;
        hasJumped = true;
        falling = true;
    }
}

public void fall()
{
    position.Y += verticalMovement;
    verticalMovement++;
}

The code speaks for itself I think. 我认为代码说明了一切。 Basically if the character is no longer moving up, falling is set to true , which triggers the fall() method, as long as the character isn't on top of a block. 基本上,如果该字符不再被向上移动, falling被设置为true ,这会触发fall()方法,只要该字符不是上的块的顶部。

Finally the character's collision rectangle is updated to the new position of the character. 最后,角色的碰撞矩形将更新为角色的新位置。

colRect = new Rectangle((int)position.X, (int)position.Y, 64, 48);

Where position.X and position.Y are the character's X and Y position, and 64 and 48 are the sprite's width and height. 其中position.Xposition.Y是角色的X和Y位置,而6448是精灵的宽度和高度。

To check whether the collision rectangle intersects with the collision rectangle of a block I have the following code 要检查碰撞矩形是否与块的碰撞矩形相交,我有以下代码

private void checkCollision()
{
    bool topCol = false;
    for (int x = 0; x < blockTileArray.GetLength(0); x++)
    {
        for (int y = 0; y < blockTileArray.GetLength(1); y++)
        {
            if (blockTileArray[x, y] != null)
            {
                if (hero.colRect.Intersects(blockTileArray[x, y].topWall))
                {
                    topCol = true;
                }

            }
        }
    }

    if(topCol == true)
    {
        hero.topOfBlock = true;
    } else
    {
        hero.topOfBlock = false;
    }       
}

topCol is a bool that checks whether there's a collision with the top of the block or not. topCol是一个bool,用于检查是否与块顶部发生冲突。 The loops check for every block in the array whether the character intersects with it's topWall or not. 循环检查数组中的每个块,无论字符是否与topWall相交。 If so, it sets topCol to true. 如果是这样,它将topCol设置为true。 After the loop it it checks whether topCol is true or not. 在循环之后,它检查topCol是否为真。 If it is, it says hero.topOfBlock to true , which means the character shouldn't fall. 如果是,则将hero.topOfBlock表示为true ,这意味着角色不应该掉落。 If it's false , it sets hero.topOfBlock to false , which would trigger the fall() method in the Hero class, as long as jumping is false as well. 如果它是false ,它将hero.topOfBlock设置为false ,这将触发Hero类中的fall()方法,只要jumping也是假的。

Lastly, the topWall collision rectangle is created as follows: 最后, topWall碰撞矩形创建如下:

topWall = new Rectangle((int)position.X, (int)position.Y - size, size, 1);

position.X and position.Y are the X and Y positions, size is the width and height of the block (both are 30 as it's a square), the 1 is to make it just 1 pixel high. position.Xposition.Y是X和Y位置, size是块的宽度和高度(两者都是30,因为它是一个正方形),1是使它只有1个像素高。

Now as I said, the problem is that the character floats after jumping. 正如我所说,问题是角色在跳跃后浮动。 The starting y position is 402 pixels (with the first block's topWall.Y being 420, meaning the character stands on top of the block when the game loads), after jumping it should go back to 402. However; 起始y位置是402像素(第一个区块的topWall.Y是420,意味着当游戏加载时角色站在块的顶部),跳跃之后它应该回到402.然而; after jumping once, it goes to 374, then 373, then 387, 386, ..., 374, 373, back to 387 again and so on. 跳一次之后,它会变为374,然后是373,然后是387,386,......,374,373,再次返回387,依此类推。 I have no idea what's causing the problem. 我不知道是什么导致了这个问题。 I've tried multiple things, like tinkering with the collision rectangles of both the block and character but nothing seems to work. 我尝试了很多东西,比如修补块和角色的碰撞矩形,但似乎没有任何效果。 When I remove the - size from (int)position.Y - size in topWall = new Rectangle() (which I thought would be the problem), the character falls through the block, so that doesn't fix it either. 当我从(int)position.Y - size删除- size (int)position.Y - size topWall = new Rectangle() (我认为这将是问题)时,字符会通过块,因此也不会修复它。

Just to make a bit clearer what I mean, here are two pictures: 为了让我的意思更清楚一点,这里有两张图片:

When the game loads 当游戏加载时

After jumping once 跳了一次

You say 你说

"After the loop it it checks whether topCol is true or not. If it is, it says hero.topOfBlock to true, which means the character shouldn't fall." “在循环之后,它会检查topCol是否为真。如果是,则表示hero.topOfBlock为true,这意味着角色不应该掉落。”

which corresponds to your if-then conditionals at the top; 这对应于你在顶部的if-then条件; you don't mention setting the character's Y-coordinate to the top of the tile. 你没有提到将角色的Y坐标设置到拼贴的顶部。 I'm not sure if that would cause your issue, it depends on when you call checkCollision, but it's probably part of the issue. 我不确定这是否会导致您的问题,这取决于您何时调用checkCollision,但这可能是问题的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM