Главная » Статьи » Деццкий сад

Делаем игру вместе. Урок №1.
Первая статья из цикла "делаем игру вместе". Делать мы будем ни что иное как мега РПГ всех времён и народов smile Ведь именно этого желают почти все начинающие геймдевелоперы, за исключением тех, конечно, кто делает GTA smile

Для начала создадим структуру папок для нашей мегаРПГ
megarpg (корневая папка)
+modules (папка для созданных нами программных модулей)
+res (папка с ресурсами игры)
++textures (текстуры)
++actors (анимированные персонажи)
++geometry (обычная геометрия)
++sound (звуки)

Теперь создадим (пока пустые) файлы скриптов:
в корневой папке: main.py
в папке modules:
__init__.py - этот файл информирует питон о том, что папка, в которой он находится является модулем, из которого можно экспортировать нужные нам классы и функции
location.py - здесь у нас будут скрипты для работы с локацией
control.py - здесь - скрипты управления - камера, мышь

Пока хватит, приступим к коду. (Если ещё не запаслись подходящим редактором для питона, то сначала изучаем статью Быстрый старт)

Открываем файл location.py и пишем

Code

# -*- coding: utf_8 -*-

Это сообщит интерпретатору, что кодировка у нас будет utf-8. Она необходима для нормальной работы с кириллическими символами.
Для земли в нашей локации мы будем использовать карту высот и класс GeoMipTerrain. Для этого импортируем нужный нам класс

Code

from pandac.PandaModules import GeoMipTerrain

Теперь создадим класс gameLocation и процедуру его инициализации

Code

class gameLocation():
    def __init__(self):
        self.terrain=GeoMipTerrain("Terrain")

процедура __init__ всегда выплняется при создании нового экземпляра класса - это стандарт языка python, впрочем, об этом лучше почитать в любом учебнике по python-у. Так же как и о базовом синтаксисе. Поэтому будем считать, что хотя бы основы питона вы уже знаете (учебников и статей по питону в сети хватает).
В процедуре у нас пока одна строчка, которая создаёт новый экземпляр GeoMipTerrain с именем "Terrain"
Добавим к нашему классу новую процедуру loadTerrain для построения нашей земли на основе карты высот. В качестве второго (первым идёт обязательный self) параметра будем передавать имя файла, содержащего карту высот. Для тех, кто не в курсе - карта высот - обычно, файл, содержащий чёрно-белое изображение - чем темнее цвет, тем ниже уровень земли и наоборот. У меня карта высот - это файлик, созданный с помощью Different Clouds (Разностные облака) в гимпе. Аналогичный фильтр есть и в фотошопе, если кому-то удобнее он.

Code

    def loadTerrain(self,hfFile):
        self.terrain.setHeightfield(Filename(hfFile))
        self.terrain.setBlockSize(32)
        self.terrain.setFactor(64)
        self.terrain.setMinLevel(2)
        self.terrain.getRoot().reparentTo(render)
        self.terrain.getRoot( ).setSz (30)
        self.terrain.generate()
        self.terrain.setFocalPoint(base.camera)

Первая строка - объявление нашей процедуры в дальнейшем я этого пояснять не буду и первой строкой буду считать уже непосредственно код, поэтому первая строка - self.terrain.setHeightfield(Filename(hfFile))
Этой строкой мы назначаем карту высот, которая будет передана в параметре hfFile созданному нами при инициализации террайну. Обратите внимание - мы используем Filename для чего, как и зачем - читать здесь. Ну и конечно нужно его импортировать - строка импотра теперь выглядит так

Code

from pandac.PandaModules import GeoMipTerrain, Filename

Вторая строка - размер блока на основе которого будет строиться сетка - в нашем случае - 32 пикселя - т.е. изображение будет разбито на блоки 32х32 пикселя и на основе этого будет построена сетка.
Третья строка - качество создаваемой сетки вблизи камеры. Забыл сказать сразу - GeoMipTerrain умеет динамически генерировать сетку в зависимости от расстояния до камеры - чем ближе камера, тем больше полигонов в сетке. Вот, качество этой сетки мы и устанавливаем третьей строкой
Четвёртая строка - уровень минимальной детализации. По дефолту он 0 - максимальное качество, однако, мы его несколько снизим. Вообще говоря, эти параметры подбираются экспериментальным путём в зависимости от расстояния камеры до нашего террайна, разрешения карты высот, желаемого качества.
Пятая строка - присоединяем нашу землю к корневому узлу сцены чтоб она была видна. почитать1 почитать2
Шестая - устанавливаем масштабирование по оси Z - вертикальной для придания видимости рельефу, т.к. изначально рельеф минимален.
Седьмая - генерируем террайн на основе уcтановленных нами параметров
Восьмая - назначаем узел, который будет считаться камерой для нашей земли и на основе положения которого будет рассчитываться уровень детализации.
С генерацией пока закончили.
Теперь нужно добавить задачу обновления нашего террайна при изменении положения камеры.
Пишем процедуру для нашей задачи - всё в том же классе

