Blitz3D – Функции и группирование объектов

В Blitz3D есть множество различных функций. Это выражения, которые выдают какое-либо значение и могут требовать один или несколько параметров. Функции записываются так: сначала имя функции, затем в скобках перечисляются параметры через запятую. Функции можно использовать в выражениях наравне с переменными.
Список функций:
SQR (a) - квадратный корень числа
ABS (a) - модуль числа
SIN (a) - синус угла
COS (a) - косинус угла
TAN (a) - тангенс угла
ASIN (a) - арксинус
ACOS (a) - арккосинус
ATAN (a) - арктангенс
ATAN2 (x,y) - угол между осью OX и радиус-вектором AB (A(0,0), B(x,y))
INT(a) - округление числа до ближайшего целого
FLOOR (a) - округление числа в меньшую сторону
CEIL (a) - округление числа в большую сторону
RAND (a, b) - случайное целое число в диапазоне от a до b
RND (a, b) - случайное дробное число в диапазоне от a до b
MILLISECS () - текущее системное время в миллисекундах

Примеры использования функций:

B = INT (A#), X = X + RAND(-1, 1) (*)
X = R * Cos (Ang#), R = SQR (X * X + Y * Y) (*)

Игра "Угадай число"

Эта программа использует большинство структур, изученных ранее и будет хорошим закрепляющим материалом.
Эта строка для того, чтобы каждый раз не загадывалось одно и то же число:

SEEDRND MILLISECS()

Компьютер загадывает число:

N = RAND (1, 100)

Бесконечный цикл, чтобы игрок мог пытаться угадывать число несколько раз:

REPEAT
 Играющий вводит число:
 I = INPUT$(“Угадай число:”)
 IF I = N THEN

Играющий угадал число, поздравляем его  с победой  и выходим:
  PRINT “Поздравляю! Вы выиграли!”
  EXIT
 END IF
 IF I > N THEN

Число больше задуманного:
  PRINT “Это число слишком велико”
 ELSE

Число меньше задуманного:
  PRINT “Это число слишком мало” 
 END IF
FOREVER
WAITKEY

Задание: изменить программу так, чтобы у играющего было только 8 попыток, количество попыток выводилось на экран и при их исчерпании выводилось сообщение о проигрыше
Задание может вызвать трудности у некоторых учащихся, поэтому стоит помочь им наводящими вопросами. Ученики, имеющие опыт в программировании, скорее всего, смогут справиться с заданием самостоятельно.
Введем следующие строки программы после REPEAT:
Увеличиваем счетчик попыток:

Tries = Tries + 1
If Tries > 8 THEN

Если попыток больше восьми,  то выходим  с сообщением  о проигрыше:
 PRINT “Вы исчерпали количество попыток. Вы проиграли.”
 PRINT “А число было “ + N
 EXIT
END IF

Выводим количество попыток  на экран:
PRINT “Попытка номер “ + Tries

Группирование объектов

Настало время поговорить о дополнительном параметре "род". Этот параметр задает "родительский" объект для данного. Когда "родительский" объект трансформируется (поворачивается, перемещается, масштабируется), с ним также трансформируются и все его "дети". Для группировки объектов, удобно сначала создать "пустой" объект с помощью следующей команды:

piv = CREATEPIVOT()

Этот объект не отображается на экране, но имеет все параметры трехмерного объекта (координаты, углы поворота, масштаб). Затем, "привяжем" все части объекта к пустому, указав при их создании параметр "род" = piv.
Этот прием, в сущности, позволяет оперировать объектами, которые являются частями более масштабного объекта, как одним целым, используя один адрес. Манипулирование всеми этими объектами по отдельности было бы крайне затруднительно и объем программы заметно увеличился бы.
Есть еще одна полезная команда, копирующая объект:

новый_объект = COPYENTITY(копируемый_объект)

А эта команда позволяет создать массу объектов, идентичных созданному. Причем, при изменении исходного объекта, меняются и все его копии.

Программа, выводящая на экран лес из уже созданных елок

Эта программа наглядно демонстрирует копирование и группирование объектов
Загрузим файл с елкой "fir.bb" и создадим пустой объект (после камеры и света):

fir = CREATEPIVOT()

Добавим  в каждый оператор создания объекта созданный "родительский" объект, заменим, например
c1 = CREATECONE(20, 1)

на
c1 = CREATECONE(20, 1, fir)

Затем, создадим цикл (перед командой RENDERWORLD):
FOR x = 1 TO 50
 fir2 = COPYENTITY(fir)
 POSITIONENTITY fir2, RND(-120, 120), 0, RND(-120, 120)
NEXT

Для большего эффекта, поменяем строки задания камеры:
cam = CREATECAMERA()
POSITIONENTITY cam, 0, 30, -20
ROTATEENTITY cam, 30, 0, 0

Итак, программа:

GRAPHICS3D 640,480

cam = CREATECAMERA()
POSITIONENTITY cam, 0, 30, -20
ROTATEENTITY cam, 30, 0, 0
l = CREATELIGHT()
ROTATEENTITY l, 0, 45, 45

fir = CREATEPIVOT()
c1 = CREATECONE(20, 1, fir)
SCALEENTITY c1, 5, 5, 5
ENTITYCOLOR c1, 0, 255, 0
c2 = CREATECONE(20, 1, fir)
SCALEENTITY c2, 4, 4, 4
POSITIONENTITY c2, 0, 4, 0
ENTITYCOLOR c2, 0, 255, 0
c3 = CREATECONE(20, 1, fir)
SCALEENTITY c3, 3, 3, 3
POSITIONENTITY c3, 0, 7, 0
ENTITYCOLOR c3, 0, 255, 0
c4 = CREATECONE(20, 1, fir)
SCALEENTITY c4, 2, 2, 2
POSITIONENTITY c4, 0, 10, 0
ENTITYCOLOR c4, 0, 255, 0
cyl = CREATECYLINDER(20, 1, fir)
POSITIONENTITY cyl, 0, -6, 0
SCALEENTITY cyl, 2, 2, 2
ENTITYCOLOR cyl, 170, 130, 30

FOR x = 1 TO 100
 fir2 = COPYENTITY(fir)
 POSITIONENTITY fir2, Rnd(-120, 120), 0, Rnd(1, 240)
NEXT

RENDERWORLD
FLIP
WAITKEY

Можно еще поэкспериментировать с программой - добавить модуль управления камерой из программы fir2.