Уход от привязки к FPS
Frames Per Second
В текущей версии программы события (а именно: обновление ботов, игрока, выстрелов) будут происходить с частотой вызова соответствующих
ф-ций. Т.е. (как видно из записи главного цикла) с частотой прорисовки - ФПС. А значит напрямую будут зависеть от производительности
системы.
Избавиться можно 2мя способами:
1) Производить обновление N раз в секунду - что приведёт к принудительному занижению высоких ФПС и скачкообразной анимации.
2) Рассчитывать переменные скорости, ускорения и проч. в соответствии с дельтой времени. Что сейчас и сделаем.
Так как в следующих версиях алгоритма или уже в этой ( при большом кол-ве ботов) время начала обработки первого и последнего ботов
вероятно будет отличаться на целое кол-во мс и так же потому, что глобальные переменные делают программу, имхо, менее удобочитаемой и
переносимой, а так же плодят логические ошибки (из-за ошибок при вводе имени) - для каждого бота сделаем собственное время последнего
обновления.
Type bot
Field entity
Field time
End Type
Function update_bot()
v#=0.03
For a.bot=Each bot
;=
If a\time=0 a\time=MilliSecs()
new_time=MilliSecs()
delta_t=new_time-a\time
a\time=new_time
;=
PointEntity a\entity,user
MoveEntity a\entity,0,0,v#*delta_t
;физика
TranslateEntity user,0,-G#*delta_t,0
Next
End Function
Ёлки-палки :o :oops - только сейчас заметил, что боты притягиваются с коэффицентом 1 а не G
Переменная v# должна получиться универсальным значением для всех ПК (однако Вы можете откалибровать её по-точнее).
Проделаем операцию ухода... для выстрелов:
Type shot
Field entity
Field dist#
Field time
End Type
Function update_shot()
v#=0.1
max_dist#=1000
For a.shot=Each shot
;=
If a\time=0 a\time=MilliSecs()
new_time=MilliSecs()
delta_t=new_time-a\time
a\time=new_time
vs#=v*delta_t
;=
MoveEntity a\entity,0,0,vs#
a\dist#=a\dist#+vs#
bot_h=EntityCollided(a\entity,BOTT)
If a\dist#>max_dist#
FreeEntity a\entity
Delete a
ElseIf EntityCollided(a\entity,TERRT)0
FreeEntity a\entity
Delete a
ElseIf bot_h0
FreeEntity a\entity
Delete a
bhandle=EntityName(bot_h)
bc.bot=Object.bot(bhandle)
Delete bc
FreeEntity bot_h
create_bot(EntityX(user)+Rnd(-100,100),2,EntityZ(user)+Rnd(-100,100))
EndIf
Next
End Function
Обратите внимание здесь рассчитанная по дельте скорость используется не идиножды - сохраняем в отдельную переменную.
Теперь сам игрок.
Поскольку мультиплеером в игре и не пахнет - игрок реализован не типизированным объектом и он один. Заведём для его обновления глобальную
переменную:
Function update_user()
;=
If user_time=0 user_time=MilliSecs()
new_time=MilliSecs()
delta_t=new_time-user_time
user_time=new_time
;=
V#=0.02*delta_t
u#=70;предельный угол
TurnEntity camera,MouseYSpeed(),0,0
TurnEntity user,0,-MouseXSpeed(),0
If KeyDown(203)=1 Then MoveEntity user,-V#,0,0
If KeyDown(205)=1 Then MoveEntity user,V#,0,0
If KeyDown(200)=1 Then MoveEntity user,0,0,+V#
If KeyDown(208)=1 Then MoveEntity user,0,0,-V#
MoveMouse GraphicsWidth()*0.5,GraphicsHeight()*0.5
If Abs(EntityPitch#(camera))>u# RotateEntity camera,u#*Sgn(EntityPitch#(camera)),0,0
If MouseHit(1) create_shot(EntityX(user),EntityY(user),EntityZ(user),EntityPitch(camera),EntityYaw(user),0)
If MouseDown(2) create_shot(EntityX(user),EntityY(user),EntityZ(user),EntityPitch(camera),EntityYaw(user),0)
;физика
TranslateEntity user,0,-G#*delta_t,0
End Function
Осталось откалибровать коэффициент гравитации.
Пока поставил такое значение.