"честная" физика
Так-с приступим к добавлению гравитации. Объявим где-нибудь в глобале переменную ускорения
свободного падения
Обратите внимание на идентификатор const (константа) и тип переменной (#-с плавающей
точкой).
Теперь надо реализовать контроль за отрывом от поверхности...
Это можно сделать 2 способами через просчёт столкновений (Collisions) и через "пики"
(Pick). С одной стороны, так как Collisions обрабатывается дольше, сложнее в коде... и
самое главное так или иначе автоматически производит response - один из 3-х методов
обработки столкновения:
1: stop
2: slide1 - full sliding collision
3: slide2 - prevent entities from sliding down slopes
С другой стороны обрабатывать это будет проще... впал в раздумья... короче делаем через
collision.
Добавим в глобал константы типов
Const USERT=1;for user
Const TERRT=2;for terrain
Переходим в Create_user() и делаем следующее.
Переходим в Create_world() и делаем следующее.
и после вызова create_user()
Collisions USERT,TERRT,2,3
в главном цикле допишем
и наконец в update_user() нацарапем
;физика
TranslateEntity user,0,-G#,0
/сразу предупреждаю физиков: это не окончательный вараинт кода/
И мы смело двигаем пользователя вниз ф-цией TranslateEntity.
TranslateEntity отличается от MoveEntity безразличем к пространственной ориентации самой
модели. Пример: если объект перевернуть "на голову", то команда move вниз приведёт к
движению этого объекта вверх, Translate же будет двигать объект вниз.
Перейдём в create_user() и подправим кое-что:
Function create_user(x#=0,y#=10,z#=0)
PositionEntity camera,0,2,-0.5
Можно запускать! В начале текста я немного занизил высоту камеры относительно "ног", что
сейчас и исправил. Теперь, между прочим, стала заметна сфера. Вернёмся к ф-ции создания:
user=CreateSphere()
EntityAlpha user,0
Этим мы задали нулевую "альфу" для сферы - т.е. сделали её полностью прозрачной.
Термины "полностью прозрачный" и "невидимый" здесь не одно и то же. Если первый сводится к
изменению альфы (и объект просто не видим для камер), то второй реализуется командой
HideEntity (и объект убирается из процедуры рендера движка). Но об этом как-нибудь в другой раз.
Как очевидно, код:
TranslateEntity user,0,-G#,0
не совсем то, что нам нужно. Хотя вблизи земли разницы никакой нет (допустимые
приближения). Вообще, здесь гравитация (вернее её подобие) нужна не столько для симуляции реалистичной физики, сколько для "прижимания" игрока к земле.
;инициализация графики
Graphics3D 800,600,32
SetBuffer BackBuffer()
Global user
Global camera
Const G#=1
Const USERT=1;for user
Const TERRT=2;for terrain
;создание игрока
Function create_user(x#=0,y#=10,z#=0)
user=CreateSphere()
EntityAlpha user,0
camera=CreateCamera(user)
PositionEntity camera,0,2,-0.5
PositionEntity user,x#,y#,z#
EntityType user,USERT
End Function
;обновление игрока
Function update_user()
V#=0.5
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
;физика
TranslateEntity user,0,-G#,0
End Function
;создание игрового мира
Function create_world()
terrain=CreatePlane()
tertex=LoadTexture("terrain1.jpg")
ScaleTexture tertex,10,10
EntityTexture terrain,tertex
FreeTexture tertex
EntityType terrain,TERRT
create_user()
Collisions USERT,TERRT,2,3
End Function
;функции закончились
;--------------------------------
create_world()
;MAIN LOOP
While Not KeyHit(1)=1
update_user()
UpdateWorld()
RenderWorld()
Flip
Wend
;----------------------------
End