iphone - 当球撞击轨道时如何获得碰撞效果或弹力

标签 iphone objective-c math physics

                        ** STILL NOT WORKING **

我使用下面的公式来移动球,其中 accelXaccelY 是来自加速度计的值,它工作正常。

但是这段代码中的问题是mRadius(我将其值固定为50),我需要根据加速度计值更改mRadius,并且当我需要弹跳效果时它触及轨道。目前,我正在假设棋盘上只有一个球来开发代码。

float degrees = -atan2(accelX, accelY);
int x = cCentrePoint.x + mRadius * cos(degrees);
int y = cCentrePoint.y + mRadius * sin(degrees);

这是我想要开发的游戏的快照:

Balls Game http://iphront.com/wp-content/uploads/2009/12/bdece528ea334033.jpg.jpg

更新:我正在发送更新的代码...

 mRadius = 5;
 mRange = NSMakeRange(0,60);

-(void) updateBall: (UIAccelerationValue) accelX 
                                  withY:(UIAccelerationValue)accelY
{

    float degrees = -atan2(accelX, accelY);
    int x = cCentrePoint.x + mRadius * cos(degrees);
    int y = cCentrePoint.y + mRadius * sin(degrees);

    //self.targetRect is rect of ball Object
    self.targetRect = CGRectMake(newX, newY, 8, 9);
    self.currentRect = self.targetRect;

    static NSDate *lastDrawTime;

    if(lastDrawTime!=nil)
    {
       NSTimeInterval secondsSinceLastDraw =
                    -([lastDrawTime timeIntervalSinceNow]);

       ballXVelocity = ballXVelocity + (accelX * secondsSinceLastDraw) 
               * [self isTouchedTrack:mRadius andRange:mRange];
       ballYVelocity = ballYVelocity + -(accelY * secondsSinceLastDraw) 
               * [self isTouchedTrack:mRadius andRange:mRange];

      distXTravelled = distXTravelled + secondsSinceLastDraw
                          * ballXVelocity * 50;
      distYTravelled = distYTravelled + secondsSinceLastDraw 
                          * ballYVelocity * 50;

      //Updating the ball rect  
      CGRect temp = self.targetRect;
      temp.origin.x += distXTravelled;
      temp.origin.y += distYTravelled;

      //calculating new radius after updating ball position
      int radius = (temp.origin.x - cCentrePoint.x) / 
                               cos(degreesToRadians(degrees));

     if( !NSLocationInRange(abs(radius),mRange))
     {
         //Colided with the tracks...Need a better logic here
      ballXVelocity = -ballXVelocity;
     }
     else
     {
           // Need a better logic here
       self.targetRect = temp; 
     }

  }

  [lastDrawTime release];
  lastDrawTime = [ [NSDate alloc] init];
}

在上面的代码中,我已将 mRadius 和 mRange(指示轨迹)初始化为某个常量以进行测试,但我没有按照我的预期获得球相对于加速度计的移动(与轨迹碰撞时的弹跳效果)。帮助我识别哪里出错了,或者发送一些执行类似工作的代码片段或链接。

我正在寻找比我的代码更好的逻辑,如果您发现与我分享。

最佳答案

如果我正确理解你的代码,那么球的位置直接由 iPhone 的方向(倾斜)控制。因此,向右倾斜 iPhone 会将球放置在轨道的右侧(3 点钟方向)。我相信您可能希望控制球的加速度(或者至少是其速度)。然后,您将加速度与速度以及放置速度相结合,同时考虑约束(轨道墙)。

按照现在的设置方式,我不知道你如何控制多个球(根据你发布的图片)。

然后,对于弹跳效果:如果您的意思是通过轨道壁弹跳,那么这将是 mRadius 的一个小调制。如果您指的是其他球的弹跳,那么您需要调制两个球的角位置(通过角速度)来反射(reflect) react 。

编辑:为了将加速度积分到速度,然后积分到位置,为了这个游戏的目的,您可以使用一阶矩形积分。而且,使加速度与倾斜角度成正比会更现实。给定 iPhone 本身的加速度值,您可以在球加速度和设备读数之间分配 1:1 的关系。所以,你想要这样的东西:

BallAccX = AccelX * Am_I_NOT_touching_a_wall_in_X_direction() * Ka
BallVelX = BallVelX + BallAccX * dT * Kv
BallPosX = BallPosX + BallVelX * dT * Kp

注意:上述速度和位置公式是一阶近似,但对于本游戏的目的来说应该足够了。

Ka、Kv、Kp 是一些比例系数。选择它们可以使感测到的加速度与球运动之间的关系随心所欲。 dT 是球状态更新之间的时间差。如果球可以自由水平移动(沿倾斜方向),则函数 Am_I_NOT_touching_a_wall_in_X_direction() 返回 1,否则返回 0。

Y 方向移动的计算是对称的。

关于iphone - 当球撞击轨道时如何获得碰撞效果或弹力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2505616/

相关文章:

ios - 与直接获取 UIImage 相比,接收 NSData 并将其转换为 UIImage 是否有性能损失?

ios - Admob Native Advanced 不可点击

JavaScript 正弦波

iphone - 带有状态的 UIButton 图像

ios - 在 ios 中延迟加载图像?

iphone - 在 Storyboard 中创建自定义 UITableViewCell

java - 提高欧拉数并行计算的性能

c# - 尽可能完美的十进制算术

ios - 我想编写一个 iOS 应用程序并在我自己的手机上严格运行它供我自己使用。可能的?

ios - UITableViewCell:iPhone 6上复选标记旁边右侧的垂直线