PSP рогалиг

Закрытые или заброшенные проекты, не состоявшие в Клубе, но имевшие ветку на форуме.

Модератор: Jolly Roger

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 23 июл 2009, 11:57

Хе хе, сделал размер тайлов 16х16 пикселей.
Ничего так, хорошо получилось!
Все прекрасно видно.
Правда глав герой чуток большой, и он полностью непомещается, голова вылезает. но это нифига не напрягает.
Оставляем с так.
16х16 будет жить.
Вложения
Mariner_16_16.zip
Тайлы 16 на 16 пикселей
(84.31 КБ) 143 скачивания

Аватара пользователя
Maelstrom
Мастер
Сообщения: 2062
Зарегистрирован: 26 ноя 2006, 14:19
Откуда: г. Усть-Кирдык
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Maelstrom » 23 июл 2009, 14:55

1. Количество тайлов по вертикали и горизонтали должно быть одинаково. Нет смысла делать обзор по горизонтали больше. Лишнее место используй под всякую полезную информацию про героя.
2. Под место для строки сообщения тоже неплохо бы подумать.
3. Одно нажатие кнопки должно приходить к одному шагу. А то нажал кнопку - а герой уже в другом конце карты.
4. Время генерации карты настораживает. Это ж пока только пустая карта, что же будет потом...
Айв кнгенгах Йог-Сотот

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 24 июл 2009, 04:54

Экран у зызки маленький, думаю будет немного странно если не использовать весь размер.
Строка сообщения, будет вынесена в отдельный класс BarMessage, он будет прорисовываться внизу экрана, в виде прямоугольной области с 50% затенения основной карты (полупрозрачность типа) в нем будет писаться сообщения. Размер этого BarMessage по умолчанию будет три строки, если текста будет слишком много, то он на время просмотра увеличивается в размерах. Если текста там до неприличия много, то будет работать скроллинг.

Еще будет панелька с названием BarInfo. Она будет тоже полупрозрачная, в ней будет показыватся время и календарь. Состояние героя. Располагаться панелька будет в правой стороне экрана, и занимать площадь будет примерно 1/4 экрана.

Про "одно нажатие" вы правы, в релизе так оно и будет. Сейчас реализовано непрерывное нажатие, чтобы отлаживать было удобно. У меня код игры, и код работы с железом зызки полностью независим, оттого переделать управление будет вообще без проблем.

Карта действительно генерится до безобразия долго... там тоже нужно оптимизировать, много оптимизировать. Но я на этом незацикливаюсь, сейчас невкартах суть.

-----
На данный момент занимаюсь тем что полностью переделываю карты.
Изначально был базовый класс MapObject с виртуальными функциями virtRender virtGenerate, от этого класса, уже создавались MapCastle и другие карты.
В котором было не только отрисовка на экране, но и генерация.
Этот способ оказался мне не эффективным.
Ибо когда стал реализовывать фабрику карт (которая создает карты загрузкой из карты памяти либо генерацией). Понял, что лучше сделать один тип карты. Но наполнение этой карты сделать разным.
Немного сумбурно получилось.

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 24 июл 2009, 11:06

Ехх. начал усе переделывать что связано с картами.
меняем архитектуру, теперь использую паттерн Builder.
Ибо карта, недолжна знать, откуда она берется (генерация, либо загрузка). Вообще карта ничего недолжна знать, ее дело - только отрисоватся на экране.
--
теперь думаю, как Bulder должен узнавать, когда генерить карту, а когда загружать ее с файла?
Может все карты уникально проименовать?
И в памети хранить только само дерево карт с индификаторами. далее буилдер смотрит, если в файле есть карта с таким индификатором, то загрузим. иначе, создадим.
Карты, в которых нет пользователя, выгрузить из памяти, но предварительно записать в файл.

-
дерево карт (все вместе получается миром) ветки переходы удерева это порталы между картами.
собственно дерево "растет" (генерится) автоматом, взависемости от сюжетной линии.
Как вам такая идея?

