Программирование с нуля - это совсем просто! 161) Программирование 3D-игр: Видеокамеры и Функции
Школа программирования
161) Программирование 3D-игр: Видеокамеры и Функции
Последний выпуск по BlitzBasic, был N 157.
Камеры. Дополнительные возможности
Продолжаем изучение возможности камер.
Диапазон действия камеры
Команда
CameraRange camera, near, far
задает минимальное расстояние near, с которого камера начинает видеть, и максимальное расстояние far, с которого камера перестает видеть. Все объекты, расположенные ближе минимального и дальше максимального расстояний, камера не воспринимает и не отображает. По умолчанию эти расстояния приняты за 1 и 1000. Слишком большую разницу между максимумом и минимумом обзора камеры брать не рекомендуется - это может привести к повышенной вычислительной нагрузке.
Масштабирование
Популярный эффект приближения/удаления камеры (zoom) реализуется с помощью команды.
CameraZoom camera, zoom
Параметр "зума" может быть дробным числом (как и в случае параметров команды CameraRange)! Значение zoom по умолчанию, равное 1, означает, что масштабирование изображения не происходит.
Параметр zoom должен быть всегда больше нуля! Значение, большее 1, означает приближение; меньшее (0.5 например) - удаление.
Задание.
Добавьте в предыдущую программу вращения камеры автоматические плавные приближение/удаление камеры.
Функции
Допустим, мы сформировали некоторый набор команд, который в дальнейшем хотим использовать в разных местах программы. Каждый раз копировать его вручную неудобно, так как если потом эту последовательность операторов понадобится немного изменить, то изменения придется вносить и дублировать во множество строк.
Обычная практика программирования подразумевает выделение таких часто используемых групп команд в блоки или модули. Они называются функции.
Функция начинается с ключевого слова
Function
за которым следует ее название, выбранное программистом, и круглые скобки, а заканчивается парой слов
End Function
Между ними записываются команды, которые в дальнейшем будут многократно повторяться при указании только одного имени функции.
Глобальные переменные
К используемым в программе переменным можно обращаться из наборов команд внутри функций. Однако чтобы значения этих переменных корректно сохранялись до обращения к функции, внутри ее содержимого и после нее, надо такие переменные (они называются глобальные) предварительно описать в начале программы с помощью команды Global.
Рассмотрим такой пример. Допустим, мы написали программу, показывающую текущее число кадров в секунду (FPS):
Graphics 800,600,16
SetBuffer BackBuffer()
FirstTime = Millisecs()
FPS = 0
N = 0
while not KeyHit(1)
Cls
if MilliSecs() > FirstTime + 1000 then
FirstTime = Millisecs()
FPS = N
N = 0
else
N = N + 1
end if
Text 400,100,FPS
Flip
Wend
Часть кода, рассчитывающая показатель FPS, удобно выделить в виде функции, чтобы потом свободно к нему обращаться из разных мест. Вот как это можно сделать:
Graphics 800,600,16
SetBuffer BackBuffer()
FirstTime = Millisecs()
FPS = 0
N = 0
while not KeyHit(1)
Cls
GetFPS()
Text 400,100,FPS
Flip
Wend
function GetFPS()
if MilliSecs() > FirstTime + 1000 then
FirstTime = Millisecs()
FPS = N
N = 0
Else
N = N + 1
end if
end function
Название нашей функции мы придумали сами - GetFPS. Значение числа кадров хранится в переменной FPS.
Код, находящийся внутри определения функции, выполняется, только когда в основной программе встречается вызов GetFPS(). При записи вызова функции надо указывать круглые скобки следом за ее названием.
Однако этот пример будет работать не так, как нужно - на экране все время будет показываться значение 0. Почему? Потому что внутри функции GetFPS() при ее вызове перед командой Text значения переменных N, FPS и FirstTime не трактуются как глобальные, и их новые вычисленные значения на каждом шаге формирования экрана не сохраняются.
Вот как надо изменить начало программы:
...
Global FirstTime = Millisecs()
Global FPS = 0
Global N = 0
...
Когда каждая из этих переменных встречается в тексте в первый раз, перед ней необходимо указать ключевое слово Global. Можно данный код переписать для большей наглядности и так:
...
Global FirstTime
Global FPS
Global N
FirstTime = Millisecs()
FPS = 0
N = 0
...
Так как переменным присваиваются значения уже после того, как они впервые были определены с помощью Global, смысл данного кода остается прежним.
Значение, возвращаемое функцией
Единственный недостаток нашего подхода - необходимость обращения к переменной FPS для получения значения числа кадров, хотя расчет ее величины происходит в функции GetFPS(). Сейчас мы переделаем ее так, чтобы получить число кадров можно было одним указанием названия GetFPS(). Такой подход хорош тем, что мы избавляемся от необходимости помнить как название функции, так и переменную, которые нужны для расчета одного параметра программы.
Для этого внутри функции надо указать, что она не просто выполняет некоторую группу команд, но и формирует некоторое значение, которое можно получить, обратившись к названию функции как к имени обычной переменной. Это достигается использованием команды Return, после которой ставится возвращаемое функцией значение.
Например:
Return 0
Важно! При выполнении этой команды работа функции сразу прекращается, и все следующие за ней операторы пропускаются.
Вот как GetFPS() может быть переписана:
function GetFPS()
if MilliSecs() > FirstTime + 1000 then
FirstTime = Millisecs()
FPS = N
N = 0
Else
N = N + 1
end if
return FPS
end function
Возвращаемое функцией значение равняется, как видно, содержимому переменной FPS. Тогда основную часть программы можно записать так:
while not KeyHit(1)
Cls
Text 400,100, GetFPS()
Flip
Wend
Функция GetFPS() здесь используется так же, как имя переменной. Хотя она не хранит значение, а рассчитывает его на лету, суть программы от этого не меняется.
Использование показателя FPS может быть самым разным. В одних программах удобнее привязывать анимационные события к числу кадров в секунду (когда выполняется объемная графическая работа, значение FPS может сильно изменяться), в других, где величина FPS достаточно стабильна и невелика, смену анимации проще выполнять через фиксированные промежутки времени (хотя принципиальной разницы между этими подходами нету, фиксированные промежутки все же менее гибки, нежели отношение номера текущего кадра в секунду к FPS).
Неплохо также основываться на показаниях FPS при определении детальности и качества изображения.
(c) 2004-2007 Сергей Бобровский : bo собака russianenterprisesolutions.com
Все эти учебные курсы рассчитаны не только на разработчиков, но и на всех тех, кто хочет стать ИТ-менеджером. Для этого как минимум нужно иметь общее представление о современных технологиях разработки и их истории и владеть соответствующей терминологией.
В книгах описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив один учебный курс, вы существенно сэкономите :) В книгах полностью описаны:
- Delphi (версия 2006, полностью совместимая с Turbo Delphi) для обеих платформ - Win32 и .NET;
- C# (новый язык Microsoft, на котором базируется платформа .NET и все новые версии Windows);
- C++ для платформы Win32.
Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книги.