【问题标题】:How to create a circle shape without solid polygon or non solid circle``如何创建没有实心多边形或非实心圆的圆形``
【发布时间】:2013-11-20 10:14:59
【问题描述】:

我正在 box2d 中开发一个赌场轮盘游戏。如您所知,在此游戏中,球/骰子将位于圆形旋转轮中。

首先我尝试使用 b2circleShape,但没有成功。我的意思是球不在圆形内。

然后我尝试使用 b2EdgeShape。但是对于 b2edgeShape,我需要创建尽可能多的顶点来构建一个光滑的圆形表面。

反正我可以创建这样的圆形,它们不是多边形或不是实心多边形吗?

如果有任何解决方法请告诉我

【问题讨论】:

  • 您只能使用边缘或更好的链条形状来形成轮辋。如果它需要 100 个顶点,那就这样吧。
  • 如果您不知道:您可以将多个链形连接在一起以形成任意复杂的曲面。您不限于单个链形状中的固定数量的顶点。

标签: cocos2d-iphone box2d box2d-iphone


【解决方案1】:

您可以使用轮盘赌的单个主体来执行此操作。对它的“内部”部分使用圆形,对它的“外部”部分使用链形。

您可能应该在链条形状中使用“尖刺”来添加一些东西让球反弹。下面是主要的创建函数:

void MainScene::CreateBody()
{
   const float32 INNER_RADIUS = 2.50;
   const float32 OUTER_RADIUS = 3.0;
   const float32 BALL_RADIUS = 0.1;
   const uint32 DIVISIONS = 36;

   Vec2 position(0,0);

   // Create the body.
   b2BodyDef bodyDef;
   bodyDef.position = position;
   bodyDef.type = b2_dynamicBody;
   _body = _world->CreateBody(&bodyDef);
   assert(_body != NULL);

   // Now attach fixtures to the body.
   FixtureDef fixtureDef;
   fixtureDef.density = 1.0;
   fixtureDef.friction = 1.0;
   fixtureDef.restitution = 0.9;
   fixtureDef.isSensor = false;

   // Inner circle.
   b2CircleShape circleShape;
   circleShape.m_radius = INNER_RADIUS;
   fixtureDef.shape = &circleShape;
   _body->CreateFixture(&fixtureDef);

   // Outer shape.
   b2ChainShape chainShape;
   vector<Vec2> vertices;
   const float32 SPIKE_DEGREE = 2*M_PI/180;
   for(int idx = 0; idx < DIVISIONS; idx++)
   {
      float32 angle = ((M_PI*2)/DIVISIONS)*idx;
      float32 xPos, yPos;

      xPos = OUTER_RADIUS*cosf(angle-SPIKE_DEGREE);
      yPos = OUTER_RADIUS*sinf(angle-SPIKE_DEGREE);
      vertices.push_back(Vec2(xPos,yPos));

      xPos = OUTER_RADIUS*cosf(angle)*.98;
      yPos = OUTER_RADIUS*sinf(angle)*.98;
      vertices.push_back(Vec2(xPos,yPos));


      xPos = OUTER_RADIUS*cosf(angle+SPIKE_DEGREE);
      yPos = OUTER_RADIUS*sinf(angle+SPIKE_DEGREE);
      vertices.push_back(Vec2(xPos,yPos));
   }
   vertices.push_back(vertices[0]);
   chainShape.CreateChain(&vertices[0], vertices.size());
   fixtureDef.shape = &chainShape;
   _body->CreateFixture(&fixtureDef);

   // Create some "spikes" for the ball to bounce off of.

   // Start it spinning
   _body->SetAngularVelocity(M_PI/8);

   // NOW create a ball to bounce around inside...
   bodyDef.position = Vec2((INNER_RADIUS+OUTER_RADIUS)/2,0);
   _ballBody = _world->CreateBody(&bodyDef);
   circleShape.m_radius = BALL_RADIUS;
   fixtureDef.shape = &circleShape;
   _ballBody->CreateFixture(&fixtureDef);

   // Give it some velocity so it starts to bounce.
   _ballBody->SetLinearVelocity(Vec2(-0.5,0.5));
}

这就是它的样子:

我为此创建了一个演示。给球一些初始速度,它会反弹一点,但很快就会卡在外面(离心力?)。要完成这项工作,您可能需要继续刺激球以使其弹跳一段时间,直到您将其“吸引”到您希望它结束​​的井/传感器点。

或者您可以在外链内侧稍微使用第二个链条固定装置,它是“平滑的”。然后当你想让球安定下来时将其移除。无论如何,如果你想让它看起来像一个轮盘赌球,你需要用力让球移动一点,直到你想让它稳定下来。

我将整个项目(Cocos2d-x、c++)发布到github here

您可以在我的网站here 上找到有关使用 Box2d 的文章。

这有帮助吗?

【讨论】:

  • 它卡在钉子旁边的外侧的原因是因为您没有考虑到真正轮盘赌的倾斜圆锥形状和垂直重力。轮盘的内边缘也很光滑,没有尖刺......
  • @StevenLu 感谢您的反馈。创建轮盘赌形状的原始请求。我并没有特别关注物理的全面模拟。代码发布在 github 上,欢迎大家踊跃投稿,提升对大家的价值……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多