views:

319

answers:

1
                        ** STILL NOT WORKING **

I am using below formula to move the ball circular, where accelX and accelY are the values from accelerometer, it is working fine.

But the problem in this code is mRadius (I fixed its value to 50), i need to change mRadius according to accelerometer values and also i need bouncing effect when it touches the track. Currently i am developing code by assuming only one ball is on the board.

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

Here is the snap of the game i want to develop:

Balls Game

Updated: I am sending the updated code...

 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];
}

In the above code i have initialized mRadius and mRange(indicate track) to some constant for testing, i am not getting the moving of the ball as i expected( bouncing effect when Collided with track ) with respect to accelerometer. Help me to recognize where i went wrong or send some code snippets or links which does the similar job.

I am searching for better logic than my code, if you found share with me.

+2  A: 

If I understand your code correctly, then the ball's position is directly controlled by the iPhone's orientation (tilt). So, tilting the iPhone to the right will place the ball at the right side of the track (3 o'clock). I believe you may want the balls acceleration (or, at least, its velocity) to be controlled. Then, you integrate the acceleration to velocity and the velocity to place, taking into account the constraints (the track walls).

The way it is set now, I don't see how you'd control more than one ball (as per the image you posted).

Then, for the bouncing effect: if you mean bouncing by the track's wall, then this will be a small modulation of the mRadius. If you mean bounce by other ball, then you'd modulate the angular position (by means of angular velocity) of the two balls to reflect the reaction.

EDIT: for integration of acceleration to velocity and then to position, for the purpose of this game, you can do with 1st order rectangular integration. Also, it will be more realistic to make the acceleration proportional to the tilt angle. Given the accel values from the iPhone itself, you can assign a 1:1 relation between the balls accel and the device reading. So, you'd like something like:

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

Note: the above formulae for velocity and position are 1st order approximation but should be sufficient for the purpose of this game.

Ka, Kv, Kp are some proportion coefficients. Choose them to make the relation between the sensed acceleration and the ball movement as you like. dT is the time difference between updates of the state of the ball. The function Am_I_NOT_touching_a_wall_in_X_direction() returns a 1 if the ball is free to move horizontally (in the direction of the tilt) and 0 otherwise.

Calculations for Y movement is symmetrical.

ysap
can you send some sample code which integrate the acceleration to velocity.
Chandan Shetty SP
Well, it really depends on what "not smooth" means. It can be caused from many reasons. Until you dig it down, there is no sense in sticking to a specific "smoothing algorithm".
ysap
I am sending the updated code, please go through the code...
Chandan Shetty SP