Показать сообщение отдельно
Старый 04.09.2005, 06:52   #26
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Прыжки и реалистичность физики

давно пора было это сделать

Для нормальной реализации кинематики нам понадобится:
1)контроль за отрывом от земли и моментом соприкосновения с ней.
EntityPickMode terrain,2
теперь к земле можно применить операцию pick.
Global jump_bool
переменная под логику отрыва от поверхности.
;физика
jump_bool=True
pick_ent=LinePick(EntityX(user,1),EntityY(user,1),EntityZ(user,1),0,-3,0)
If pick_ent jump_bool=False
допишем в функции обновления игрока. И добавим
Text 10,10,"jump_bool="+jump_bool
Flip
в главном цикле.
Запустим.
И увидим, что программа работает неверно.
jump_bool=1, т.е. условие If pick_ent не срабатывает, т.е. LinePick возвращает 0, т.е. на расстоянии 3 ед. под игроком ничего "не цепляется" командой Pick =(
Вообще в этой точке будет как раз соприкосновение сферы игрока и земли, так что надо попробовать увеличить расстояние - методом калибровки подбираем значение=3.6
pick_ent=LinePick(EntityX(user,1),EntityY(user,1),EntityZ(user,1),0,-3.6,0)
Ориентировочное значение три я взял, исходя из ф-ции создания игрока:
user=CreateSphere()
k#=3
ScaleEntity user,k#,k#,k#
и если был бы внимательнее, посмотрел чуть ниже
EntityRadius user,k#
Радиус коллизи тоже равен 3, что как раз и объясняет возникшее затруднение. Наше расстояние должно быть немногим больше 3, как оказалось = 3.6 .
Теперь значение jump_bool характеризует состояние игрока - есть или нет сцепления.
2)время невзаимодействия с землёй.
перепишем обновление игрока ещё раз
;физика
	
	pick_ent=LinePick(EntityX(user,1),EntityY(user,1),EntityZ(user,1),0,-3.6,0)
	If pick_ent 
 jump_bool=False 
	Else
 jump_bool=True
	EndIf
время взаимодействия как-таковое нам нужно между обновлениями,а оно у нас уже есть.
3)скорости движения для их динамического изменения.
Global user_vy#
снова переписываем
	pick_ent=LinePick(EntityX(user,1),EntityY(user,1),EntityZ(user,1),0,-3.6,0)
	If pick_ent 
 jump_bool=False 
 user_vy#=0
	Else
 jump_bool=True
 user_vy#=user_vy#-G#*delta_t;v1=v2-a*t
	EndIf
	TranslateEntity user,0,user_vy#*delta_t,0
4)инициализация события "прыжок".
TranslateEntity user,0,user_vy#*delta_t,0
;;;
	If KeyHit(57) And jump_bool=False Then user_vy#=50
однако - не работает =(

после некоторых раздумий подправим физику:
	pick_ent=LinePick(EntityX(user,1),EntityY(user,1),EntityZ(user,1),0,-3.6,0)
	
	TranslateEntity user,0,user_vy#*delta_t,0,True
	
	If pick_ent
 jump_bool=False
 user_vy=0
 TranslateEntity user,0,-1,0,True
	Else
 jump_bool=True
 user_vy#=user_vy#-G#*delta_t;v1=v2-a*t
	EndIf

;;;
	If KeyHit(57) And jump_bool=False Then user_vy#=1
И гравитацию на 0.001
Однако теперь объект не смещается вниз, пока его не сдвинут вперёд-назад или влево-вправо.
Я думаю, логика игры не пострадает, если предположить, что человек, прыгая вверх чуть-чуть смещается вперёд.
	TranslateEntity user,0,user_vy#*delta_t,user_vy#*0.01,True
Всё!
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием