Главная » Статьи » Учебник: практика

Hellow World!
Итак мы напишем нашу самую первую программу на Панде с использованием питона - типичный Hellow world.

Программа, которую мы напишем будет загружать небольшую сцену и анимированную модель панды.

Для начала создадим текстовой файл с расширением .py . Если вы хотите использовать кириллические символы в тексте и комментариях, то необходимо чтобы файл был в кодировке utf-8. Напишем следующие строчки в нашем файле:
Code
#-*- coding: utf-8 -*-
import direct.directbase.DirectStart
run()


Первая строка сообщает интерпретатору о том, что мы будем использовать кодировку utf-8. Импортирование DirectStart загружает большинство необходимых модулей панды и подготавливает окно к выводу изображения. Run - подпрограмма, содержащая главный цикл Panda3D. В ней отрисовывается кадр и выполняются фоновые задачи, после чего цикл повторяется. Эта подпрограмма должна быть вызвана единожды в конце вашего скрипта. В этом примере сцена не содержит данных для отрисовки, поэтому мы увидим пустое серое окно.

Для запуска програмы наберите в командной строке:

python filename.py

Большинство специализированных редакторов позволяют запускать скрипт прямо из окна редактирования. Если всё было сделано правильно, мы должны увидеть серое окно с заголовком Panda. Пока мы ничего не можем в нём сделать, однако это недолго изменить.

Теперь загрузим небольшую демонстрационную сцену, для этого изменим код следующим образом:

Code
#-*- coding: utf-8 -*-
import direct.directbase.DirectStart
#Загрузка модели окружения
environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)
#Запуск
run()


Команда loader.loadModel() загружает указанный файл. Расширение файла указывать не обязательно. Поиск файла модели будет производиться сначала по указанному пути, а если ничего не найдено, то в model path, прописанном в конфигурационном файле (как в данном случае). Возвращаемое значение 'NodePath', указатель на модель. Обратите внимание, в имени файла используются прямые слеши даже под Windows.

Panda3D содержит структуру данных, называемую scene graph. Scene graph это дерево, содержащее все модели, которые необходимо выводить на экран. Корень этого дерева - объект, называемый render. Объекты не помещённые в граф сцены не будут выведены на экран.

Для перемещения нашей модели в граф сцены мы используем метод reparentTo. Этим методом мы устанавливаем родителя нашего объекта, тем самым помещая его в граф сцены, что делает его видимым.

В завершение мы изменяем позицию и масштаб модели.
Попробуйте запустить программу.
По умолчанию Панда запускает задачу, которая позволяет управлять камерой с помощью мыши:
Левая кнопка: перемещение вправо-влево
Правая кнопка: назад-вперёд
Средняя: вращение вокруг центра сцены
Правая и средняя: вращение по оси взгляда
Попробуйте - вам станет ясно, что это не самый удобный способ управления камерой.
Взамен, мы напишем задачу (task) которая напрямую будет контролировать камеру. Задача (task) - это подпрограмма, вызываемая каждый цикл прорисовки, либо через заданный промежуток времени. Изменим наш код:

Code
#-*- coding: utf-8 -*-
import direct.directbase.DirectStart
from direct.task import Task
from direct.actor import Actor
import math
#Загрузка модели окружения
environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)
#Задача перемешения камеры
def SpinCameraTask(task):
  angledegrees = task.time * 6.0
  angleradians = angledegrees * (math.pi / 180.0)
  base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
  base.camera.setHpr(angledegrees, 0, 0)
  return Task.cont
  taskMgr.add(SpinCameraTask, "SpinCameraTask")
run()


Функция taskMgr.add указывает менеджеру задач панды, что нужно каждый цикл вызывать подпрограмму SpinCameraTask . Это подпрограмма, которую мы написали для управления камерой. До тех пор, пока подпрограмма SpinCameraTask возвращает константу Task.cont, менеджер задач будет продолжать выполнять её каждый кадр.

Наша подпрограмма вычисляет необходимую позицию камеры, основанную на прошедшем времени.Камера поворачивается на 6 градусов в секунду . Первые две строчки вычисляют желаемую ориентацию камеры - первая в градусах, вторая в радианах. SetPos устанавливает новую позицию камеры. SetHpr - ориентацию камеры. Замечание: SetPos и SetHpr- методы, наследованные от nodePath - подробнее об этом в главе про Граф сцены.

