Все игровые объекты в BGE являются экземплярами классов, предоставляя пользователю широкий выбор возможностей для управления. Есть конечно нюансы, например новый экземпляр класса, наследующего базовый, невозможно создать "с нуля", обязательно нужно "мутировать" старый экземпляр, в офф. документации есть пример кода, его обязательно нужно прочитать. И есть один затык - " а как же собственно, созданным экземпляром управлять?" То есть как вызывать дописанные нами функции? Попробуем разобраться.
Пишем определение тестового класса, он будет простейшим:
class a(bge.types.KX_GameObject):
def __init__(self, old_owner):
self.prop = 0
def update(self):
self.prop += 1
self.worldPosition[1] += 0.1
Как видно, расширенное определение класса при создании экземпляра всего-навсего добавляет базовому классу дополнительное (неигровое!!!) свойство и функцию .update(), которая прибавляет к значению этого свойства 1 и смещает экземпляр по глобальной оси Y на 0.1 будем считать что метра. Где-то делаем отдельную функцию или вообще отдельный скрипт, который будет добавлять с неактивного слоя выбранный нами объект и дополнять его, как в примере кода. Что-то вроде:
# должно еще быть оформление функции или if sensor.positive:
old = scene.addObject('Sphere')
obj = a(old)
Всё, экземпляр создан, все функции по идее доступны, мы в любой момент можем вызвать obj.update() вручную, но сей пост затевался с целью прояснить вопрос, а как бы экземпляр сам себе вызывал функции, автоматом. Самый простой способ - создать в глобальном словаре, или еще где, список ссылок на экземпляры класса, нуждающиеся в обновлении. И потом просто пробегать его каждый тик циклом:
for obj in bge.logic.globalDict['updateObjects']:
obj.update()
Вполне подходит для всяких эмиттеров частиц, или для других объектов, нуждающихся в постоянном запуске одной и той же функции, причем скопом. Есть еще вариант всунуть функцию update в список pre_draw или post_draw объекта текущей сцены, но там есть еще подводные камни, типа невозможности нормального удаления объекта с помощью endObject(). Я этот способ рекомендовать не могу, поскольку сам не разбираюсь толком. Чисто посмотреть на код:
def __init__(self, old_owner):
self.prop = 0
scene.pre_draw.append(self.update)
Функция .update будет исполнятся каждый раз при подготовке рендера, или после него. Оба предыдущих варианта вполне подходят, что бы организовать в .update чтение событий клавиатуры, или состояния сенсоров, к примеру. Но раз уж зашла речь о сенсорах, то зная, какой объект мы будем добавлять в сцену для последующего тюнинга, вполне возможно организовать на нём цепочку сенсор -> контроллер, типа "модуль", и указать для исполнения функцию типа такой:
def update(cont):
own = cont.owner
own.update()
Как-то так:
В таком варианте используется BGE-шный способ управления событиями, основанный на связке кирпичей и скриптов, получается более привычно, что для новичка немаловажно. Каким способом воспользоваться, решайте сами. Если придумаете еще какой-нибудь, обязательно отпишитесь, интересно же.
Пишем определение тестового класса, он будет простейшим:
class a(bge.types.KX_GameObject):
def __init__(self, old_owner):
self.prop = 0
def update(self):
self.prop += 1
self.worldPosition[1] += 0.1
Как видно, расширенное определение класса при создании экземпляра всего-навсего добавляет базовому классу дополнительное (неигровое!!!) свойство и функцию .update(), которая прибавляет к значению этого свойства 1 и смещает экземпляр по глобальной оси Y на 0.1 будем считать что метра. Где-то делаем отдельную функцию или вообще отдельный скрипт, который будет добавлять с неактивного слоя выбранный нами объект и дополнять его, как в примере кода. Что-то вроде:
# должно еще быть оформление функции или if sensor.positive:
old = scene.addObject('Sphere')
obj = a(old)
Всё, экземпляр создан, все функции по идее доступны, мы в любой момент можем вызвать obj.update() вручную, но сей пост затевался с целью прояснить вопрос, а как бы экземпляр сам себе вызывал функции, автоматом. Самый простой способ - создать в глобальном словаре, или еще где, список ссылок на экземпляры класса, нуждающиеся в обновлении. И потом просто пробегать его каждый тик циклом:
for obj in bge.logic.globalDict['updateObjects']:
obj.update()
Вполне подходит для всяких эмиттеров частиц, или для других объектов, нуждающихся в постоянном запуске одной и той же функции, причем скопом. Есть еще вариант всунуть функцию update в список pre_draw или post_draw объекта текущей сцены, но там есть еще подводные камни, типа невозможности нормального удаления объекта с помощью endObject(). Я этот способ рекомендовать не могу, поскольку сам не разбираюсь толком. Чисто посмотреть на код:
def __init__(self, old_owner):
self.prop = 0
scene.pre_draw.append(self.update)
Функция .update будет исполнятся каждый раз при подготовке рендера, или после него. Оба предыдущих варианта вполне подходят, что бы организовать в .update чтение событий клавиатуры, или состояния сенсоров, к примеру. Но раз уж зашла речь о сенсорах, то зная, какой объект мы будем добавлять в сцену для последующего тюнинга, вполне возможно организовать на нём цепочку сенсор -> контроллер, типа "модуль", и указать для исполнения функцию типа такой:
def update(cont):
own = cont.owner
own.update()
Как-то так:
В таком варианте используется BGE-шный способ управления событиями, основанный на связке кирпичей и скриптов, получается более привычно, что для новичка немаловажно. Каким способом воспользоваться, решайте сами. Если придумаете еще какой-нибудь, обязательно отпишитесь, интересно же.
Комментариев нет:
Отправить комментарий