Аватара пользователя
Anfeir
Сообщения: 711
Зарегистрирован: 14 дек 2007, 09:29
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Anfeir » 27 июл 2009, 07:13

Очень тонкий намек: "Как вам идея - все имена монстров хранить в переменных? Или еще мега-идея: всех монстров - зафигачить в связный список!"

А по сути, проще надо быть. На парадигмах ООП "каждый объект сам себя отрисовывает" и т.п. тоже заморачиваться _слишком_ не стоит. Можно:
а) определить, что хочешь получить как конечный результат,
б) определить, какие механизмы при этом используются (практически безотносительно к конкретному языку или даже к ооп, просто - какая должна быть логика на пальцах. На пальцах но крайне четко и строго.),
в) исходя из этого уже определить средства языка, на котором вы пишите, и способы хранения данных на диске.

Если два типа карт, - один генерится, другой - хранится полностью, то храним на диске 1)тип карты и 2)тип генерации / либо тайлы. Загрузить по этой инфе можно из файла? можно. Объекты нужные в памяти создать можно? Использовать их тоже можно. Если логика простая, зачем все усложнять в 20 раз? Если "карта сама себя рисует" чем-то не нравится, можно сделать карту пассивной структурой, которую использует для отрисовки какой-нибудь РисовательКарт.

А то наоборот получается: паттерны, идентификаторы, деревья, а потом думать начинаешь, что с этим со всем делать. Кроме всего прочего, это будет не дерево, к примеру, у дерева нет замкнутых переходов, а тут их полно может быть. Чтобы определиться, какие структуры использовать, надо много что прикинуть- сколько будет карт, каков размер карты в памяти, и т.п. вариант - сделать объект Карта, все карты одного размера, внутри карты уже информация на то, что ей нужно (скажем, указатель на массив тайлов), все карты хранить в одном массиве. У карты есть айдишка, айдишка - это индекс карты в массиве карт. Вместо айдишек можно использовать указатели, но сразу стоит подумать о том, как вы это хозяйство будете save/load-ить при загрузке-сохранении игры.
Может я и не прав конечно, сильно подробно не думал )

Аватара пользователя
Anfeir
Сообщения: 711
Зарегистрирован: 14 дек 2007, 09:29
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Anfeir » 27 июл 2009, 07:20

Yozka писал(а):Ибо карта, недолжна знать, откуда она берется (генерация, либо загрузка). Вообще карта ничего недолжна знать, ее дело - только отрисоватся на экране.
Почему ж нет-то?
Карта, как объект, может хранить информацию о себе: свой тип (hand-made, generateable), какой-нибудь подтип (тип генерации) и т.п. Это не сколько информация о том, откуда она берется, сколько информация о внутренней структуре. Если не в объекте карты хранить информацию о структуре карты, то где ? :)
А исходя из этой информации уже хранить на диске.

class Map
{
public:
enum Type {MAP_TILES, MAP_GENERATE};

unsigned char type;
unsigned char subtype;
Tile *tiles; // array of tiles, NULL for generateable карт.
};

Или я что-то не понял?

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 27 июл 2009, 08:33

Здравствуйте!
Даже и не знаю что вам ответить, ибо читал этот форум, наткнулся на ветку, где обсуждают что лучше ООП либо плоский код. Ну нафиг, холивар тут разводить.


Монстры и другие объекты (ну монстр это тотже игровой объект, только он может перемещаться) хранятся в списке. Список на карте.

С картами все прорисовывается.
К карте прикрутил список тем.
Темы - мощная вещь получается.

Немножко отступления. Что подразумеваю под темой.
Например, генератор сценария, который создает карты.
Сценарий подготавливает тему следующего содержания:
1. создать карту среднего размера.
2. заполнить карту подьземельем.
3. разбросать рандомно денюжки.
4. разбросать рандомно сундуки с вещами
5. расставить 10 ловушек
6. рандомно поставить лестницу
7. рядом со входом поставить 3 монстра
8. рядом с лавай поставить 2 огнедыщаши монстра


