无法将CCSprite减速度绑定到ccTime dt

时间:2011-05-21 01:52:59

标签: iphone ios cocos2d-iphone benchmarking

我有一个CCSprite的子类,它知道如何基于两个浮动属性,velX和velY来移动自身。我从游戏层中的同名方法调用子类的- (void)update:(ccTime)dt方法。

我使用dt来衡量我移动玩家的程度,它运作得很好。我想使用dt来缩放减速因子,以使玩家减慢速度,无论其更新频率如何。

但它只是让我的CCSprite不显示。

这是CCSprite类......


#import "Player.h"

#define kDeceleration 0.95

@implementation Player

@synthesize velX, velY;

# pragma mark

+ (id)player
{
    Player *player = nil;
    if ((player = [[[super alloc] initWithFile:@"rocket.png"] autorelease])) {
    player.velX = 0.0;
    player.velY = 0.0;
    }
    return player;
}

- (void)update:(ccTime)dt
{
    CGSize winSize = [[CCDirector sharedDirector] winSize];

    // move
    self.position = ccp(self.position.x + self.velX * dt, self.position.y + self.velY * dt);
    if (self.position.x < -self.contentSize.width/2) self.position = ccp(winSize.width + self.contentSize.width/2, self.position.y);
    if (self.position.x > winSize.width + self.contentSize.width/2) self.position = ccp(-self.contentSize.width/2, self.position.y);
    if (self.position.y < -self.contentSize.width/2) self.position = ccp(self.position.x, winSize.height + self.contentSize.width/2);
    if (self.position.y > winSize.height + self.contentSize.width/2) self.position = ccp(self.position.x, -self.contentSize.width/2);

    // decelerate
    self.velX *= kDeceleration * 0.0165 / dt; // works if the line is: self.velX *= kDeceleration;
    if (fabs(self.velX) < 1.0) self.velX = 0.0;
    self.velY *= kDeceleration * 0.0165 / dt; // works if the line is: self.velY *= kDeceleration;
    if (fabs(self.velY) < 1.0) self.velY = 0.0;

}

- (void)draw
{
    [super draw];
    glLineWidth(1);
    ccDrawCircle(ccp(self.contentSize.width/2, self.contentSize.height/2), 3*self.contentSize.width/4, CC_DEGREES_TO_RADIANS(360), 60, NO);
}

@end

问题出在// decelerate部分。如果我遗漏了使播放器减速的两条线的* 0.0165 / dt部分,它可以正常工作,但由于帧率差异,它在手机上比模拟器更快。这应该缩放它,但它只是搞砸了。

我尝试了各种NSLogging,如果我使用dt,我会得到nan我的velX和velY属性的值。

是否与使用方法名称-update?

有关

1 个答案:

答案 0 :(得分:2)

请尝试使用此公式:

float decelerator = pow(kDeceleration, 60 * dt);
self.velX *= decelerator;
self.velY *= decelerator;

数学背后的逻辑:

假设模拟器上的帧速率与设备上的正常60fps相比为30fps。因此,对于模拟器上的每个帧,设备已经显示2帧。因此,模拟器上update上的每次调用都应该为设备上的2次调用提供相同的结果。在设备上进行两次调用后,self.velX已经两次乘以kDeceleration,这意味着新值等于self.velX * kDeceleration * kDeceleration。同样的逻辑,如果模拟器上的帧速率是设备上的帧速率的1/3,则新值为self.velX * kDeceleration * kDeceleration * kDeceleration。因此,我们可以将其概括为self.velX * pow(kDeceleration, n),其中n是update方法调用以获得60fps帧率的次数,即60 * dt