在我的场景中,我已覆盖默认的-(void) update: (CFTimeInterval) currentTime
功能。值得注意的是,currentTime
变量实际上是从大概任意系统时间开始以来经过的时间,而不是自上一帧起经过的时间。此更新功能贯穿我的所有角色,并根据每秒的速度和自上次更新后经过的时间(以秒为单位)应用其移动。以秒为单位获取自上次更新以来经过的时间的常用方法是在类中存储NSTimeInterval以存储上次更新,并从当前更新时间减去上次更新时间,获取经过的秒数。但是,初始经过的时间不为零。因此,从非常大的数量中减去零会产生数万秒的感知经过时间。因此,第一帧中已经运动的任何角色都会移动很远。
对此的明显解决方案是最初将最后更新时间设置为经过的初始时间。但是,我没有看到任何方法在SKScene
内,或更具体地在-(void) didMoveToView: (SKView *) view
内访问此内容。
另一种解决方案是将初始CFTimeInterval设置为负数,例如-1
。然后,人们会检查每个更新函数是否时间是-1
。如果是这样,可以将自上次更新以来经过的时间设置为0
,否则可以执行普通elapsedTime = currentTime - lastUpdate
。但是,执行此if语句每个更新函数似乎都很麻烦且不需要。
是否有其他方法可以准确找到自上次更新以来的经过时间?
答案 0 :(得分:0)
我想我理解......但我可能不会。如果我错了,请纠正我。但是你的问题是你的初始增量时间非常大,因此使用该值移动角色会导致它们立即跳到游戏的第一帧。如果是这样,那么你在更新中遗漏了一段关键代码。
if self.last_update_time == 0.0 { // this is the important part
self.delta = 0
} else {
self.delta = currentTime - self.last_update_time
}
self.last_update_time = currentTime
游戏开始时, last_update_time
时间总是0,而delta也总是0。在那之后,你的delta值将是非常小的数字,你可以用它来逐步移动你的精灵。
希望这很有帮助
答案 1 :(得分:0)
你认为每次迭代检查一个标志是浪费的,所以这是最有效的解决方案的问题。
我认为最好的(读取:最有效的)解决方案是不在第一个update
中应用任何更改,只需保存currentTime变量。这根本不会影响你的游戏玩法;没有人会注意到框架已被丢弃。您可以通过保存指向函数的指针,在update
的第一次迭代中调用该函数来执行此操作,这也将更改指向另一个函数的指针,然后update
将从该点调用第二个函数向前。
我认为您正在寻找的方法是CFAbsoluteTimeGetCurrent
,但SK的update
方法倾向于提前返回不同的时间,可能是因为花费了大量时间将时间推迟到update
与仅使用CFAbsoluteTimeGetCurrent
。如果您在不使用if
的情况下获得额外开销,则可以忽略currentTime
并始终在CFAbsoluteTimeGetCurrent
方法中使用update
。
然后,如果您担心每个帧中单个if
语句的开销,则不会使用框架。即使是最慢的移动处理器,每秒60 if
s也是微不足道的工作。