我有一个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?
答案 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
。