在目标C中增加并保持对象的恒定速度

时间:2011-02-08 15:47:06

标签: iphone objective-c

我之前发过类似的东西,但我得到了一些建议,但我仍然遇到问题......因此,我想在审核此代码时提出任何帮助。

我实际上是想让代码中的球对象拥有更好或更平滑的动画并不断提高其速度直到达到最大速度但是现在我得到的是以指定速度开始的球随着速度的增加,它的运动变得不稳定,几秒后,球就会从iphone模拟器屏幕移开。

有人可以帮助我运行此代码(请在IB中添加一个代表球的图像),看看我做得不好。

提前感谢您的帮助。

   .h

@interface ViewController : UIViewController 
{
    UIImageView *ball;
    int speedX;
    int speedY;
    CGPoint ballMovement;
}
@property (nonatomic, retain) IBOutlet UILabel *scoreLabel;
@property (nonatomic, retain) IBOutlet UIImageView *ball;

- (void)initializeTimer;
- (void)animateBall:(NSTimer *)theTimer;

@end



.m

@implementation ViewController
@synthesize ball;

- (void)dealloc {
    [ball release];
    [super dealloc];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    ball.center = CGPointMake(50,50);

    speedX = 1;
    speedY = 1;

    ballMovement = CGPointMake(speedX,speedY);

    [self initializeTimer];
}

- (void)initializeTimer {
    float theInterval = 0.1f;
    [NSTimer scheduledTimerWithTimeInterval:theInterval target:self selector:@selector(animateBall:) userInfo:nil repeats:YES];
}

- (void)animateBall:(NSTimer *)theTimer {
    ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);
    speedX += 1;
    speedY += 1;

    NSLog(@"%d,%d", speedX, speedY);

    if (speedX <= 1)    
        speedX ==1;
    if (speedY <= 1)
        speedY ==1;

    if(ball.center.x > 300 || ball.center.x < 20)
        speedX = -abs(speedX);
    if(ball.center.y > 440 || ball.center.y < 40)
        speedY = -abs(speedY);
}

3 个答案:

答案 0 :(得分:1)

你没有把速度限制在任何地方,那么它应该如何达到恒定的速度呢?从您的代码中,一旦您通过ball.center.x&gt; 300,你改变速度。

if (speedX <= 1) speedX ==1;
if (speedY <= 1) speedY ==1;

什么都不做,因为它们实际上并没有为speedX / speedY赋值。看起来这就是你的意思:

if (speedX <= 1) speedX = 1;
if (speedY <= 1) speedY = 1;

即便如此,这实际上也不会做你想要的。如果你想要一个最大速度,那么它应该是这样的:

// Compact version
speedX = MIN(speedX + 1, TARGET_SPEED_X);

// More like your code:
speedX += 1;
if (speedX > TARGET_SPEED_X) speedX = TARGET_SPEED_X;

答案 1 :(得分:0)

加速度=速度/ Delta_time

所以你必须修改代码:

- (void)animateBall:(NSTimer *)theTimer {
    ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);

    static float acceleration = 1.0f;

    speedX += acceleration*theTimer.timeInterval;
    speedY += acceleration*theTimer.timeInterval;

    NSLog(@"%d,%d", speedX, speedY);

    if (speedX <= 1)    
        speedX ==1;
    if (speedY <= 1)
        speedY ==1;

    if(ball.center.x > 300 || ball.center.x < 20)
        speedX = -abs(speedX);
    if(ball.center.y > 440 || ball.center.y < 40)
        speedY = -abs(speedY);
}

答案 2 :(得分:0)

如果你想让球从底部反弹,沿着y轴重力:

- (void)animateBall:(NSTimer *)theTimer {
    ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);
    speedY += 1;

    if(ball.center.x > 300) {
        speedX = -abs(speedX);
    }
    if(ball.center.y > 440)
        speedY = -abs(speedY);
}

您看到的不稳定运动的主要原因可能是因为屏幕顶部/侧面反弹。例如:

if(ball.center.y > 440 || ball.center.y < 40)
    speedY = -abs(speedY);

当球在这里飞向顶部时会发生什么?比如说ball.center.y = 30,speedY = -4。 你的速度Y将保持在-4。接下来将它传递-3,然后是-2,然后是-1,然后它将在-1和0之间振荡。对于speedX最终也是如此。

问题是你正在寻找什么样的运动。您的原始代码在(1,1)方向上看起来像是恒定加速度,在右下角有一个反弹效果,但您的描述表明您希望加速到最大速度。

对于最快速度的加速球:

@interface ViewController : UIViewController {

    UIImageView *ball;
    double speedX;
    double speedY;
    int maxSpeed;
    double acceleration;
    CGPoint ballMovement;
}
@property (nonatomic, retain) IBOutlet UIImageView *ball;

- (void)initializeTimer;
- (void)animateBall:(NSTimer *)theTimer;

@end
@implementation ViewController

@synthesize ball;

- (void)dealloc {
    [ball release];
    [super dealloc];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    ball.center = CGPointMake(50,50);

    speedX = 1;
    speedY = 1;
    maxSpeed = 20;
    acceleration = 1;
    ballMovement = CGPointMake(speedX,speedY);

    [self initializeTimer];
}

- (void)initializeTimer {
    float theInterval = 0.1f;
    [NSTimer scheduledTimerWithTimeInterval:theInterval target:self selector:@selector(animateBall:) userInfo:nil repeats:YES];
}

- (void)animateBall:(NSTimer *)theTimer {

    ball.center = CGPointMake(ball.center.x + speedX, ball.center.y + speedY);

    // Discover the actual speed.
    double actualSpeed = sqrt(speedX * speedX + speedY * speedY);

    // Increase the speed by the acceleration (actually acceleration * time interval),
    // Cap at max speed
    double newSpeed = MIN(acceleration + actualSpeed, maxSpeed);

    // Increase velocity uniformly along both x and y axis
    // (This example does not properly handle when speedX and speedY both start at zero)
    speedX = speedX * newSpeed / actualSpeed;  
    speedY = speedY * newSpeed / actualSpeed;

    // Make sure to bounce
    if (ball.center.x > 300) speedX = -abs(speedX);
    if (ball.center.x < 20) speedX = abs(speedX);
    if (ball.center.y > 440) speedY = -abs(speedY);
    if (ball.center.y < 40) speedY = abs(speedY);
}

@end
相关问题