0

在过去的几天里,我一直在尝试制作类似乒乓球的游戏。我有 2 个桨和一个球。所有动态精灵。除了我遇到的一个问题外,一切都运行良好。球往往会在某个点以相同的角度反弹。所以有时玩家可以简单地在特定部分移动球拍,游戏可以持续一段时间或可能永远,因为无论击中球拍的哪个部分,球都不会改变其角速度. 我正在使用线速度和角速度的组合来保持球像这样移动:

if(_isPaused == FALSE)
{
    _world->Step(dt, 10, 10);
    for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
        if (b->GetUserData() != NULL) {
            CCSprite *sprite = (CCSprite *)b->GetUserData();
            if(sprite.tag == 2)
            {
                b2Vec2 dir = b->GetLinearVelocity();
                dir.Normalize();
                float currentSpeed = dir.Length();
                int maxSpeed = 60;
                float accelerate = vel;

                if(currentSpeed <= maxSpeed)
                {
                    b->SetLinearVelocity(accelerate * dir);
                }

                sprite.position = ccp(b->GetPosition().x * PTM_RATIO,
                                      b->GetPosition().y * PTM_RATIO);
                sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());

                //Keep sprite from bouncing in a straight angle
                b->SetAngularVelocity(_body->GetAngle());
            }}}

所以我的问题是,我如何操纵角速度以使球在每次与我的桨碰撞时以不同的角度弹跳?我正在考虑获取当前角速度然后将其乘以某个值,但我不确定这是否是解决我遇到的问题的正确方法。任何建议或想法将不胜感激。提前致谢。

4

2 回答 2

1

在我看来,你有两个选择:

  1. 检查碰撞的位置。如果它靠近桨的顶部/底部边缘,则将传出速度偏转一个与该点表面“曲率”成比例的角量。当然,这是作弊,但如果艺术品和代码一致,它看起来是正确的。图形是“不被抓住的作弊艺术”。
  2. 您可以考虑桨的当前速度以及球的当前速度。例如:如果球向下和向右移动,并且桨向下移动,那么您可以使用线性动量守恒来计算传出方向。只要确保将桨沿水平轴的动量变化限制为零即可。

最后,您可以结合上述技术,但现在您必须使用准确的碰撞检测(不是我在上面 (1) 中描述的 hack)。

希望有帮助!

于 2013-03-08T06:51:40.297 回答
0

一些指针,你应该SetLinearVelocity()很少使用SetAngularVelocity()。每一个都会改变 body 定义的一个属性,当事情变得更复杂时,这可能会让你遇到问题。最好使用ApplyForceToCenter()ApplyLinearImpulse()代替,SetLinearVelocity()因为这两个功能更加通用,并且对编码器更友好。

在我看来,我认为你不应该使用b->SetAngularVelocity(_body->GetAngle());如果你想在每次碰撞时改变角速度,你可以在你的beginContact方法中写下每次身体与桨体碰撞时,都会应用随机角脉冲对球,使用ApplyAngularImpulse().

希望有帮助。

于 2013-03-30T22:03:59.027 回答