|
| |
Сообщение: 35
Зарегистрирован: 19.05.07
Рейтинг:
0
|
|
Отправлено: 23.05.07 14:26. Заголовок: Re:
Определение текстуры довольно сложно воспринимается на слух, практическое закрепление будет более результативным. Файл - это растровый рисунок с расширением bmp, png или jpg. bmp-рисунок можно создать в редакторе Paint, который можно запустить, нажав кнопку "Пуск", затем выбрав в меню Программы->Стандартные->Paint. Рисунки желательно копировать в директорию, где находится программа либо указывать полный путь к ним. Мы будем использовать рисунки из директории C:\media. После того, как мы загрузили текстуру, ее нужно "привязать" к объекту с помощью команды ENTITYTEXTURE: ENTITYTEXTURE объект, текстура Также, текстуру можно масштабировать командой: SCALETEXTURE текстура, SX, SY Программа "Лес на траве" (10 мин) Воспользуемся старой программой и добавим строки создания плоскости перед командой CREATEPIVOT): Cоздаем плоскость: ground = CREATEPLANE() Опускаем плоскость вниз на 8 единиц: POSITIONENTITY ground, 0, -8, 0 Загружаем текстуру: grass = LOADTEXTURE("C:\media\grass.jpg") Увеличиваем текстуру в 50 раз: SCALETEXTURE grass, 50, 50 Привязываем текстуру к плоскости: ENTITYTEXTURE ground, grass Зеркала (5 мин) Зеркало - это тоже плоскость, которая отражают объекты. Зеркала задаются командой: a = CREATEMIRROR([род]) Но на зеркало нельзя наложить текстуру, поэтому для создания зеркальной поверхности мы должны применить такой прием: установить прозрачность затекстурированной плоскости и создать на ее месте зеркало. Программа "Зеркальная земля" Добавьте следующие строки после недавно введенных команд: Делаем плоскость земли полупрозрачной: ENTITYALPHA ground, 0.5 Создаем зеркало: mirror = CREATEMIRROR() Перемещаем его туда же, куда переместили плоскость: POSITIONENTITY mirror, 0, -8, 0 Задание: оттекстурировать ели текстурами moss.jpg и wood.jpg (10 мин) Это задание является довольно несложным и вполне может быть выполнено учащимися самостоятельно. Вставить строки перед командой “FOR x = 1 TO 100”: moss = LOADTEXTURE("C:\media\moss.jpg") ENTITYTEXTURE c1, moss ENTITYTEXTURE c2, moss ENTITYTEXTURE c3, moss ENTITYTEXTURE c4, moss wood = LOADTEXTURE("C:\media\wood.jpg") ENTITYTEXTURE cyl, wood Трехмерные модели (2.5 мин) Blitz3D позволяет загружать трехмерные модели, сделанные в 3D-редакторах. Поддерживаются форматы "X", "3DS", "B3D". Модель загружается командой: a = LOADMESH(файл) Затем можно работать с ней, как с обычным трехмерным объектом. Часто модели уже оттекстурированы и имеют ссылки на файлы текстур, применять к таким моделям команду ENTITYTEXTURE не стоит. Наведение камеры на объект (2.5 мин) Навести камеру на объект можно так: POINTENTITY камера, объект В принципе, можно навести любой объект на любой другой. Управление объектом с клавиатуры (17.5 мин) Загрузим модель робота с помощью команды: robot = LOADMESH("C:\MEDIA\running.3ds") Изменим размеры модели: SCALEENTITY robot, 0.4, 0.4, 0.4 Теперь зададим начальные значения переменных - координаты робота: rx#=10; координата X модели робота rz#=0; координата Z модели робота ang=90; угол поворота модели робота Создадим бесконечный цикл, команды для изменения положения робота и условия, изменяющие координаты при нажатии соответствующих клавиш: REPEAT Изменение координат и угла поворота: POSITIONENTITY robot, rx#, -8, rz# ROTATEENTITY robot, 0, ang + 90, 0 Наводим камеру на робота: POINTENTITY cam, robot Если нажата клавиша "вверх", перемещаем робота на вектор с длиной 0.5 под углом ang: IF KEYDOWN(200) THEN rx# = rx# + COS(ang) * 0.5 rz# = rz# + SIN(ang) * 0.5 END IF Изменяем угол поворота модели при нажатии клавиш "влево" и "вправо": IF KEYDOWN(203) THEN ang = ang + 5 IF KEYDOWN (205) THEN ang = ang - 5 Выходим, если нажата клавиша ESC: IF KEYDOWN (1) THEN EXIT RENDERWORLD FLIP FOREVER Анимация (7.5 мин) Этот и следующий разделы довольно сложны для восприятия и главным образом направлены на демонстрацию возможностей языка. Также, можно загрузить анимированную модель: a = LOADANIMMESH(файл) Каждый такой файл содержит одну последовательность фаз движения (скажем, бег или прыжок). Можно наложить на этот же объект еще одну последовательность фаз с помощью команды: a = LOADANIMSEQ(объект, файл) Чтобы анимировать модель, нужно задать параметры анимации с помощью команды: ANIMATE объект [,режим] [,скорость] [,последовательность] [,количество промежуточных фаз] Типы анимации: 1 - зацикленная анимация (по достижении конца последовательности, переходим в начало) 2 - пинг-понг (по достижении конца последовательности, прокручиваем ее назад, затем снова и снова) 3 - прокрутить один раз с начала до конца Чем больше скорость, тем быстрее происходит анимация и наоборот Чем больше количество промежуточных фаз, тем плавней переход от одной фазы к другой. И в заключение, необходимо добавить команду UPDATEWORLD перед RENDERWORLD, чтобы обновить форму анимированных объектов. Добавление анимации в программу (15 мин) Изменим введенный кусок программы: Загружаем анимационную последовательность номер 0 - модель робота, смотрящая по сторонам: robot = LOADANIMMESH("C:\media\standing.3ds") Добавляем анимационную последовательность номер 1 - бегущая модель робота: LOADANIMSEQ robot, "C:\media\running.3ds" SCALEENTITY robot, 0.4, 0.4, 0.4 rx# = 10 rz# = 0 ang = 90 REPEAT POSITIONENTITY robot, rx#, -8, rz# ROTATEENTITY robot, 0, ang + 90, 0 POINTENTITY cam, robot IF KEYDOWN(200) Если нажата клавиша "вверх" и робот стоит на месте, то задаем анимационную последовательность 1 (бег), тип анимации - зацикленная (1), скорость - 0.5, количество промежуточных фаз - 10 IF ANIMSEQ(robot) = 0 THEN ANIMATE robot, 1, 0.5, 1, 10 rx# = rx# + COS(ang) * 0.5 rz# = rz# + SIN(ang) * 0.5 ELSE Если клавиша "вверх" не нажата и робот бежит, то задаем анимационную последовательность 0 (стоять на месте), тип анимации - пинг-понг (2), скорость - 1, количество промежуточных фаз - 10 IF ANIMSEQ(robot)=1 THEN ANIMATE robot, 2, 1, 0, 10 END IF IF KEYDOWN(203) THEN ang = ang + 5 IF KEYDOWN (205) THEN ang = ang - 5 IF KEYDOWN(1) THEN EXIT Обновляем анимированную модель: UPDATEWORLD RENDERWORLD FLIP FOREVER Физическая модель прыжка (15 мин) Это задание выходит за рамки временного интервала урока, поэтому его лучше провести отдельно. Теперь добавим возможность прыжка. Для этого необходимо ввести еще одну переменную - ry#, а также приращение dy#: ry# = -8 dy# = 0 Затем, вводим условие: если нажата клавиша "пробел" и робот стоит на земле (т.е. координата ry# = -8), то задаем импульс -приращение, равное 2 IF KEYDOWN(57) THEN IF ry# = -8 THEN dy# = 2 END IF Прибавляем к переменной ry# приращение: ry# = ry# + dy# Но, т. к. на робота должна действовать гравитация, мы должны периодически уменьшать приращение на 0.1: dy# = dy# - 0.1 Причем, координата робота ry# не должна быть меньше -8 (робот не должен опускаться ниже плоскости), поэтому введем следующее условие: IF ry# < -8 THEN ry# = -8: dy# = 0 Поменяем также фиксированную координату -8 в команде POSITIONENTITY на ry#. Измененный модуль выглядит теперь вот так: robot = LOADANIMMESH( IMSEQ(robot)=1 THEN ANIMATE robot, 2, 1, 0, 10 END IF IF KEYDOWN(203) THEN ang = ang + 5 IF KEYDOWN (205) THEN ang = ang - 5 IF KEYDOWN(1) THEN EXIT UPDATEWORLD RENDERWORLD FLIP FOREVER Урок 7 – спрайты, поверхности "Проволочный каркас" (5 мин) В Blitz3D существует режим отображения, который называется "проволочный каркас". В нем изображаются только контуры элементарных фигур - треугольников. Этот режим включается командой: WIREFRAME 1 Попробуйте посмотреть в этом режиме последнюю созданную программу. Этот режим наглядно демонстрирует структуру объектов. Спрайты (5 мин) Спрайт - это двумерный рисунок в трехмерном пространстве. Классический спрайт всегда повернут в сторону камеры и меняет размеры в зависимости от расстояния до нее. Любой точечный рисунок можно сделать спрайтом: a = LOADSPRITE(файл) Спрайт масштабируется с помощью специальной команды: SCALESPRITE спрайт, SX, SY Программа "Звездное небо" (10 мин) Эта программа похожа на программу создания леса. Изменим программу с роботом (эти строки нужно добавить после строк текстурирования). Загружаем спрайт: star = LOADSPRITE("C:\media\star.jpg") Увеличиваем его размеры в 3 раза: SCALESPRITE star, 3, 3 Создаем цикл, размещающий случайным образом 100 спрайтов над лесом: FOR x = 1 TO 100 star2 = COPYENTITY(star) POSITIONENTITY star2, RND(-120, 120), RND(20, 50), RND(1, 240) NEXT Трехмерная поверхность (10 мин) Трехмерную поверхность можно представить, как листок бумаги в клетку, у которого мы можем задавать высоты точек, лежащих на пересечении линий. Еще, представьте клетчатую сетку, в каждое пересечение брусьев которой впаян штырек. Штыри имеют разные высоты, и если мы накинем на них ткань, то она будет лежать на них некоторой поверхностью. Этот рисунок желательно продемонстрировать учащимся. Создается поверхность с помощью команды: a = CREATETERRAIN(размер [,род]) Параметр «размер» определяет, на сколько клеток делится поверхность по длине и ширине. Он, так же, как и размер текстуры, должен быть степенью двойки. Высоту определенной точки поверхности задает команда: MODIFYTERRAIN поверхность, x, z, высота x и z должны лежать в пределах от 0 до размера поверхности - они определяют точку поверхности. Высота должна лежать в интервале [0, 1]. А вот эта команда включает затенение поверхности: TERRAINSHADING поверхность, 1 Программа, выводящая на экран поверхность воды с рябью (25 мин) Сделаем заголовок программы: GRAPHICS3D 640, 480 cam = CREATECAMERA() POSITIONENTITY cam, 64, 64, -16 ROTATEENTITY cam, 45, 0, 0 l = CREATELIGHT() ROTATEENTITY l, 0, 45, 45 Создадим поверхность: t = CREATETERRAIN(64) Включим затенение поверхности: TERRAINSHADING t, 1 Загрузим текстуру воды и увеличим ее размер в 16 раз, затем привяжем текстуру к поверхности. water = LOADTEXTURE("C:\media\water.jpg") SCALETEXTURE water, 16, 16 ENTITYTEXTURE t, water Увеличим размеры поверхности (особенно высоту): SCALEENTITY t, 2, 20, 2 Создадим бесконечный цикл: REPEAT Здесь, в этих циклах будут задаваться высоты для каждой из точек поверхности: FOR x = 0 TO 64 FOR z = 0 TO 64 Вкратце можно описать формулу, по которой задаются точки так: синус расстояния от средней точки поверхности до данной плюс приращение умножается на расстояние. r# = SQR((x - 32) * (x-32) + (z - 32) * (z - 32)) / 16 MODIFYTERRAIN t, x, z, SIN(r# * 360 + k) / 2 / (r# + 1) + .5 NEXT NEXT Добавим команды для визуализации, приращение переменной, условие выхода и закроем цикл: RENDERWORLD FLIP k = k - 5 IF KEYDOWN(1) THEN EXIT FOREVER Создание холмистой поверхности (25 мин) Эта программа показывает последовательное сглаживание поверхности, заданной случайным образом. Создадим заголовок, где будет создана камера, свет и текстурированная поверхность: GRAPHICS3D 640, 480 cam = CREATECAMERA() POSITIONENTITY cam, 64, 64, -16 ROTATEENTITY cam, 45, 0, 0 l = CREATELIGHT() ROTATEENTITY l, 0, 45, 45 t = CREATETERRAIN(64) TERRAINSHADING t, 1 grass = LOADTEXTURE( "C:\media\grass.jpg" ) SCALETEXTURE grass, 32, 32 ENTITYTEXTURE t, grass SCALEENTITY t, 2, 60, 2 Делаем цикл из 10 шагов: FOR n = 1 TO 10 Циклы по всем точкам поверхности: FOR x = 0 TO 64 FOR z = 0 TO 64 На первом этапе- задаем высоты точек случайным образом: IF n=1 THEN MODIFYTERRAIN t, x, z, RND(0, 1) Else На следующих этапах устанавливаем для каждой точки значение высоты, равное среднему арифметическому между значениями высоты ее и соседних: MODIFYTERRAIN t, x, z, (TERRAINHEIGHT(t, x - 1, z) + TERRAINHEIGHT(t, x, z - 1) + TERRAINHEIGHT(t, x, z) + TERRAINHEIGHT(t, x + 1, z) + TERRAINHEIGHT(t, x, z + 1)) / 5 END IF NEXT NEXT Визуализируем сцену, ждем нажатия клавиши и закрываем цикл: RENDERWORLD FLIP WAITKEY NEXT Урок 8 – Чтение данных, построение моделей Операторы READ и DATA (7.5 мин) Часто бывает так, что нужно переработать в цикле много однородных данных. Для этого существуют операторы READ и DATA. Оператор READ читает значения задаваемых переменных из списка DATA. Синтаксис: READ переменная1, переменная2, ... DATA значение1, значение2, ... Наберем небольшую программу: FOR n = 1 TO 5 READ a PRINT a NEXT DATA 1, 10, 19, 125, 563 Команда “READ читает одно значение из списка DATA и заносит его в переменную затем команда “PRINT выводит переменную a на экран. В цикле этот процесс происходит 5 раз. Еще можно читать строки, а также писать в операторе несколько переменных через запятую. В операторе READ важно помнить, какой тип данных вы считываете. Программа, выводящая фигуру из сфер, считывая их координаты (10 мин) Инициализируем трехмерную сцену: GRAPHICS3D 640,480 cam = CREATECAMERA() l = CREATELIGHT() Задаем цикл из 8 повторений: FOR n = 1 TO 8 Создаем сферу: a = CREATESPHERE() Читаем два значения и заносим их в две переменные дробного типа: READ x#, y# Помещаем созданную сферу в точку, заданную считанными переменными: POSITIONENTITY a, x#, y#, 5 Закрываем цикл и выводим сцену на экран: NEXT RENDERWORLD FLIP WAITKEY Это данные для оператора READ - восемь раз по два значения DATA -1.5, 2, -1, 3, 0, 3.5, 1, 3, 1.5, 2, 1, 1, 0, 0, 0, -2 Построение трехмерных фигур по треугольникам (17.5 мин) До сих пор мы строили трехмерные сцены из объемных фигур. Но, во многих случаях требуется построить трехмерный объект, который формой отличается от них (взять хотя бы усеченный конус). Для этого в Blitz3D существуют команды построения объектов по элементарным частям - треугольникам. Сначала нужно создать пустую фигуру: a = CREATEMESH([род]) Эта фигура состоит из поверхностей, каждая из которых имеет свои параметры (текстуру, цвет и т. д.). Поэтому, далее мы создаем поверхность для заданной фигуры: a = CREATESURFACE(фигура) Теперь можно добавлять к ней треугольники. Для этого, вначале, нужно найти координаты вершин и внести их в поверхность. Первая введенная вершина имеет индекс 0, следующая - 1 и т. д. Это делается с помощью команды: ADDVERTEX поверхность, x, y, z, u, v x, y, z – координаты вершины в пространстве, u, v – координаты на текстуре. Текстурные координаты нужны, чтобы правильно наложить текстуру на объект – они задают соответствие между вершинами в пространстве и точками двумерного рисунка текстуры. Текстура зациклена, то есть бесконечно простирается во все стороны, повторяясь, как плитки паркета. Координаты u = 0 и v = 0 задают угол такой плитки, а u = 0.5 и v = 0.5 – середину. Таким образом, длина “плитки” текстуры по вертикали и горизонтали равна 1ед независимо от ее разрешения. Следующий шаг – задание самих треугольников. Они задаются командой: ADDTRIANGLE поверхность, вершина1, вершина2, вершина3 Вершины задаются индексами. Необходимо отметить, что на самом деле такой треугольник имеет только одну сторону. Представим, что он спроецирован на экран. Треугольник изображается тогда, когда его вершины расположены в порядке по часовой стрелке – это значит, он повернут видимой стороной к камере. Если же вершины треугольника расположены против часовой стрелки, значит, он невидим в данный момент и изображать его не нужно. Для обеспечения корректного освещения предназначена следующая команда: UPDATENORMALS фигура Создание модели меча (45 мин) Сначала полезно построить чертеж и найти координаты вершин. Создаем заголовок: GRAPHICS3D 640,480 cam = CREATECAMERA() POSITIONENTITY cam, 0, 0, -30 l = CREATELIGHT() ROTATEENTITY l, 0, 45, 45 Загрузим текстуры: wood = LOADTEXTURE("c:\media\wood.jpg") steel = LOADTEXTURE("c:\media\steel.jpg",1 + 8 + 64) Дополнительный параметр во второй строке означает то, что текстура является сферической картой отражений. Это особый тип текстуры, который создает иллюзию зеркальности объекта. Создаем две пустые фигуры и накладываем на них текстуры steel (сталь) и wood (дерево): m1 = CREATEMESH() ENTITYTEXTURE m1, steel m2 = CREATEMESH(m1) ENTITYTEXTURE m2, wood Так как порядок действий для оформления фигур один и тот же, а в программе необходимо создать две фигуры, то удобнее будет сделать это в цикле. Оператор IF-THEN задает первую фигуру для оформления в первом шаге цикла, а вторую – во втором. FOR n=1 TO 2 IF n = 1 THEN m = m1 ELSE m = m2 END IF Создаем поверхность, привязанную к фигуре: s = CREATESURFACE(m) Считываем количество вершин: READ vq Цикл по всем вершинам: FOR nn = 1 TO vq Считываем координаты вершины: READ x#, y#, z# Добавляем вершину к поверхности (координаты текстуры возьмем случайные) и закрываем цикл: ADDVERTEX s, x#, y#, z#, RND(1), RND(1) NEXT Считываем кол-во треугольников READ tq Цикл по всем треугольникам: FOR nn = 1 TO tq Считываем индексы вершин: READ v1, v2, v3 Добавляем треугольник, закрываем цикл: ADDTRIANGLE s, v1, v2, v3 NEXT Обеспечение корректного освещения: UPDATENORMALS m NEXT Теперь вернемся к основной программе. Создадим две фигуры с адресами m1 и m2 и текстурами steel и wood. Обратите внимание на то, что родительский объект фигуры m1 равен 0, то есть не существует. m1 = READMESH(0, steel) m2 = READMESH (m1, wood) Создадим ручку меча – цилиндр: cyl = CREATECYLINDER(20, 1, m1) POSITIONENTITY cyl, 0, -3, 0 SCALEENTITY cyl, 1, 2, 1 ENTITYTEXTURE cyl, wood Перекладина гарды меча: cube = CREATECUBE(m1) POSITIONENTITY cube, 0, -0.5, 0 SCALEENTITY cube, 3, 0.5, 1 ENTITYTEXTURE cube, wood Далее идет цикл с командами управления вращением меча с клавиатуры: REPEAT IF KEYDOWN(200) THEN xa = xa + 1 IF KEYDOWN(208) THEN xa = xa - 1 IF KEYDOWN(203) THEN ya = ya + 1 IF KEYDOWN(205) THEN ya = ya - 1 ROTATEENTITY m1, xa, ya, 0 IF KEYDOWN(1) THEN EXIT RENDERWORLD FLIP FOREVER Данные рекомендуется найти по чертежу, привлекая к поиску учеников. Данные (9 вершин лезвия): DATA 9 DATA -2, 0, 0 DATA 0, 0, -0.5 DATA 2, 0, 0 DATA 0, 0, 0.5 DATA -2, 20, 0 DATA 0, 19, -0.5 DATA 2, 20, 0 DATA 0, 19, 0.5 DATA 0, 22, 0 12 треугольников лезвия: DATA 12 DATA 0, 4, 1 DATA 4, 5, 1 DATA 4, 8, 5 DATA 8, 6, 5 DATA 5, 6, 2 DATA 5, 2, 1 DATA 0, 3, 4 DATA 3, 7, 4 DATA 3, 2, 7 DATA 2, 6, 7 DATA 7, 8, 4 DATA 7, 6, 8 10 вершин концов гарды: DATA 10 DATA -5, -2, 0 DATA -3, 0, -1 DATA 3, 0, -1 DATA 5, -2, 0 DATA 3, -1, -1 DATA -3, -1, -1 DATA -3, 0, 1 DATA 3, 0, 1 DATA 3, -1, 1 DATA -3, -1, 1 8 треугольников концов гарды: DATA 8 DATA 0, 1, 5 DATA 0, 9, 6 DATA 0, 6, 1 DATA 0, 5, 9 DATA 4, 3, 8 DATA 2, 3, 4 DATA 7, 3, 2 DATA 8, 3, 7 Урок 9 – массивы, взаимодействие объектов Массивы (10 мин) Далее массивы понадобятся для хранения адресов, координат, приращений. Одномерный массив можно представить, как полоску клетчатой бумаги, в каждой клетке которой записано какое-л значение. Пример: задаются командой: DIM имя_массива (количество_элементов) Примеры: DIM A(7), DIM Name$(5), DIM K#(256) Числовой массив изначально заполнен нулями, строковой – пустыми строками. Массивы также бывают двумерными, трехмерными и т. д.: Для доступа к элементу массива необходимо указать имя и в скобках номер, например A(2), A(5), Name$(4). Для двумерного массива нужно указать два номера, для трехмерного – три и т. д. Пример: DIM K(3, 3) K(1, 2) = 5 K(3, 1) = 4 PRINT K(1, 1) PRINT K(1, 2) Программа, заполняющая массив – таблицу умножения (5 мин) DIM A(10, 10) FOR X = 1 TO 10 FOR Y = 1 TO 10 A(X, Y) = X * Y NEXT NEXT Задание: вывести элементы массива, соответствующие умножению 5 на 7 и 3 на 9 (5 мин) PRINT * 7 = + A(5, 7) PRINT * 9 = + A(3, 9) Обработка массива объектов (20 мин) В предыдущих программах уже создавались множества однотипных объектов, но дальше в программе с ними не происходило никаких изменений. Адрес этих объектов терялся, так как мы, создавая новый объект в цикле, присваивали его адрес одной и той же переменной. Для сохранения этих адресов в памяти воспользуемся массивами. Напишем программу, которая перемещает в пространстве 100 звезд по разным траекториям. Сначала – заголовок. Здесь создается камера и загружается спрайт: GRAPHICS3D 640,480 cam = CREATECAMERA() POSITIONENTITY cam, 0, 0, -20 star = LOADSPRITE("C:\MEDIA\STAR.JPG") Теперь необходимо разобраться с физической моделью программы. Изначально, 100 звезд размещаются в пространстве случайным образом. Каждая звезда имеет приращения по каждой из координатных осей, которые сначала равняются нулю, но изменяются, в зависимости от положения звезды относительно начала координат. То есть, если какая-либо координата положительна, то приращение уменьшается, если отрицательна – увеличивается. Это приводит к тому, что звезда будет кружиться вокруг начала координат по изогнутой траектории, которую называют кривой Лиссажу. Создадим три массива. Первый будет содержать адреса спрайтов, второй – их координаты, третий – приращения. Так как координат всего три, а звезд – 100, то второй и третий массивы будут иметь размерность 100 x 3. Звезда n будет иметь адрес addr(n), располагаться в точке с координатами x = c#(n, 1), y = c#(n, 2), z = c#(n, 3) и иметь приращения dx = dc#(n, 1), dy = dc#(n, 2), dz = dc#(n, 3) DIM addr(100) DIM c#(100, 3) DIM dc#(100, 3) В следующем цикле создается 100 звезд FOR n = 1 TO 100 addr(n) = COPYENTITY(star) FOR nn = 1 TO 3 Каждая из трех координат приравнивается к случайному значению от –8 до 8. C#(n, nn) = RND(-8, 8) NEXT NEXT Далее следует бесконечный цикл, в котором для каждой из 100 звезд изменяются координаты и приращения, а также происходит визуализация трехмерной сцены: REPEAT В двух вложенных циклах к каждой координате каждой звезды прибавляется ее приращение. Затем в зависимости от знака координаты, приращение изменяется (если с#(n, nn) < 0, то SGN(с#(n, nn)) = -1 и приращение увеличивается на 0.005 и наоборот). Затем спрайт звезды помещается в точку, заданную координатами. FOR n = 1 TO 100 FOR nn = 1 TO 3 c#(n, nn) = c#(n, nn) + dc#(n, nn) dc#(n, nn) = dc#(n, nn) - 0.005 * SGN(c#(n, nn)) NEXT POSITIONENTITY addr(n), c#(n,1), c#(n,2), c#(n,3) NEXT IF KEYDOWN(1) THEN EXIT RENDERWORLD FLIP FOREVER Взаимодействие объектов (15 мин) В большинстве случаев, когда программа оперирует массивом объектов, встает вопрос об их взаимодействии. Наиболее часто встречаемый вариант – столкновение объектов. Когда два или более материальных объекта пытаются занять одно и то же пространство, нужен способ изменить их траекторию (другие варианты – уничтожить один из них, остановить оба объекта и т. д.). Этот случай называется столкновением или коллизией. Blitz3D может автоматически реагировать на столкновения, используя один из нескольких стандартных методов. Чтобы активизировать механизм реагирования на столкновения нужно вначале задать тип сталкиваемых объектов с помощью команды: ENTITYTYPE объект, тип Это нужно для того, чтобы затем определить, какие объекты с какими и как должны сталкиваться. Тип – это число. Задавая один и тот же тип для разных объектов, вы определяете их, как группу участников столкновений. Теперь нужно задать механизм столкновения командой: COLLISIONS тип движущегося объекта, тип неподвижного объекта, метод определения столкновения, реакция Данная команда определяет столкновение, если объект первого типа движется и пытается занять пространство второго, неподвижного. Если двигаются оба объекта, то сначала первый из них надвигается на второй, затем второй на первый. Методы столкновения: 1 - сфера со сферой, 2 – сфера с многогранником, 3 – сфера с параллелепипедом. То есть, движущийся объект всегда виртуально представлен сферой, то есть вне зависимости от его формы он будет реагировать на столкновения, как сфера. Можно задавать радиус этой сферы: ENTITYRADIUS объект, радиус сферы Реакция на столкновение может быть двух типов: 1 – остановка объекта, 2 – скольжение объекта вдоль неподвижного. И в заключение, необходимо дать команду UPDATEWORLD, чтобы проверить столкновения и соответственно отреагировать. Для следующей программы понадобятся функции определения текущих координат объекта ENTITYX(объект) – координата X ENTITYY(объект) – координата Y ENTITYZ(объект) – координата Z Программа, создающая нагромождение шаров (20 мин) Создадим заголовок: GRAPHICS3D 640,480 cam = CREATECAMERA() l = CREATELIGHT() ROTATEENTITY l, 45, 45, 0 Создадим и оттектурируем плоскость: grass = LOADTEXTURE("C:\MEDIA\GRASS.JPG") SCALETEXTURE grass, 16, 16 p = CREATEPLANE() POSITIONENTITY p, 0, -5, 0 ENTITYTEXTURE p, grass Зададим тип плоскости, равным 1, тип шаров будет равным 2: ENTITYTYPE p, 1 Шары (2) могут сталкиваться с плоскостью (1), которая определяется, как многогранник(2), при этом они будут останавливаться (1): COLLISIONS 2, 1, 2, 2 Шары (2) могут сталкиваться с другими шарами (2), которые определяются, как сферы(1), при этом они будут скользить(2): COLLISIONS 2, 2, 1, 2 Когда переменная s равна 0, это означает, что нужно создать новый шар: s = 0 Бесконечный цикл: REPEAT IF s = 0 THEN Создаем шар, если s = 0, задаем его тип (2) и радиус сферы столкновения (1): s = CREATESPHERE() ENTITYTYPE s, 2 ENTITYRADIUS s, 1 Задаем случайное местоположение шара на высоте 12: POSITIONENTITY s, RND(-5,5), 12, RND(10,20) END IF Заносим текущие координаты шара в три переменные: sx# = ENTITYX(s) sy# = ENTITYY(s) sz# = ENTITYZ(s) Шар перемещается вниз под воздействием гравитации: MOVEENTITY s, 0, -0.3, 0 Проверяем столкновения: UPDATEWORLD Если координаты шара не изменились, то он прочно застрял и нужно бросать новый шар: IF sx# = ENTITYX(s) AND sy#=ENTITYY(s) AND SZ# = ENTITYZ(s) THEN s = 0 Завершаем цикл, визуализируем сцену: IF KEYDOWN(1) THEN EXIT RENDERWORLD FLIP FOREVER Заключение Основная цель данного спецкурса - заинтересовать людей этим перспективным направлением в программировании и показать его возможности. Базовые навыки, данные здесь, конечно, не могут полностью охватить все аспекты (особенно математические) создания комплексной программы трехмерного моделирования, для научного эксперимента и других целей. Но, проведенные занятия дадут импульс заинтересованным людям для дальнейшего изучения языка Blitz3D (возможно, трехмерных технологий других, более близких им языков), что позволит им в будущем стать специалистами в этой области, использовать знания в применении к другим научным дисциплинам. Спецкурс был проведен в Естественно-Математическом Лицее №1 г. Южно-Сахалинска. Ученики успешно освоили программу данного курса. В ходе занятий у учеников возникало множество вопросов, на которые были даны исчерпывающие ответы. Все программы были набраны, отлажены и запущены. Материалы этого спецкурса можно рекомендовать к использованию при факультативном изучении данного раздела информатики, при необходимости корректируя структуру уроков. Памятка(1) Сочетания клавиш: Shift-Ctrl - переключение шрифта с английского на русский и обратно Shift+курсорные стрелки - выделить фрагмент текста Ctrl-Ins - копировать выделенный фрагмент в буфер Shift-Ins - копировать выделенный фрагмент из буфера на место курсора Переменные: A - целая A# - дробная A$ - строковая Команды: WAITKEY - ждать нажатия клавиши Режим экрана: GRAPHICS3D ширина, длина, [глубина цвета] [,режим] - установка режима экрана. WIREFRAME 1 - "проволочный каркас" Создание объектов: a = CREATECUBE([род]) - создать куб a = CREATESPHERE([детализация] [,род]) - создать сферу a = CREATECYLINDER([детализация] [,наличие оснований] [,род]) - создать цилиндр a = CREATECONE([детализация] [,наличие основания] [,род]) - создать конус a = CREATECAMERA([род]) - создать камеру a = CREATELIGHT([тип] [,род]) - создать источник освещения a = CREATEPIVOT([род]) - создать пустой объект a = CREATEPLANE([род]) - создать плоскость Визуализация: RENDERWORLD - отобразить мир на экранный буфер FLIP - копировать содержимое экранного буфера на экран Управление объектами: POSITIONENTITY объект, X, Y, Z - задать координаты объекта ROTATEENTITY объект, RX, RY, RZ - задать угол поворота объекта SCALEENTITY объект, SX, SY, SZ - задать масштаб объекта COLORENTITY объект, красный, зеленый, синий - задать цвет объекта ENTITYALPHA объект, коэффициент прозрачности - задать прозрачность объекта a = COPYENTITY (объект) - скопировать объект POINTENTITY камера, объект - навести камеру на объект Текст: PRINT - вывести значение выражения на экран A$=INPUT$([приглашение]) - задать переменную, введя строку с клавиатуры Цикл: FOR переменная = начало TO конец STEP шаг …операторы… NEXT Бесконечный цикл: REPEAT …операторы… FOREVER Условие: IF условие THEN ….эти операторы выполняются, когда условие ИСТИННО …. ELSE ….эти операторы выполняются, когда условие ЛОЖНО …. END IF Проверка нажатия клавиши: IF KEYGET(скан-код) THEN ….эти операторы выполняются, если клавиша нажата …. ELSE ….эти операторы выполняются, если клавиша не нажата …. END IF Скан - коды: Стрелка влево - 203 Стрелка вправо - 205 Стрелка вверх - 200 Стрелка вниз - 208 A - 30 Z - 44 Пробел - 57 ESC - 1 Функции: SQR (a) - квадратный корень из числа ABS (a) - модуль числа SIN (a) - синус угла COS (a) - косинус угла TAN (a) - тангенс угла ASIN (a) - арксинус ACOS (a) - арккосинус ATAN (a) - арктангенс ATAN2 (y,x) - угол между осью OX и радиус-вектором AB (A(0,0), B(x,y)) SGN (a) – знак числа (-1, 0, 1) INT (a) - округление числа до ближайшего целого FLOOR (a) - округление числа в меньшую сторону CEIL (a) - округление числа в большую сторону RAND (a, b) - случайное целое число в диапазоне от a до b RND (a, b) - случайное дробное число в диапазоне от a до b MILLISECS () - текущее системное время в миллисекундах Памятка(2) Текстуры: a = LOADTEXTURE(файл) - загрузить текстуру ENTITYTEXTURE объект, текстура - оттекстурировать объект SCALETEXTURE текстура, SX, SY - масштабировать текстуру Трехмерные модели: a = LOADANIMMESH(файл) - загрузить модель LOADANIMSEQ модель, файл - загрузить анимационную последовательность ANIMATE объект [,режим] [,скорость] [,последовательность] [,количество промежуточных фаз] - анимировать модель UPDATEWORLD - обновить форму модели Спрайты: a = LOADSPRITE(файл) - загрузить спрайт SCALESPRITE спрайт, SX, SY - масштабировать спрайт Поверхности: a = CREATETERRAIN(размер [,род]) - создать поверхность MODIFYTERRAIN поверхность, x, z, высота - изменить высоту точки поверхности TERRAINSHADING поверхность, 1 - включить затенение поверхности Данные: READ переменная1, переменная2, ... – считать переменные DATA значение1, значение2, ... – блок данных для считывания Построение объектов по треугольникам: a = CREATEMESH([род]) – создать фигуру a = CREATESURFACE(фигура) – создать поверхность ADDVERTEX поверхность, X, Y, Z, U, V – добавить вершину ADDTRIANGLE поверхность, вершина1, вершина2, вершина3 – добавить треугольник UPDATENORMALS фигура – обеспечение корректного освещения фигуры Задание массива: DIM имя_массива(количество элементов, количество элементов, ...) Столкновения: ENTITYTYPE объект, тип – задание типа объета COLLISIONS тип движущегося объекта, тип неподвижного объекта, метод определения столкновения, реакция – активизация механизма реакции на столкновения ENTITYRADIUS объект, радиус сферы – радиус сферы столкновения Параметры объекта: ENTITYX(объект) – координата X ENTITYY(объект) – координата Y ENTITYZ(объект) – координата Z Литература 1. M. Sibly, "Blitz3D documentation", BlitzResearch, 2003 2. "Персональный компьютер ZX-Spectrum. Динамическая графика", Москва, Инфорком, 1995 3. Г. Зельднер "Программируем на языке QuickBasic 4.5", ABF, 1996 4. С.В. Глушаков, Г.А. Кнабе "Компьютерная графика – учебный курс", Москва, АСТ, 2001 5. DirectX SDK, Microsoft 6. Scaven. "Основы Blitz3D", 2003, http:\\www.unblitz.narod.ru 7. iXBT. "Генерация трехмерных ландшафтов", 2003, http:\\www.ixbt.com
|