Главная › Форумы › Blender Game Engine (BGE) › Курс по BGE от drdotmom › Ответ в теме: Курс по BGE от drdotmom
Глава 4.
Подробнее про синтаксис и сам процесс написания скриптов на bge python.
Как я понял — синтаксис был затронут слишком поверхностно. Попробую рассказать о нём подробно.
Подготовка пространства Blender 3D для работы с BGE
Во-первых — стоит заменить таймлайн на редактор логики. Таймлайн в процессе создания игрушки вам врядли пригодится. Вообще я настоятельно рекомендую создавать все объекты в другой сессии блендера. Это позволит вам сосредоточиться строго на объекте и не путаться в сцене.
Далее — окно 3D вида стоит разделить и в одном из получившихся открыть Text Editor для редактирования скриптов.
При желании можно так же потянуть за уголок, но с зажатым шифтом для того, что бы вместо разделения текущего окна создалось отдельное, которое можно в случае чего свернуть.
Тип рендера следует переключить на Blender Game, в n-панели 3D вида во вкладке Shading установить режим материала на GLSL.
В редакторе текста нажать Ctrl+T (появится T-панель) и во вкладке Proporties включить Line Numbers (нумерация строк), Word Wrap (перевод строк) и Syntax Highlight (подсветка синтаксиса)
Заповеди bge python.
1. Всё, что вы имеете в скрипте — можно присвоить переменной.
Это и значения, и имена объектов, и функции. При присвоении используется оператор ‘=’. При этом значение правой части присваивается переменной в левой части
x = y \\ x принимает значение y
color = [1.0, 1.0, 1.0] \\ color принимает набор значений
object = scene.objects [‘Empty’] \\ object принимает значение объекта Empty становясь «ссылкой» на него.
debug = bge.render.showProperties \\ debug принимает значение функции, показывающей переменные. Теперь для её активации достаточно написать debug = True для активации или debug = False для деактивации.
2. Всегда соблюдай табуляцию.
В текстовом редакторе Blender табуляция (Tab) по-умолчанию ровняется четырём пробелам, однако смысловая разница есть.
Табуляция используется под каждым логическим оператором.
##########################################
if x == t:
y = 4
elif x != t and y<1:
y = 2
else:
y = 6
##########################################
if x == t:
if x == 3:
y = 1
if x == 4:
y = 3
else:
y = 0
else:
y = 2
#########################################
Табуляция — способ разделения условия от операции, производимой при соблюдении этого самого условия.
Кстати говоря — вы можете записать операции и в одну строку, разделив их знаком ;
if x == t: y = 4; g = 2; e = 0
Но это уже вопрос читабельности — вариант с записью в одну строку читать намного труднее. Я мог бы и промолчать про эту возможность для того, что бы вы так не делали, но это было бы не проффесионально. Так что знайте, но не используйте, пожалуйста =)
3. Помни про регистр.
«String» не равен «string»!
4. Держи скрипт в чистоте и порядке.
Это не обязательно и на работу скрипта не влияет, но очень даже желательно. Даже если никому не собираешься показывать код — тебе самому, возможно, придётся в нём ползать, искать ошибки и добавлять \ менять функции.
Два скрипта ниже абсолютно одинаковые по функциям, но со вторым работать приятнее
5. Не путай сравнение и равенство!
Для логических операторов используется только «==»
Для присваивания только «=»
if x==y:
t=q
Также не забываем про двоеточие в конце вопроса.
6. Если код не работает — виноват сам код.
Лично у меня за всё время ползанья по bge (а это чуть больше 2х лет) ни разу не случалось ошибок bge. Только мои собственные. Если и есть шанс бага блендера — он настолько мизерный, что его можно не брать в расчёт и в любом случае начинать с проверки кода.
Глава 5.
Процессируем в Text Editor на пальцах.
Код, указанный выше довольно простой, а потому хорошо подойдёт для разогрева.
Итак, по коду — он управляет освещением автомобиля. Это стоп-сигналы, лампы заднего хода и фары. Альтернатива — только анимация, что намного жирнее по ресурсам выйдет. Бонусом придётся забить кирпичиками ноды всех объектов и страдать при попытке что-то подрегулировать.
Посмотреть полную версию скрипта можно в последнем обновлении.
О процессе создания.
Этап первый — подготовка.
Первым делом было написано :
import bge \\ импортируем библиотеку BGE
cont = bge.logic.getCurrentController() \\ сокращаем получение текущего контроллера
own = cont.owner \\ сокращаем доступ к объекту, на котором находится контроллер
scene = bge.logic.getCurrentScene() \\ сокращаем получение информации от текущей сцены
Это что-то вроде базовых функций, которые используются чаще всего. Их стоит знать в глаза.
Грубо говоря я на этом этапе заранее утаптывал почву для того, что бы начать строить скрипт.
Этап второй — планирование.
Самое время задуматься о том, что требуется от скрипта.
Из обязательного — включение\выключение ламп заднего хода и тормоза без использования анимации.
Смотрим на наши возможности — открываем python reference и вводим в поиск «light»
Она нам выдаёт внушительный список, но нас интересует только bge.
В списке в первой позиции имеется bge.types.KX_Scene.lights — читаем и видим A list of lights in the scene, (read-only).
Это нам не подходит т.к. функция позволяет лишь получить список ламп в сцене. Возвращаемся в поиск.
Листаем ниже и находим bge.types.KX_LightObject. Под ним находим переменные этого LightObject — дистанция, энергия, цвет, тип источника света — то, что нужно. Значит, это функция отвечает непосредственно за источник освещения.
Смотрим в пример:
import bge
co = bge.logic.getCurrentController()
light = co.owner
light.energy = 1.0
light.color = [1.0, 0.0, 0.0]
Из примера становится ясно, что управляется источник света через Объект.функция света = (значение)
Потому как bge.logic.getCurrentController().owner равнозначно текущему объекту. Это хорошо потому, что вместо текщего объекта можно поставить любой другой. Значит, можно уместить код на одном объекте без сложностей указав лампы из кода и накинуть скрипт куда-нибудь на пустышку, объединяющую все лампы.
Наличие переменной цвета нам очень даже пригодится — мы можем те же задние лампы использовать и в качестве ламп заднего хода, что хорошо — сэкономим на кол-ве источников света.
Этап третий — пишем код.
Если мы хотим расположить скрипт на одном объекте — нужно указать все лампы.
База у нас уже была, а потому дописываем:
lamp1 = scene.objects['StopL']
lamp2 = scene.objects['StopR']
Мы присвоили этим двум переменным значение объектов-ламп тормоза.
Теперь можно задуматься о способе включения ламп.
Из очевидного — включать лампы когда нажата клавиша S, но это не то т.к. лампы будут работать и при заднем ходе. Идём в объект-автомобиль и попутно открываем Powertrain. В планах переключать переменную только тогда, когда констреинт будет использовать торможение.
Находим в Powertrain.py блок, отвечающий за торможение — def Brakes()
В нём нас интересует только # brake и # no brakes потому, что # emergency это ручной тормоз, а # emergencyD — копипаста ручника при смерти, которая клинит колёса.
сам скрипт я немного модифицировал т.к. старый не работал. Он проверял разные состоряния нажатия клавиши тормоза (brake.positive == True) и клавиши занего хода (reverse.positive == False), хотя это была одна клавиша — ‘S’.
Я добавил проверку скорости и состояния клавиши газа. Таким образом, тормоза срабатывали [при скорости выше 0 и при нажатом тормозе] или [при скорости ниже 0 и при нажатом газе ]
Конструкция проверки уже имеется и нам остаётся только дописать под функциями присвоение нашей переменной.
Состояние записывается в пееременную BrakeBool (True или False). Записана она в виде «own[‘BrakesBool’]» потому, что находится в N-панели редактора логики и, соответственно, сперва приходится указывать объект, на котором скрипт уже будет искать переменную.
Нам осталось только получить состояние этой переменной в скрипте освещения.
Всё, что было сделано в Powertrain.py — чисто для определения состояния тормоза. ну, за исключением правки скрипта. Таким образом на выходе мы имеем переменную, которая имеет значение <True или False в зависимости от состояния тормоза.
Содаём объект-пустышку и родительской связью привязываем его к фонарям. У пустышки создаём через редактор логики сенсор Always (всегда), включаем обновление (кнопочка с тремя точками сверху) и соединяем с контроллером «python» с указанием нашего скрипта.
Далее идём в скрипт и собираем всю необходимую информацию от объекта-автомобиля:
car = scene.objects['Cube'] \\ сокращаем получение информации от объекта "Cube" (коллайдер автомобиля, на котором "держится" основная часть логики машины)
brake = car['BrakeBool'] \\ присваиваем переменной brake состояние переменной BrakeBool от объекта-автомобиля
rear = car.sensors['Reverse'] \\ присваиваем переменной rear состояние сенсора "Reverse"(по-сути просто нажатие клавиши S)
speed = car['speed'] \\ присваиваем переменной speed переменную speed из объекта автомобиля.
Далее просто собираем всю информацию в код.
if brake == True: \\ если тормоз включён
stop1.energy = 8.0 \\ энергия первой лампы = 8
stop2.energy = 8.0
stop1.color = [1.0,0.0,0.0] \\ цвет первой лампы красный (значения указываются по палитре RGB [r,g,b])
stop2.color = [1.0,0.0,0.0]
elif rear.positive and speed < 0: \\ иначе если нажата клавиша S и скорость меньше 0 (задний ход)
stop1.energy = 1.0 \\ энергия первой лампы равна 1
stop2.energy = 1.0
stop1.color = [1.0,1.0,1.0] \\ цвет первой лампы белый
stop2.color = [1.0,1.0,1.0]
else: \\ иначе (если машина не тормозит и не включён задний ход)
stop1.energy = 0.0 \\ энергия первой лампы = 0
stop2.energy = 0.0
По тормозам вроде всё. Для наполнения скрипта я ещё добавил фары и в кирпичики поставил переключение boolean переменной при нажатии клавиши H
front1 = scene.objects['FrontL'] \\ присваиваем переменной front1 объект-лампу
front2 = scene.objects['FrontR']
FrontLight = own['FrontLight'] \\ присваиваем переменной FrontLight переменную с таким же названием, но созданную в редакторе логики (которая регулируется кирпичиками)
if FrontLight == True: \\ если переменная имеет значение True
front1.energy = 2.0 \\ энергия фары1 = 2
front2.energy = 2.0
else: \\ иначе (т.е. если переменная имеет значение False)
front1.energy = 0.0 \\ энергия = 0
front2.energy = 0.0
Весь скрипт в основном состоит из той самой конструкции проверки:
Если условие выполнено:
выполняем действие