Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.03.2010, 22:10   #441
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Сообщений: 136
Вопрос

Да, тема довольно интересная, правда, местами сложная для понимания.
Но, у меня возникло небольшое разногласие: простите, если я ошибаюсь, но мне кажется что Банк текстур не нужная трата ресурсов. Что бы избавиться от непониманий в дальнейшем, привожу код своего Банка:

Код:
// В глобальных переменных задаю массивы карты и банка
Map: array[0..19,0..19] of word; Bank: array[1..256] of TBitmap;
// Процедура создания банка
procedure TForm1.CBank;
var
i: word;
begin
for i:=1 to 256 do
begin
Bank[i]:= TBitmap.Create; Bank[i].LoadFromFile('текстуры\'+IntToStr(i)+'.gif');
end;
end;
{Теперь, когда банк создан, и массив map заполнен, я рисую карту:}
procedure TForm1.DMap;
var
a,b: word;
begin
for y:=0 to 19 do for x:=0 to 19 do
begin
Form1.Canvas.Draw(10*a,10*b,Bank[Map[a,b]]);
end;
{Вот тут можно почистить Банк дополнительным циклом с методом FreeImage}
end;
В итоге получается: 256 битмапов с текстурами в памяти (если их не почистить, но даже с чистыми картинками массив все же “висит” в памяти).
Скажите, неужели толк от Банка текстур настолько выше и значительней, чем простое создание 1-го битмапа, загрузки в него текстур и очистки этого битмапа, после окончания работы с ним???

P.S. Тему читал всю, но заметил лишь два пункта превосходства Банка текстур, хотелось бы больше.
Alexan-Dwer вне форума Ответить с цитированием
Старый 14.03.2010, 22:48   #442
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Зачем же обязательно 256, когда можно использовать ровно столько, сколько надо? Используйте динамический массив строго необходимого размера, и будет вам оптимальное использование ресурсов. (Хотя уже в упор не помню, есть ли в Паскале динамические массивы, но в Delphi точно должно быть что-то подходящее!)
Можно, конечно, хранить все текстуры в виде одного сложного битмапа - это вопрос удобства, но все равно где-то должна храниться разнообразная информация о картинке (размеры, количество кадров в анимации, прозрачность и т.д. и т.п.)
Или вы имеете в виду каждый раз грузить из файла одну текстуру, рисовать ее, выгружать из памяти, грузить следующую, рисовать, выгружать, и так далее множество раз в секунду? Вот тогда это уж настоящая пустая трата ресурсов!
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 14.03.2010, 23:42   #443
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Сообщений: 136
Стрелка

Уважаемый Гром, я не профессионал и все что пишу, основано на моих собственных умозаключениях и на том, что видел своими глазами. Вот вы в своем сообщение говорите, что происходит при использовании буфера:
Цитата:
...грузить из файла одну текстуру, рисовать ее, выгружать из памяти, грузить следующую, рисовать, выгружать, и так далее множество раз в секунду...
А что мы имеем при Банке текстур? Загрузка и рисование присутствует, разве что вот выгрузки нет; но зато у нас есть целый массив с картинками, которые весят как минимум по 3 Кб, а если карта как в примере 20x20? Тогда получим 1Мб на одни картинки, а то и больше. Я понимаю, что когда речь идет об одинаковых текстурах, Банк текстур это очень хороший выход. Но, один раз я имел случай сделать screenshot 2D игры и то, что я там увидел, было жестоко — все текстуры были похожи, но различались примерно на 7 точек из 16 (насколько помню). А вот на первый взгляд казалось, что они просто копия друг друга. Для подтверждения увиденного открыл папку текстуры, скопировал около 40% и сравнивал в программе Photoshop с максимальным увеличением. Вот сейчас, когда вернулся к этому вопросу, думаю, есть ли смысл делать Банк текстур.

Цитата:
Зачем же обязательно 256, когда можно использовать ровно столько, сколько надо?
Это для примера К тому же, чем больше текстур, тем, на мой взгляд, меньше необходимость использовать Банк. Я считаю, что когда текстур мало, банк очень актуален, а вот когда есть всякие “каемки” и прочий реалистичный блеск, который увеличивает кол-во текстур, то тут уж очень спорный вопрос…

Последний раз редактировалось Alexan-Dwer; 14.03.2010 в 23:56. Причина: Пояснение
Alexan-Dwer вне форума Ответить с цитированием
Старый 15.03.2010, 00:14   #444
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Не отличающиеся внешне текстуры - это просто грубая ошибка художника/дизайнера. Тому, кто их делал - руки оторвать и пришить в более правильное место.
Так что, исходя из того, что разные текстуры выглядят достаточно отлично друг от друга, получаем, что либо текстур гораздо меньше, либо толк от них всех все равно есть.
Потом, при работе с банком текстур есть однократная загрузка с диска, а потом идет работа с оперативной памятью, что гораздо быстрее! А каждый раз читать с диска одну маленькую картинку, потом читать с диска еще 399 маленьких картинок, и так, скажем, 25 раз в секунду... Очень снижается быстродействие.
С банком текстур мы не имеем такой проблемы, расплачиваясь за существенное быстродействие сравнительно небольшим расходом оперативки, а если текстуры часто повторяются - то и совсем небольшим.

В общем, при увеличении числа текстур в варианте с банком - объем использования оперативной памяти растет линейно, в варианте без него - линейно же падает быстродействие. Вот только коэффициенты пропорциональности не в пользу варианта без банка.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 15.03.2010, 00:58   #445
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Гром говорит умные вещи, стоит поверить на слово, ...если только код написан был автоматически по примерам, и нет желания все же разобраться самому.

Попробую более доступным языком выразить все, что было уже сказано и показано в примерах.
Вот у нас некий шаблон карты. Он закодирован, и на каждую текстуру клетки карты приходится свой код. В структуре есть матрица индексов текстур (это слой карты), есть динамический массив банка текстур, например Array of TGBank. Идет загрузка данных, при этом натыкаясь на первый байт кода текстуры банку задается размер 1, в ячейку помещается текстура и все сопутствующие данные по типу (размеры, смещения и пр.) в матрицу слоя записывается по координатам (x,y) индекс ячейки банка. Далее, переход на следующий код клетки, ...массив банка проверяется на наличие уже загруженной такой текстуры от 1 до размера массива, если такой нет, то идет увеличение размера массива на 1 и заполнение последней ячейки текстурой и данными к ней, также в матрицу слоя идет индекс ячейки банка. На очередном шаге встречается очередной код карты, при проверке банка оказалось, что такая текстура уже загружена, ...загрузка пропускается, вместо нее в матрицу пойдет индекс найденного совпадения кода на карте и в проверяемой ячейке банка. И так далее, пока не будет считана вся карта.

Банк текстур никогда не очищается, если эта карта, или ее участок является активным в игре. Если нужна другая карта, тогда банк освобождается и заполняется заново, но уже текстурами к новой карте.
Алгоритм построения кадра игры всегда пользуется индексами матрицы карты и берет текстуры непосредственно из банка, ...никакого другого хранения текстур в игре, кроме как в банке, быть не должно.

Что в итоге? ...если текстурщик все продумал и создал набор оптимальных текстур, с помощью которых можно построить поверхность любой нужной сложности, то в памяти никогда не будет количества текстур, равных количеству клеток на карте, ...в том и заключается оптимизация.
Вот у нас слой поверхности: трава, земля, дорога. Если прикинуть, то по 5 вариантов достаточно для неоднообразности. В сочетании со случайным наполнением и точным расположением нужных типов текстур карты 20х20, благодаря банку в памяти будет всего 15 текстур, ...иначе 400 (!) ...а если текстуры 25х25, то в размерах соотносится как 27 Кбайт к 720 Кбайт (!) ...есть разница?
То же самое касается и слоя объектов, где текстуры уже будут поболее (вплоть до 400х500 пкс), понятно, что нет смысла держать в памяти копии текстуры одного и того же типа дерева, здания, части горы, ...да чего еще угодно.

Вот в этом суть банка текстур, при правильном его создании и использовании.

Что касается редактора карт. В любой момент может понадобиться любая из имеющихся текстур, ...у вас есть выбор, сразу загрузить все, или делать это по мере обращения к новым типам текстур, причем не выгружая прежних (если использование таковых не предвидится, то и загружать не нужно).
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 15.03.2010 в 01:02.
Beermonza вне форума Ответить с цитированием
Старый 16.03.2010, 21:18   #446
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Сообщений: 136
Лампочка

Цитата:
Гром говорит умные вещи, стоит поверить на слово, ...если только ... нет желания все же разобраться самому.
Желание есть, поэтому и разбираюсь. Для меня главное то, что я все же правильно мыслил: без Банка объем используемой ОЗУ меньше, но скорость тоже не велика.
Цитата:
Идет загрузка данных, при этом натыкаясь на первый байт кода текстуры банку задается размер 1, в ячейку помещается текстура … в матрицу слоя записывается по координатам (x,y) индекс ячейки банка. Далее, переход на следующий код клетки, ...массив банка проверяется на наличие уже загруженной такой текстуры ..., если такой нет, то идет увеличение размера массива на 1 и заполнение последней ячейки текстурой и данными к ней….
Насколько я понимаю, этот вариант используется в случаях, когда название текстуры состоит из букв (road.bmp, water.bmp) и идут не по порядку (1.bmp, 3.bmp, 8.bmp и т.д.), или же для того, что б уменьшить объем ОЗУ и загружать только необходимые текстуры.
  • В первом случае я бы их просто переименовал по порядку (1.bmp, 2.bmp...) и полностью загружал циклом:
    Код:
    for i:=1 to 255 do
    begin
    Bank[i]:= TBitmap.Create; Bank[i].LoadFromFile('текстуры\'+IntToStr(i)+'.gif');
    end;
  • Второй случай сложнее, поэтому лучше действительно воспользоваться советом от Beermonza.
В заключении хотел бы привести свою систему 2D RPG:
Пока что основные составляющие это: игрок и карта. Теперь сама реализация:

Тип игрока:
Код:
TPlayer = packed record
// Координаты.
X, Y: Byte;
end;
Работа с картой:
Код:
// Банк текстур.
Bank: array[1..256] of TBitmap;
// Вся карта.
FullMap: array[0..190,0..190] of Byte;
// Часть карты, выводимая на экран.
ScreenMap: array[0..19,0..19] of Byte;
В событие FormCreate происходит загрузка текстур, потом карты. В зависимости от координат персонажа происходит заполнение ScreenMap текстурами из Банка.

Управление персонажем: при нажатии на кнопку W вначале происходит проверка на проходимость и не занятость каким-либо НПС клетки выше персонажа. Если эта клетка свободна, то y координата игрока уменьшается на одну единицу, дальше отрисовывается анимация перемещения модели игрока вверх.

Я сейчас все это только начинаю реализовать, и кое-что пока не совсем понятно. Поэтому прошу объяснить с простыми примерами о том, как значения из FullMap перевести в ScreenMap в зависимости от координат игрока.

И прошу, если у меня в коде или в рассуждениях есть ошибки или не рациональные подходы, пожалуйста, напиши об этом.

Последний раз редактировалось Alexan-Dwer; 16.03.2010 в 23:33. Причина: Ошибка
Alexan-Dwer вне форума Ответить с цитированием
Старый 16.03.2010, 23:29   #447
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Вот тут ошибка:

Код:
Bank: array[1..256] of TBitmap;
...тип Byte, который используется в массивах FullMap и ScreenMap имеет строгие границы: 0 - 255. Текстура 256 никогда не появится в игре. Вот так правильно:

Код:
Bank: array[0..255] of TBitmap;
Если набор текстур столь незначительный, что его кодом может быть 1 байт, то и нет смысла называть текстуры по именам, ...достаточно составить таблицу, где каждой текстуре присвоен номер от 0 до 255, ...и игра и редактор будут пользоваться этими кодами, а редактор и списком, чтобы было понятно, что за текстура устанавливается на карту.

По идее ScreenMap не нужен в принципе. Достаточно иметь 4 переменные, которые хранят диапазон выборки клеток карты. Две отвечают за сдвиг от начата карты по-X и по-Y, остальные две размер области экрана, т.е. ширину и высоту в клетках (у вас обе по 20).

Я так понимаю речь идет о классическом расположении персонажа в центре экрана?
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 16.03.2010, 23:46   #448
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Сообщений: 136
Стрелка

Цитата:
Вот тут ошибка
Спасибо

Цитата:
Я так понимаю речь идет о классическом расположении персонажа в центре экрана?
По сути да, если я правильно понял вашу мысль. Персонаж может появиться в любом месте, потом при движении смещается по центру, а когда карта заканчивается, он оказывается у ее краев.

Цитата:
По идее ScreenMap не нужен в принципе. Достаточно иметь 4 переменные, которые хранят диапазон выборки клеток карты.
А делать эту выборку так — увеличивать соответствующие переменные, отвечающие за сдвиг и по ним рисовать на canvas?
Alexan-Dwer вне форума Ответить с цитированием
Старый 17.03.2010, 15:07   #449
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Очень просто.
Вот персонаж в начальной клетке K(0,0), если он центрируется на экране, то мы четко знаем сколько клеток карты нужно, чтобы положение персонажа было в центре. Экран 20х20 - уже ошибка, числа должны быть нечетными. Пусть 19х19, тогда диапазон выборки будет от 0 до (19-1)/2. Теперь для координаты X, ближе к коду. Если сдвиг это DispX, а количество клеток в экране ScreenW, то цикл выборки организуется так:

Код:
For X := 0 to ((ScreenW-1) div 2)+DispX do
  Begin
    ...
  end;
Эта выборка справедлива для координаты X персонажа, до значения (ScreenW-1) div 2, после него выборка станет такая:

Код:
For X := DispX to ScreenW+DispX do
  Begin
    ...
  end;
До того как будет производится выборка идут условия, которые определяют два аргумента цикла X1 и X2, поэтому код видоизменяется:

Код:
If DispX <= (ScreenW-1) div 2 then
  Begin
    X1 := 0;
    X2 := ((ScreenW-1) div 2)+DispX;
  end
else
  Begin
    X1 := DispX;
    X2 := ScreenW+DispX;
  end;

For X := X1 to X2 do
  Begin
    ...
  end;
Для Y аналогично. Disp(X и Y) - переменные, управляемые алгоритмом смещения персонажа, в тот момент когда он переходит на очередную клетку значения переменных увеличиваются или уменьшаются на 1, точнее к ним прибавляется скорость смещения 1 или -1 (смотрите в теме примеры, уровень грубого смещения).

По поводу отображения. Оно теперь не привязано к координатам начала 0,0, а будет плавающим:

Код:
Form1.Canvas.Draw((ScreenW-(X2-X1))*TexW, (ScreenH-(Y2-Y1))*TexH, Buf);
TexW и TexH - размеры текстуры клетки карты в пикселах. Данный пример сильно упрощен из более сложного, в котором персонаж дойдя до края карты отрывается от центра и может свободно перемещаться по углам, карта при этом всегда рисуется во весь экран, а не так как например в Героях Магии и Меча 2-3. Возможно есть недочеты, вы исправите их, если примените код.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 04.05.2010, 18:51   #450
Манжосов Денис :)
Участник клуба
 
Регистрация: 29.01.2008
Сообщений: 1,039
По умолчанию Помогите с редактором

Объясню суть вкратце: есть редактор, на мой взгляд, с не совсем удобным интерфейсом, но лучше придумать не могу. Что меня смущает: если я хочу, чтобы выбранный объект создавался как препятствие, я щёлкаю на галочку "Препятствие". К примеру, добавляю квадрат как препятствие, второй квадрат как не препятствие(снимаю галочку), третий как препятствие и т.д. Хочется придумать для этой операции вариант получше. Далее...Далее нет смысла объяснять, это очень долго. Во вложении exe редактора. Мне важно ваше мнение, как сделать программу удобней.
Небольшая инструкция:
- Чтобы добавить объект, нажмите на + рядом с пустым полем и выберите любое изображение на вашем компьютере
- Чтобы прекратить расстановку объектов по карте, нажмите "Сброс"
- Чтобы выделить объект, нажмите на него. Вы можете перемещать объект по карте, с помощью стрелок. Чтобы сбросить выделение, нажмите на пустую область карты или на "Сброс"
- Чтобы удалить объект, выберите объект и нажмите Delete
- Чтобы ставить объекты как препятствия, щёлкните на галочке "Препятствие"
- Чтобы создать новую зону, нажмите + рядом с надписью "Зона"
- Чтобы удалить текущую зону, нажмите -
- Чтобы перемещаться по зонам, используйте << и >>
Надеюсь, что вы поможете мне. Спасибо
P.S. Просьба не пользоваться меню - оно не до конца сделано и могут возникнуть проблемы.
Вложения
Тип файла: rar WorldEdit.rar (226.1 Кб, 43 просмотров)
Манжосов Денис :) вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хорошие уроки Render Общие вопросы Delphi 9 15.09.2012 07:13
Акцесс вопросы новичков Yaga Помощь студентам 4 02.06.2008 00:16
Учебники для новичков в програмировании Рар Общие вопросы Delphi 6 08.01.2007 08:07