【问题标题】:Prevent collisions in an animated game防止动画游戏中的碰撞
【发布时间】:2018-06-23 12:57:45
【问题描述】:

我一直在尝试编写一种方法来防止我的角色接触墙壁,这样他就无法穿过它,但我找不到像你在这个视频中看到的那样的正确方法(我录制的) .对(体面的)麦克风质量感到抱歉:https://youtu.be/jhTSDgSXXa8。我还说要防止碰撞,而是它会检测到并停止,但您可以通过。

碰撞代码是:

foreach (PictureBox pbMur in pbListeMurs)
{
    if (pbCharacterCat.Bounds.IntersectsWith(pbMur.Bounds))
    {
        if (pbCharacterCat.Right > pbMur.Left)
        {
            bWalkRight = false;
            bIdle = true;              
        }                        
     } 
}

谢谢! :D

【问题讨论】:

  • 你当前的代码是...?
  • 所以你想让我们去别的地方,看一个游戏的视频,然后想象一下代码可能是什么样子,然后设计碰撞代码?请阅读How to Ask 并采取tour
  • @InBetween 哟对不起,我忘了!已添加!
  • 你正在检查猫是否在墙内,但你没有纠正这种情况,你必须把猫拉到墙外:D
  • @Gusman 我如何在不破坏动画的情况下做到这一点。因为将猫传送回来会很丑。

标签: c# collision-detection collision


【解决方案1】:

我不确定您如何使用 bIdlewalkRight,但是这些类型的布尔标志很容易出错,并且当您通常尝试堵塞漏洞并结束时,它会使您的整个代码变得一团糟在这个过程中不断涌现新的。

首先,你为什么需要它们?这还不够吗?

var newPotentialCharacterBounds = 
    GetNewBounds(pbCharacterCat.Bounds, movementDirection);
var collidedWalls = pbListeMurs.Where(wall => 
    wall.Bounds.IntersectsWith(newPotentialCharacterBounds));

if (!collidedWall.Any())
{
    pbCharacterCat.Bounds = newPotentialCharacterBounds   
}

//else do nothing

这是如何工作的?好吧,前提是你的角色不能从一个无效的位置开始,如果它永远不允许到达一个无效的位置,那么你永远不需要撤消移动或重置位置。

我建议您创建一个描述所有可能方向的枚举:

enum Direction { Up, Down, Left, Right };

当给出相应的方向命令时,获取角色的潜在新位置(newPotentialCharacterBoundsGetNewBounds)。如果该位置与任何东西发生碰撞,则什么也不做,如果没有,则移动!

更新:伪代码如下:

//event handler for move right fires, and calls:
TryMove(pbCharacterCat, Direction.Right)


//event handler for move left fires and calls:
TryMove(pbCharacterCat, Direction.Left)

//etc.

private static Rectangle GetNewBounds(
    Rectangle current, Direction direction)
{
     switch (direction)
     {
          case Direction.Right:
          {
              var newBounds = current;
              newBounds.Offset(horizontalDelta, 0);
              return newBounds;
          }
          case Direction.Left:
          {
              var newBounds = current;
              newBounds.Offset(-horizontalDelta, 0);
              return newBounds;
           }
          //etc.   
}

//uses System.Linq
private bool TryMove(Control ctrl, Direction direction)
{
    var newBounds = 
        GetNewBounds(ctrl.Bounds, direction);
    var collidedWalls = pbListeMurs.Where(wall => 
        wall.Bounds.IntersectsWith(newBounds));

    if (!collidedWall.Any())
    {
        ctrl.Bounds = newBounds;   
        return true;
    }

    //Can't move in that direction
    Debug.Assert(collidedWall.Single); //sanity check
    return false;
}

因为TryMove 返回移动是否成功,现在您可以利用该信息;例如不同的音效等。

【讨论】:

  • 我有点明白你向我展示的内容,但不太明白如何使用它。
猜你喜欢
  • 1970-01-01
  • 2016-07-06
  • 2018-05-26
  • 1970-01-01
  • 2017-12-28
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多