Code

    def update(self,task):
        self.terrain.update()
        #self.terrain.getRoot().setRenderModeWireframe()
        return task.cont  

тут всё просто - первая строчка обновляет террайн, вторая закомментирована - если её раскомментировать, то мы будем видеть сетку (Wireframe) террайна - это если интересно посмотреть как наш террайн генерируется.
По поводу формы записи процедур для пандовского менеджера задач читать здесь
Ну и добавим написанную процедуру в менеджер задач - для этого вернёмся к процедуре __init__ и допишем строку

Code

taskMgr.add(self.update,'location_update')

taskMgr является глобальной переменной менеджера задач, которая создаётся при использовании DirectStart, так же как и некоторые другие базовые объекты, например, корневые узлы или камера. Мы конечно можем это всё создавать сами, но проще использовать готовый DirectStart.

Переходим к главному файлу main.py
Пишем следующее:

Code

# -*- coding: utf_8 -*-
import direct.directbase.DirectStart
from modules.location import gameLocation

loc=gameLocation()
loc.loadTerrain('res/textures/heightfield.png')

run()

Певая строка - понятно, уже пояснял.
Вторая - Импортируем DirectStart о котором я только что говорил.
Третья - Импортируем созданный нами модуль локации
Четыре - создаём экземпляр нашей локации и присваиваем её переменной loc
Пять - генерируем террайн - процедурой, которую мы только что с вами написали в модуле location.py. Естественно, карту высот нужно предварительно кинуть в res/textures
Шесть - "Мотор!"

Можно запускать, в итоге мы узреем серый экран с непонятной белой фигнёй

Если покрутить её при помощи зажатой средней клавиши мыши, то станет ясно, что это всё же какая-то поверхность.

Попробуйте повторить. Вот мой heightfield.

P.S. Вопросы и обсуждение лучше вести в соответствующей ветке форума.

Категория: Деццкий сад | Добавил: ninth (06.05.2009)
Просмотров: 3189 | Рейтинг: 5.0/5
Всего комментариев: 9
0  
1 Stas-Malkov   (20.01.2011 14:50)
(all display modules loaded.)
Traceback (most recent call last):
File "main.py", line 3, in <module>
from modules.location import gameLocation
ImportError: No module named modules.location
Выдаёт ошибку =(

0  
2 ninth   (01.02.2011 22:49)
Если файл location.py существует в папке modules, но он всё равно ругается - проверь там же должен лежать пустой файл __init__.py

0  
3 pihto   (06.03.2011 02:17)
location.py в 11 строчке пробел self.ter rain.setFactor(64)

0  
4 ninth   (09.03.2011 23:03)
это глюки местного bb code - он периодически пробелы в код втыкает.

0  
5 Nedrovai   (17.07.2011 16:33)
цитата ninth "в папке modules, но он всё равно ругается - проверь там же должен лежать пустой файл __init__.py"
Stas-Malkov сам мучался целый вечер))) проснулся присмотрелся и вуаля, собака зарыта в имени файла __init__.py. у меня он записан был _init_.py. тоесть не две "__" (незнаю как назвать _ _ эти подчерки) а одна "_"

вывод.

максимум внимательности!

0  
6 injbon   (19.07.2011 19:02)
Помогите, только учусь, - мне не понятно в каких файлах, что писать, пробывал разные варианты но всегда ошибка
ImportError: No module named modules.location
Помогите, что делаю не так?

0  
7 serg-kkz   (19.07.2011 20:48)
injbon Это сообщение о том что не найден модуль(файл) 'location' в папке 'modules' проверте есть ли он в ней, так же проверьте наличие в ней файла '__init__.py' он пустой, если нет то скопируйте название отсюда(без ковычек) и создайте txt файл и вставьте в название. Ещё один момент, у кого винда. В любом окне, Сервис->Cвойства папки->Вид, убрать галочку, Скрывать расширения для зарегистрированных типов файлов. У этого урока есть тема на форуме, просить о помощи здесь. ДеЦЦкий сад "ПандЁнок"

0  
8 injbon   (19.07.2011 21:09)
спасибо

0  
9 3BiP   (20.09.2011 00:26)
У мя ошибочка...
:grutil(error): No valid heightfield image has been set!

Вроде все прально сделано, и картинка пральная... Подскажите в чем можт быть проблемка....
Ответ: Ответил на форуме.

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