Войти

Показать полную графическую версию : *Теория* | Спрайты в псевдо 3D


Kerbit
16-04-2007, 17:17
Здраствуйте.
Нужна информация по программированию спрайтов, на подобии тех, что были в играх Doom или Wolfenstein. Что это такое мне известно и я даже представляю как это написать, но хотелось бы узнать, как это делать правильно. Желательно ссылки на статьи и теорию.

XPEHOMETP
16-04-2007, 22:34
Надо бы еще определиться с системой разработки. Например, под С есть игровая библиотека Allegro, у которой есть функции для работы со спрайтами. Если такой вариант подходит, соответственно, гуглить на Allegro.

Kerbit
16-04-2007, 23:05
Система разработки тут роли не играет. Все пишется с нуля и нужна чистая теория по написанию таких спрайтов.

ivank
17-04-2007, 00:36
Когда мне было 11 лет, я читал книжку "Секреты разработки игр" имени Андре Ла Мота. Страшная гадость, но основы того, как сделать игру типа вульфенштейна там были. Так же как и в учебнике геометрии за 7-й класс (разве что в случае учебника стоит ещё чуть-чуть голову приложить).

В вульфе и ему подобных есть два класса отрисовываемых объектов: стены и всё остальное :) Стены отрисовываются с помощью рэй-кастинга (отсчение лучей, наверное, сойдёт за перевод). В качестве отправной точки можно взять, например статью в википедии (http://en.wikipedia.org/wiki/Ray_casting). Там всё очень просто.

Второй класс объектов, которые следует рассматривать - "всё остальное". Тоже тривиально
1. Проходим по всем объектам, проводим вектор от игрока до объекта, если этот вектор попадает в область видимости, то объект ртрисовывтаь на экране надо, иначе - нет.
2. Если надо рисовать объект на экране - вычисляем расстояние до объекта, на основе которого вычисляем коэффициент масштабирования (размер спрайта обратно-пропорционален расстоянию до него).
3. Затем по углу вычисляем, где на экране получится центр спрайта (если прочитать про рейкастинг, то там будет написано, что каждой вертикали на экране игрока соответствует свой угол, от (направление взгляда игрока - alpha), до (направление взгляда игрока + alpha), где alpha ~ 30-45 uhflecjd)).
4. Рисуем спрайт в соответствии с z-буфером
5. всё

Я свой клон вульфа (с рудиментарными монстрами) написал на QBasic'е за неделю. Он даже почти не тормозил на 486'ом.

В думе всё сложнее (в части поиска пересечения со стеной, там по-моему впервые BSP-деревья додумались применять для этого), проще разобраться с "настоящей" трёхмерной графикой, по-моему. Тем более, что в нынешних условиях это намного практичней и эффективней.

Kerbit
17-04-2007, 01:40
Необходимо чтобы процесс отрисовки спрайтов был наиболее оптимален. Программа пишется исключительно в учебных целях. Просьба не указывать на то, что сейчас это не актуально.
Благодарю за пояснения. Только у меня есть несколько вопросов. Уточню, что спрайт может перемещаться исключительно по сетке, на которой могут распологаться стены.
1. Проходим по всем объектам, проводим вектор от игрока до объекта, если этот вектор попадает в область видимости, то объект ртрисовывтаь на экране надо, иначе - нет.
Как определить попадает ли вектор в область видимости? Заново проверять его пересечения со стенами? Или отдельно хранить информацию про видимые сектора? Не логичнее ли будет в процессе определения пересечения лучей со стенами запоминать, какие спрайты пересек луч.
4. Рисуем спрайт в соответствии с z-буфером
Насколько я понимаю, то z-буфер строится только для спрайтов. Как нарисовать спрайт, если он частично перекрыт стеной? Нужно выводить отдельно каждую вертикальную линию спрайта?

ivank
17-04-2007, 10:28
Kerbit
Как определить попадает ли вектор в область видимости?
Из точки стояния игрока можно провести луч - направление его взгляда. Если этот луч повернуть налево на 30 градусов и направо на 30 градусов, то получится угловой сектор в 60 градусов - область видимости. Чтобы проверить попадает ли объект в область видимости, надо проверить, что угол вектора до этого объекта лежит в этом секторе. (Чтобы избавиться от "дорогостоящей" операции арктангенса, которая требуется для определения угла, можно воспользоваться скалярным произведением векторов. Произведение вектора до объекта на левый луч, ограничивающий область видимости, должно быть отрицательно, а на правый - положительно [или наоборот, запамятовал я элементарную геометрию]).

Не логичнее ли будет в процессе определения пересечения лучей со стенами запоминать, какие спрайты пересек луч.Если они у вас могут находится только вдоль сетки стен (т.е. ничем от не отличаются от обычных стен, на самом дель), то наверное огичней. Но в общем случае, вы не можете оперделить пересечение с произвольным обхектом, так как они как правило хранятся только в виде координаты и радиуса. Считать персечение луча с окружностью (тем более, что это придётся делать "количество лучей (320)" х "количество обхектов на карте") - это очень дорого.

Насколько я понимаю, то z-буфер строится только для спрайтов. z-буфер строится для всего экрана. Сначала мы отрисовываем стены и в соответствии с ними первоначально заполняем z-буфер. Затем каждый раз при необходимости нарисовать (непрозрачную) точку спрайта проверяем - если расстояние до неё < расстояния в z-буфере, то рисуем и записывем в буфер расстояние до этой точки, иначе ничего не делаем.

В крайнем случае (для экономии памяти и количества вычислений) можно сделать z-буфер размером только по числу лучей (т.е. хранить для каждого луча координаты до ближайшего объекта с которым он пересёкся), но в этом случае некорретно будут отрисовываться одни объекты за другими; тогда надо будет применить "алгоритм художника" - сначала определяем список всех объектов, которые надо отобразить, сортируем их по дальности и отрисовываем "от дальних к ближним".

Нужно выводить отдельно каждую вертикальную линию спрайта?да. В принципе механизм отсечения лучей основан на том, что мы всё рисуем по вертикалям, соответствующим лучам в горизонтальной плоскости.

Vlad Drakula
22-04-2007, 14:11
Kerbit
покупаем клини под авторством - "шиков и боресков", там все подробно описано от теории до практики с примерами...
книги дешовые, но очень позновательные, просто маст хев!!!




© OSzone.net 2001-2012