Дальше эта тема, прикручивается к карте и все.
Когда карту нужно сгенерить, она генирится согласно установленной теме.
Как было сказано выше, саму тему создает «генератор сценарий» в зависимости от сюжета.
Вооот туто и разворачиваются все прелести ООП. Выполнение тем, реализуются без единого switch if.

Кстати, «тип генерации» в карте, это именно «темы», только, темы получаются более гибкие.

Вот крпимеру, кусок кода, который создает у меня карту

CPersonage *pPersonage = new CPersonage;//создадим пользователя
CMap * pMap = new CMap;//создадим пустую карту
//к карте прикрутим темы
new CThemeSetSizeNormal(pMap); //устанавливаем размер карты
new CThemeMapCastle(pMap);//заполняем карту комнатами замка
new CThemePersonageMove(pMap, pPersonage);//привязка персонажа к карте

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

Сейчас работаю над лестницами и порталами (одно и тоже). Далее думаю можно и весь проект выложить сюда. Может комунить интересна моя реализация.

----------
На выходные маялся с памятью на зызке.
Палево! Мне дается всеголишь 2.6 мега.
Это примерно 10 карт!!
Уменьшаем размер карт.
Переписал менеджер тайлов. Теперь когда нехватает памяти, менеджер выгружает неиспользуемые тайлы. Но если тайл понадобится, то он сново загружается.


Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 29 июл 2009, 12:04

Сделал лестницы между картами.
Теперь делаю загрузка - выгрузка карт.
Далее:
1. "туман войны" (хмм хотя он сейчас не очень актуален)
2. Двухкнопочное управление.

Аватара пользователя
Anfeir
Сообщения: 711
Зарегистрирован: 14 дек 2007, 09:29
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Anfeir » 29 июл 2009, 16:09

Главное, НЕ забросить, это по жизни самая серьезная угроза молодому проекту.
Через силу конечно тоже работать смысла никакого нет, поэтому энтузиазм надо использовать :) Постоянным он никогда не держится, это нормально.
В принципе, даже если забросить, то потом можно вернуться, посмотреть, что такое было напридумано. Смысл в этом можно найти -- как бы наивно прошлые проекты не выглядели спустя время, они всегда создавались "от души" и в них что-то было интересное обязательно. А для профилактики (мое мнение) таки можно четко обозначить первый реальный результат - играбельную версию, что там будет, и какие фичи будут только потом (и реализовывать их соотв. потом). Критерий - какая-никакая завершенность, лучше мало фич да полностью реализованных, чем дырка в wilderness или фичи которые есть но недоделаны или глючат. Т.к. имхо, есть определенный порог в процессе разработки, перейдя который уже забросить намного сложнее, чем завершить ). Обычно это какой-то реальный результат, который можно пощупать руками, ну и при этом есть ощущение, что движок более-менее стабилен и его можно развивать дальше, не должно быть такого - "гляжу в код, руки опускаются". Бискап вон движок для Jade не менее 3х раз переписывал уже. Поэтому нельзя жалеть сил на тот код движка, на котором держится все "наполнение". Ну и главное, это удовольствие от процесса, а не поддержка юзеров на форуме, от них себя в зависимость тоже ставить нельзя. Молодые проекты всегда очень уязвимы. Про проект в разработке всегда можно сказать - это Авно, причем, это будет субъективное чье-то мнение, но, скажем, про мажорный рогалик такое уже не скажешь. Ну и быть готовым к неожиданным проблемам. Скажем, если создать условие для сцены боя между разными монстрами, увеличив их количество по сравнению с обычным в 100 или 1000 раз (критерий - система не виснет наглухо) и уйти спать, вот если не повиснет, тогда...

На философию чтот потянуло... :)

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 30 июл 2009, 05:26