Теперь загрузим анимированного персонажа — допишем код:

Code
#-*- coding: utf-8 -*-
import direct.directbase.DirectStart
from direct.task import Task
from direct.actor import Actor
import math

#загрузка модели окружения
environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

#задача перемещения камеры
def SpinCameraTask(task):
  angledegrees = task.time * 6.0
  angleradians = angledegrees * (math.pi / 180.0)
  base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
  base.camera.setHpr(angledegrees, 0, 0)
  return Task.cont

taskMgr.add(SpinCameraTask, "SpinCameraTask")

#загрузка модели и проигрывание анимации
pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"})
pandaActor.setScale(0.005,0.005,0.005)
pandaActor.reparentTo(render)
pandaActor.loop("walk")

run()


Класс Actor предназначен для анимированных моделей. Мы используем loadModel для статических моделей, и Actor только если они анимированы. Два аргумента конструктора класса Actor — первый - имя файла, содержащего модель, второй — словарь, содержащий записи о файлах анимации.

Команда loop("walk") запускает анимацию на циклическое воспроизведение. В результате модель панды топчется на месте.

Следующим шагом мы заставим панду перемещаться назад-вперёд:

Code
#-*- coding: utf-8 -*-
import direct.directbase.DirectStart
from pandac.PandaModules import *

from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
import math

#загрузка модели окружения
environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

#задача перемещения камеры
def SpinCameraTask(task):
  angledegrees = task.time * 6.0
  angleradians = angledegrees * (math.pi / 180.0)
  base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
  base.camera.setHpr(angledegrees, 0, 0)
  return Task.cont

taskMgr.add(SpinCameraTask, "SpinCameraTask")

#загрузка моддели и проигрывание анимации
pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"})
pandaActor.setScale(0.005,0.005,0.005)
pandaActor.reparentTo(render)
pandaActor.loop("walk")

#создаём четыре интервала
pandaPosInterval1= pandaActor.posInterval(13,Point3(0,-10,0), startPos=Point3(0,10,0))
pandaPosInterval2= pandaActor.posInterval(13,Point3(0,10,0), startPos=Point3(0,-10,0))
pandaHprInterval1= pandaActor.hprInterval(3,Point3(180,0,0), startHpr=Point3(0,0,0))
pandaHprInterval2= pandaActor.hprInterval(3,Point3(0,0,0), startHpr=Point3(180,0,0))

#создаём из интервалов последовательность и проигрываем её
pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1,
  pandaPosInterval2, pandaHprInterval2, name = "pandaPace")
pandaPace.loop()

run()


Интервалы (interval) — это фоновые задачи (tasks) которые меняют параметры от одного значения к другому в течение заданного времени. Например, рассмотрим pandaPosInterval1. Когда интервал запущен он постепенно меняет позицию панды от (0,10,0) до (0,-10,0) за период в 13 секунд. Аналогично pandaHprInterval1 меняет ориентацию — поворачивает панду на 180 градусов в течение 3 секунд.

Последовательность (Sequences) — задача, которая запускает интервалы один за другим. PandaPace — последовательность, которая перемещает панду по прямой, затем разворачивает на 180 градусов и перемещает обратно, и снова поворачивает. PandaPace.loop() стартует последовательность в режиме цикла.

В результате наша панда должна перемещаться между деревьями туда-сюда.
Категория: Учебник: практика | Добавил: ninth (28.01.2009)
Просмотров: 9774 | Комментарии: 5 | Рейтинг: 4.4/9
Всего комментариев: 5
1  
То что надо для таких как я ! wacko

2  
Крутой сайт! Как раз вот питоном увлёкся, очень гибкий язык. Теперь вот захотелось создать чё-нить 3d-шное. Спасибо за статью! biggrin

3  
  • У меня в 40-й строке синтаксическую ошибку. Программа показывает ошибку в "=" в отрезке "name = "pandaPace"". В чем может быть причина?

  • 4  
    Я ошибку воспроизвести не могу - после копирования кода и вставки в редактор всё работает. Желательно привести полный текст ошибки.

    5  
    Интересно . Только плохо что всё через коддинг. Была бы студия , было бы полегче))

    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0