【问题标题】:How to sense if two objects are touching each other in XNA Game Studio?如何在 XNA Game Studio 中感知两个物体是否相互接触?
【发布时间】:2015-05-02 11:48:53
【问题描述】:

我最近开始在 XNA Game Studio 中使用 C# 编写游戏,但是我无法检测球何时击中特定方块,有人可以帮忙吗?

注意:blocksPosition 是一个数组,因为它们有多个

这是我的代码:

public Boolean DetectBallBox(int BoxNum)
    {
        if (blocksPosition[BoxNum].X >= ballPosition.X + ball.Width && blocksPosition[BoxNum].Y >= ballPosition.Y + ball.Height)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

public void detectBallCollision()
    {
        for (int blockCount = 0; blockCount < 40; blockCount++)
        {
            if (DetectBallBox(blockCount))
            {
                Console.WriteLine("Block Hit");
            }
        }
    }

【问题讨论】:

  • 您能推荐一些比 xna 更好、更新的东西吗?
  • 试试谷歌。这是另一个讨论:stackoverflow.com/questions/10714091/…
  • @steve “有点 OT,但 XNA 已经报废了。” - 也许。但是作为学习工具还是很有用的

标签: c# xna


【解决方案1】:

简单的解决方案:

使用 Rectangle.Intersects:

Rectangle x = new Rectangle(ball.x, ball.y, ball.width, ball.height);
Rectangle y = new Rectangle(x,y, width, height);
return x.Intersects(y);

答案很简单,因为球更像椭圆... :)

更好的解决方案

寻找矩形和椭圆的交点:

System.Drawing.Rectangle brick = new Rectangle();
int ballX, ballY, radiusX, radiusY;

brick.Width = // dont see it in your code
brick.Height = // dont see it in your code
brick.X = blocksPosition[BoxNum].X;
brick.Y = blocksPosition[BoxNum].Y;

ballX = ballPosition.X;
ballY = ballPosition.Y;

radiusX = ball.Width;
radiusY = ball.Height;

// find closest point:
var closestX = Math.Min(brick.Width + brick.X, Math.Max(ballX, brick.X));
var closestY = Math.Min(brick.Height + brick.Height, Math.Max(ballY, brick.Y));

// find distance:
var distanceX = ballX - closestX;
var distanceY = ballY - closestY;

// if distance is lesser then circle radius, then we have intersaction:
var dSq = ((distanceX * distanceX) + (distanceY * distanceY))
if (dSq < (radiusX*radiusX))
{
  return dSq < (radiusY*radiusY);
}
return false;

最佳解决方案 (©®™):

使用任何 2d 物理引擎,比如 Farseer。从头开始学习更多,但最终对您来说会更好,更容易。

球击砖的快速而肮脏的例子如下所示:

World world = new World(new Vector2(0f, 0f)); // no gravity

Body myBall = world.CreateBody();
myBall.BodyType = BodyType.Dynamic;
CircleShape circleShape = new CircleShape(0.5f);
Fixture fixture = myBall.CreateFixture(circleShape);

Fixture brick = FixtureFactory.CreateRectangle();
// etc... Setting Position and so on.
// Its big topic to discuss here whole project.

每一帧:

world.Step(0.033333f); // 60 fps

在最终项目中,您将拥有两个“空间” - 一个是物理空间(您/先知将计算碰撞、力等),第二个是您从物理世界中绘制身体的地方(顺便说一句 - 身体只是空间中的一个点) ,Shape 是任何形状/多边形,Fixture 是将 Body 和 Shape 结合在一起的东西……正如我所说,这是一个非常大的话题。请随意询问有关 Farseer 的任何其他问题 :))

【讨论】:

    猜你喜欢
    • 2016-06-18
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2012-10-02
    • 2018-07-05
    • 1970-01-01
    相关资源
    最近更新 更多