Есть такое…
Этот рагалик пишу, чтобы откатать некоторые моменты работы с зызкой.
Что я сейчас делаю с рогаликом?
Рутина, по сути один рутинный код. Связанный с обработкой карты, загрузка выгрузка, как она будет сидеть в памяти итд. Для меня это не интересно.
Но я это делаю, иначе без этого, нормальный рогалик не написать.
Более интересные для меня направления это – реализация квестов, АИ жителей. И это я хочу оставить на потом.
Не знаю насколько меня хватит, энтузиазм пока есть.

-
Задумался над форматом хранения номеров тайлов в карте.
Сейчас клетка карты у меня следующей структуры:
WORD flag – тип клетки, тип задается побайтно.
WORD Tile1 – номер тайла, основной фон
WORD Tile2 – наложенные тайлы, на основной фон, например, «картина» в магазине. (статические объекты)
WORD Tile3 – тайлы, для отрисовки следы крови, следы от пуль, разрушения. (тоже ресуется поверх, с прозрачностью итд.)

В итоге, одна клетка занимает 8 байт. Если карта 128х128 то будет вокурат 128кбайт. Когда на зызке мне доступно всего 2.6мега. 128кб ооочень много для карты. Ибо в памяти должно висеть как минимум 10 карт (чтобы обрабатывать там жизнь монстряков)
Решил изменить структуру.
Теперь выглядить она будет вот так
BYTE flag
BYTE TileIndex1
BYTE TileIndex2
BYTE TileIndex3

Флаг уменьшим до 1 байта
Теперь храним не номер тайла а иго индекс в подготовленном массиве, в массиве же буду хранить номер тайла. Массив виде WORD TileNumber[256]
Теперь чтобы отрисовать. Нужно в маcсиве взять номер спрайта типа Tile = TileNumber[TileIndex1]; И отрисовать тайл с номером tile.
В итоге что получается:
Клетка занимает 4 байта , елси карта размером 128х128 то она в памяти будет весить 64кб. + 1.5 кб на массивы индексов.
Таким подходом можно уменьшить карту в два раза.
Ну и конечно, в фале карту нужно хранить не с индексами, а с номерами тайлов. Ибо индексы должны генерится автоматом, но это уже дело кода. Самое главное это идея.

Аватара пользователя
Anfeir
Сообщения: 711
Зарегистрирован: 14 дек 2007, 09:29
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Anfeir » 30 июл 2009, 06:56

а разве flag нельзя однозначно определить по TileIndex1? если можно, то незачем хранить для каждой клетки.
На tile2 и tile3 тоже можно при желании сэкономить - сделать одно и/или другое не тайлами, а отдельными объектами (особенно если это хозяйство планируется чтобы исчезало со временем), тогда тратиться на место в клетке для них не надо. И как будет выполняться кстати задача: "выяснить, какие объекты (монстры, вещи, и тп) есть в данной клетке?

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: [test] PSP рогалиг, нужно потестить

Сообщение Yozka » 30 июл 2009, 07:43

«а разве flag нельзя однозначно определить по TileIndex1?»
Нельзя. Ща попытаюсь объяснить.
Есть секретные ходы, которые мы видим как кирпичи, но насамом деле сквозь них можно пройти. Также, непроходимых тайлов может быть много, это кирпичи, горный массив, табуретко итд. То есть мне придется каждый раз проверять ооооччень большой список тайлов на предмет что можно пройти или нет.

Также во флаге хранится «видемые» области, либо области которые мы уже обследовали.
Вот описание флага:

Код: Выделить всё

enum
{
    /*тип клетки на карте
    */
    bitDoor     = 0x01, //b00000001 - (0) клетка не проходима, дверь закрыта, никто непройдет
    bitBrick    = 0x02, //b00000010 - (1) клетка не проходима (кирпичи)
    bitRock     = 0x04, //b00000100 - (2) клетка не проходима вообще (бетон-камни)
    bitWater    = 0x08, //b00001000 - (3) вода водичка, можно только плыть или лететь
    bitLava     = 0x10, //b00010000 - (4) лава, можно только пролететь

