7 ноября 2012 в 12:45
Blitz3d - массивы, взаимодействие объектов
Массивы
Далее массивы понадобятся для хранения адресов, координат, приращений.
Одномерный массив можно представить, как полоску клетчатой бумаги, в каждой клетке которой записано какое-л значение. Пример:
1 | 5 | 7 | 19 | 29 | 111 | 3 |
Массивы задаются командой:
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)
Программа, заполняющая массив – таблицу умножения
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
PRINT “5 * 7 = “ + A(5, 7) PRINT “3 * 9 = “ + A(3, 9)
Обработка массива объектов
В предыдущих программах уже создавались множества однотипных объектов, но дальше в программе с ними не происходило никаких изменений. Адрес этих объектов терялся, так как мы, создавая новый объект в цикле, присваивали его адрес одной и той же переменной. Для сохранения этих адресов в памяти воспользуемся массивами.
Напишем программу, которая перемещает в пространстве 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
Взаимодействие объектов
В большинстве случаев, когда программа оперирует массивом объектов, встает вопрос об их взаимодействии. Наиболее часто встречаемый вариант – столкновение объектов. Когда два или более материальных объекта пытаются занять одно и то же пространство, нужен способ изменить их траекторию (другие варианты – уничтожить один из них, остановить оба объекта и т. д.). Этот случай называется столкновением или коллизией. Blitz3D может автоматически реагировать на столкновения, используя один из нескольких стандартных методов.
Чтобы активизировать механизм реагирования на столкновения нужно вначале задать тип сталкиваемых объектов с помощью команды:
ENTITYTYPE объект, тип
Это нужно для того, чтобы затем определить, какие объекты с какими и как должны сталкиваться. Тип – это число. Задавая один и тот же тип для разных объектов, вы определяете их, как группу участников столкновений. Теперь нужно задать механизм столкновения командой:
COLLISIONS тип движущегося объекта, тип неподвижного объекта, метод определения столкновения, реакция
Данная команда определяет столкновение, если объект первого типа движется и пытается занять пространство второго, неподвижного. Если двигаются оба объекта, то сначала первый из них надвигается на второй, затем второй на первый.
Методы столкновения: 1 - сфера со сферой, 2 – сфера с многогранником, 3 – сфера с параллелепипедом. То есть, движущийся объект всегда виртуально представлен сферой, то есть вне зависимости от его формы он будет реагировать на столкновения, как сфера. Можно задавать радиус этой сферы:
ENTITYRADIUS объект, радиус сферы
Реакция на столкновение может быть двух типов: 1 – остановка объекта, 2 – скольжение объекта вдоль неподвижного.
И в заключение, необходимо дать команду UPDATEWORLD, чтобы проверить столкновения и соответственно отреагировать.
Для следующей программы понадобятся функции определения текущих координат объекта
ENTITYX(объект) – координата X
ENTITYY(объект) – координата Y
ENTITYZ(объект) – координата Z
Программа, создающая нагромождение шаров
Создадим заголовок: 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 (возможно, трехмерных технологий других, более близких им языков), что позволит им в будущем стать специалистами в этой области, использовать знания в применении к другим научным дисциплинам.
комментарии отсутствуют
авторизуйтесь