1

我得到了 NSIntersectionRect 用于碰撞检测的概念,但我似乎想不出如何为我的项目实现它。没什么花哨的,单击一个按钮,就会调用一个视图子类,并在窗口中的任意位置放置一个圆圈。在该视图中单击,圆圈会跳动(这使其成为活动视图)。如果您有一个活动视图,单击它外部的任何位置(但不在另一个圆圈上)都会将该视图移动到单击点。

我正在使用 [activeView animator setFrame: NSMakeRect(x, y, w, h)] 移动活动视图。我可以将其用于碰撞检测还是必须使用 CABasicAnimation?基本上我要做的是检测与其他圆圈的碰撞(此时不需要物理,只需停止运动)和/或应用程序窗口的边界。

如果有人可以将我推向正确的方向(教程链接,代码片段),我将不胜感激。

编辑:根据下面详细的答案,我需要更清楚一点。我对在哪里实施碰撞检测感到困惑。视图类的动画方法是一行代码。我将如何遍历屏幕上的每个静态圆圈来运行碰撞检查?这就是为什么我首先想知道,如果我需要使用 CoreAnimation、OpenGL 或像 Chipmunk 之类的东西,然后我是否能得到一个轻推或帮助,那就太好了。

4

1 回答 1

4

后来..回答您最近的问题:

这就是为什么我首先想知道,如果我需要使用 CoreAnimation、OpenGL 或像 Chipmunk 之类的东西,然后我是否能得到一个轻推或帮助,那就太好了。

答案 - 你绝对不需要 OpenGL :) 接下来,你绝对不需要像 Box2D 或 Chipmunk 这样的物理库......如果你愿意,你可以这样做,但是,这将是大量不必要的工作。需要明确的是:在您完全熟悉使用 DrawRect 之前,Chipmunk 之类的东西对您来说无论如何都是无用的,所以请忘记这一点。

Core Animation 不会真正帮助你。需要明确的是,您可能希望在动画发生时中断它。那是对的吗?

我对在哪里实施碰撞检测感到困惑。视图类的动画方法是一行代码。我将如何遍历屏幕上的每个静态圆圈来运行碰撞检查?

坏消息......如果你真的想中断动画,如果有碰撞,忘记核心动画。Core Animation 会让你将它作为动画的“一个单元”从 A 发送到 B。 它不会让你在中间停下来(如果发生碰撞)。所以,就是这样。

需要明确的是,这就是你想要做的对吗? 你让圆圈运动起来,如果它在路上碰到什么东西,你想让它停下来。它是否正确?如果是这样,请完全忘记核心动画并丢弃您迄今为止所做的任何工作。

您将不得不潜入“真正的”编程(无论这意味着什么)并开始使用 drawRect。你准备好了吗?!

在这一点上,我可能会提到:考虑购买一份Corona的副本(大约 100 美元——我相信演示是免费的)。您可以使用 Corona 在五分钟内完成您所描述的所有事情。(写这篇文章的时间是写这篇文章的 1/10??)我总是向那些对 iPhone 好奇的人推荐这个。如果你真的不想花 6 到 18 个月的时间成为一名枪手 iPhone 程序员 - 只需点击适用于 iPhone 的 Corona,只需花费一小部分时间就可以使用 Stack Overflow,你就可以让你的圈子在 iPhone 上疯狂跳跃屏幕。

因此,如果做不到这一点,您将不得不开始工作并学习如何启动计时器 (NSTimer) 并在 UIView 中使用 drawRect。

创建一个名为 MyFirstView 的新类(.h 和 .m 文件),它是 UIView 的子类(不是 UIViewController,它是为 wimps 设计的!)。您将需要 MyFirstView 中的 drawRect 方法并从那里继续!


原答案..

我不确定我明白你在说什么,但要清楚:

您想检测两个圆圈之间的碰撞。在您的情况下,所有圆圈的直径都相同。那是对的吗?

如果是这样,幸运的是这很容易做到。

编写一个获取两个 CGPoints 之间距离的例程。(如果您不知道该怎么做,我将其包含在下面。)

下一步,你必须知道你的圆圈的直径。假设该示例为 50.0。

接下来,这是一个检查两个圆圈是否发生碰撞的例程:

static inline bool areTwoCirclesColliding( CGPoint aa, CGPoint bb )
    {
    return ( distanceBetweenTwoCGPoints(aa,bb) < 50.0 );
    }

注意...如果您是 Objective C 的新手,请注意上面是完全有效的代码。只需将其粘贴到文件顶部即可。好吗?)

最后,你只需要检查你所有的圈子,一个对一个,看看是否有碰撞。

如果你有一个简单的固定数量的圆圈,比如说三个左右,只需写出所有代码行来检查是否有任何组合发生碰撞,因此:

areTwoCirclesColliding(a,b)
areTwoCirclesColliding(a,c)
areTwoCirclesColliding(b,c)

如果你有一个数组或某种圆圈列表,你只需要遍历它们并检查每个圆圈是否都没有接触到任何其他圆圈。在伪代码中,它可能是这样的......

for n in 1 to numberCircles
   oneCircle = circles[n]
   for m in n+1 to numberCircles
      anotherCircle = circles[m]
      if ( areTwoCirclesColliding(oneCircle,anotherCircle) )
         .. break, you found a collision

或者你可以这样写,没有区别..

for each aa in circles
  for each bb in circles
    if (aa != bb) if (areTwoCirclesColliding(aa,bb)) .. break, found collision

{除此之外 - 为了记录,您在该伪代码中检查每一对两次是完全不重要的,没问题。}

我无法为您编写实际代码,因为我不知道您使用的是什么结构,抱歉。

当然,如果您的圈子是一个对象,您可以明智地让它针对所有其他圈子进行自我测试,同样的想法。如果您有一个圈子的 SQL 数据库,请将它们全部相互测试。

幸运的是,您可以看到只需一 (1) 行代码即可检查两个圆圈是否发生碰撞。大约需要 3 或 4 行代码来检查你所有的圈子是否有碰撞。幸运的是,总共大约 5 行!

所以,这是一个非常简单的视频游戏物理教程,第 1.1.1.1 部分!!!!希望能帮助到你!如果这不是您想要达到的目标,那完全是浪费打字!:)

作为记录,这里有一个获取两个 CGPoints 之间距离的例程:

static inline float rawDistance(float x, float y, float p, float q)
    {
    return sqrt( ((x-p)*(x-p)) + ((y-q)*(y-q)) );
    }
static inline float distanceBetweenTwoCGPoints( CGPoint a, CGPoint b )
    {
    return rawDistance( a.x, a.y, b.x, b.y );
    }

注意...如果您是 Objective C 的新手,请注意上面是完全有效的代码。只需将其粘贴到文件的顶部即可。好吗?这就像使用 Apple 提供的任何日常功能,例如 x=CGLayerGetContext (),例如。享受!)

后来..根据大众的需求,对于一个对象,Circle ...

-(bool)isTouchingOtherCircle:(circle)c
  {
  return areTwoCirclesColliding(self.center, c.center);
  }
-(bool)isTouchingAnyOtherCircle
  {
  for oc in yourCircles
    if (oc != self)
      if ( [self isTouchingOtherCircle:oc] )
        return false;
  return true;
  }
于 2011-02-19T19:20:26.723 回答