    bitOpenRegion   = 0x20, //b00100000 - (5) обследованная (открытая) область
    bitVisible      = 0x40, //b01000000 - (6) видемая область
}
В итоге я разделил информацию, которая описывает отображение на экране, и информация виде флага для обработки взаимодействия игрока и монстряков с картой.


«На tile2 и tile3 тоже можно при желании сэкономить - сделать одно и/или другое не тайлами, а отдельными объектами (особенно если это хозяйство планируется чтобы исчезало со временем),» Правильно, так оно и будет реализовано, только для интерактивных объектов, например к огню, который современем может погаснуть.
Эти дополнительные тайлы нужны для обрисовки статической информации, к ним относятся прежде всего капли/лужи крови. Тайл виде полупрозрачной паутинки, чтобы можно было показать что карта пустует и заросла пылью. Можно конечно отдельно нарисовать тайл виде «поношенный со временем и сломанный который зарос мхом» но это трудоемко (много рисовать тайлов).


« И как будет выполняться кстати задача: "выяснить, какие объекты (монстры, вещи, и тп) есть в данной клетке?» очень интересный вопрос.
Есть ирархия классов, которая реализует этот момент:

В начале всего, сделан список виде класса
CItem – это узел списка.
Списком управляет CListItem.
В нем есть такая реализация как Add, delete, next и другие штуки для работы со списком Item

Далее сделан класс игровых объектов
CObject он унаследован от Citem
В этом объекте есть базовые свойства, такие как на какой карте расположены, и координаты. Для этого у меня создана структура CPointMap;
Также есть вертуальные функции отрисовки и установку на карту


От этого базового объекта уже пляшут другие игровые штуки. Такие как монстряки, предметы итд.

Собственно на карте есть CListItem в котором лежат все игровые объекты и монстры.
Теперь, когда мне нужно выяснить что находится в данной клетке нужно выполнить код вроде этого:

Код: Выделить всё

CObject * obj = монстры_объекты.getObject(координата);



//реализация кода вот такая
CObject * CObjectList::getObject(const CPoint &ptPosition)
{
    CObject * objFind = NULL;
    backup();
    setFirst();
    int iCount = getCount();
    for (int i = 0; i < iCount; i++)
    {
        CObject * objItem = (CObject*)item();
        if (objItem->getPosition().pt == ptPosition)
        {
            objFind = objItem;
            break;
        }
        next();
    }
    restore();
    return objFind;
}
Если нам нужен не один объект, а несколько, (ведь на одной клетке может находится дочерта всяких объектов) то возвратим связный список найденных объектов. Сейчас вместо кода стоит заглушка.

Конечно, пока поиск сделан тупым перебором, что не очень эффективно.
В будущем, этот кусок кода перепешу, данные в списке будут отсортированы и будет реализован бинарный поиск. Что должна скорость возрасти на большой порядок.

Relict
Сообщения: 59
Зарегистрирован: 05 сен 2008, 13:53
Откуда: Kursk

Re: [test] PSP рогалиг, нужно потестить

Сообщение Relict » 30 июл 2009, 10:09

Все предметы в одном списке, затем ищем что в клетке сравнивая по координате?
При отображении на экране вызываем эту функцию для каждой клетки видимой на экране?

Аватара пользователя
BreakMT
WANDER Team
Сообщения: 920
Зарегистрирован: 27 ноя 2006, 12:16

Re: [test] PSP рогалиг, нужно потестить

Сообщение BreakMT » 30 июл 2009, 10:32

На выходные маялся с памятью на зызке.
Палево! Мне дается всеголишь 2.6 мега.
Это примерно 10 карт!!
А ты что - все карты хранишь в памяти? Зачем?

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость