Просмотр полной версии : uint идентификаторы
Appleman
30.05.2018, 18:22
Решил выйти на новый уровень и попробовать отказаться от строковых идентификаторов там, где это возможно. В частности, делать все игровые предметы на uint-идентификаторах. Пока получается как-то тяжко. Бог с ним, что теперь в консоли появляются абсолютно не информативные сообщения типа "Надеваем предмет ID 114576", можно и к Модели языковой пакет прикрутить и название на русском сразу подцеплять, не велика беда.
Главная проблема - обеспечить уникальность этих самых идентификаторов. А когда они ещё и записаны в шестнадцатиричном представлении, то даже визуально их сопоставлять тяжко.
Пока выкрутился так. Нажимаю Ctrl+K, открываю палитру. Для первого элемента беру какой-нибудь цвет типа RGB 175:175:175. А для каждого следующего увеличиваю яркость с шагом 5 и получаю новое uint-значение. Но это, по-моему, порнография.
Что посоветуете? Спасибо.
undefined
30.05.2018, 18:28
делать как в java: первый айдишник 0,второй 1 и т.д.
Скачай консоль (https://github.com/junkbyte/flash-console) для проекта, очень удобная. Можно даже в рантайме произвольный код выполнять, функций дёргать, смотреть состояние объектов. Ещё у флеша есть дебаггер с полноценными точками останова, незаменимая вещь. Так, прост, вдруг ты ещё не использовал.
пс. Айдишник должен быть уникальным, а не красивым и понятным человеку! Начинай нумерацию с 1, зачем такие сложности. Ноль лучше не юзать, может пригодиться, например, для обозначения отсутствия сущности (null).
Appleman
30.05.2018, 20:26
пс. Айдишник должен быть уникальным, а не красивым и понятным человеку! Начинай нумерацию с 1, зачем такие сложности. Ноль лучше не юзать, может пригодиться, например, для обозначения отсутствия сущности (null).
Спасибо. Вот не поверишь, мне в натуре понравилось, как шестнадцатиричные числа выглядят - так красиво и "загадочно", точно как у крутого хакера ;)
Пока надумал наваять статический класс-генератор, который наплодит uint-ов по порядку, забьёт всё в массив и будет по одному выдавать. И всё.
А мне 16x числа напоминают дизайнеров. Они цвета в нём обычно хранят. Смотришь на какой нибудь 0xFF0000 и сразу видишь женщину в красном красный цвет. :mosking:
ZergMaster
31.05.2018, 00:59
Вот не поверишь, мне в натуре понравилось, как шестнадцатиричные числа выглядят - так красиво и "загадочно", точно как у крутого хакера ;)
Оооо, дааа, верю. Я тоже так раньше программировал. Чтобы выглядело круто и сложно и, желательно, никому не понятно. Боже, сколько же от этого было проблем! Сейчас наоборот, стремлюсь, чтобы код был предельно прост и как можно более примитивен. Не чураюсь дописать лишнюю функцию в угоду понятности, по пол часа думаю над названиями переменных и т.п. Сильно проще стало жить.
caseyryan
31.05.2018, 09:32
Я вот как-то не верю, что там такое количество инвентаря, что аж строковых констант не хватит.
Я бы не рекомендовал использовать никакие uint идентификаторы и уж тем более автогенератор айдишников. Ты потом задолбишься это отлаживать, если что-то пойдет не так, особенно если это еще и в базу пишется, которую потом потребуется рефакторить. Делай всегда так, чтобы ты сразу мог понять что происходит.
Вот есть у тебя, допустим, плащ, который добавляет 50% защиты, и другой плащ, дающий 100% защиты.
Называешь их cloak_50 и cloak_100 соответственно. Можешь туда и какие-то другие параметры добавить.
Если у тебя есть 2 плаща, которые дают 50% защиты, но отличаются цветом, то можешь написать так
cloak_50_green / cloak_50_red и т.п.
Appleman
31.05.2018, 10:05
Старый анекдот:
- Мальчик, ты пионер?
- (гордо) Да!
- Да?!
- (испуганно) Н-нет...
- Нет?!!!
- (в истерике) Ну я не зна-а-а-ю!
Вот так же и с идентификаторами. В соседних ветках меня всей ватагой застыдили, вот типа от Tails:
В принципе, это норм, только класс я бы назвал CharacterProperty и значения использовал не строковые, а целочисленные. (Int, Uint). Строки - жирные и тормознутые.
:umnik2:
caseyryan
31.05.2018, 10:21
Надо понимать где строки тормознутые, а где нет. Если у тебя что-то там со строками делается миллион раз за кадр, то да, лучше числа считать. А для идентификаторов "тормознутость" вообще не имеет значения, зато в отладке числа - это полнейший геморой. Да ты уже и сам это понял, судя по началу темы
А автогенератор использовать нельзя потому что при добавлении чего-то не в конец списка, все айдишники пересчитаются и получится каша. Допустим у игрока был меч с одним айди, а перед ним был молот с другим айди. Айдишники пересчитаются, и окажется, что у игрока уже молот, вместо меча, к примеру.
Appleman
31.05.2018, 12:14
зато в отладке числа - это полнейший геморой. Да ты уже и сам это понял, судя по началу темы
На точняк! Спасибо, камрад, успокоил мою душу. Сейчас с чувством облегчения верну обратно строки! :)
А автогенератор использовать нельзя потому что при добавлении чего-то не в конец списка, все айдишники пересчитаются и получится каша. Допустим у игрока был меч с одним айди, а перед ним был молот с другим айди. Айдишники пересчитаются, и окажется, что у игрока уже молот, вместо меча, к примеру.
Ну я думал завести в классе-справочнике константы идентификаторов и при запуске программы один раз раздать им значения из генератора, а потом уже до самого конца их использовать:
// В классе Model IDs
static public const TEST_ID: uint = IDGenerator.generate();
// В классе AllItems
var i:Item = new Item(TEST_ID)
caseyryan
31.05.2018, 12:42
Ну я думал завести в классе-справочнике константы идентификаторов и при запуске программы один раз раздать им значения из генератора, а потом уже до самого конца их использовать:
Я понял. Об этом и говорю. Вот этот код у тебя будет выполняться при каждом запуске программы. То есть хоть ты и задал это как константу, но по сути это динамическое значение. Если в твоем генераторе поменяются какие-то данные (а они по-любому поменяются), ты получишь каждый раз разные ID для одних и тех же айтемов. Если задача просто в том, чтобы у разных айтемов были уникальные айди, то ок, все будет работать. А если задача сохранять что-то в базу данных, то это фиаско, так как в базе будут одни айдишники, а в программе уже другие при каждом запуске.
Я бы лучше их руками вписал, чтобы они были реальными константами и никогда не менялись
Appleman
31.05.2018, 16:15
Вот! Я как раз хотел ещё спросить в продолжение темы. Смотрите. Всё, что мы сейчас обсуждаем - это идентификаторы в Модели. Но у наших объектов ещё есть ID для Вью, плюс в силу специфики моего жанра (текстовый RPG/квест), ещё и ID подбора фраз для языковой системы.
Изначально я сразу назначал строковые ID и использовал их везде (Модель, Вью, язык) в неизменном виде. Потом начались усложнения. Например, в зависимости от пола ГГ фраза может звучать по-разному: "пришёл"/"пришла" и т.д. Я начал к идентификаторам добавлять пол персонажа (значение uint). Далее, по мере усложнения Модели и добавления функционала, я понял, что некоторые мои ID уже не так хорошо отражают суть и требуют уточнения. Но чуть только я их тронул, сразу "поехал" язык. Короче, я запутался.
В связи с эти подумалось завести класс-посредник, где в огромном справочнике будут указаны соответствия идентификаторов Модели и, например, Вью. Плюс туда же можно добавлять какую-то логику. Вот маленький пример из класса IconIDs, который хранит идентификаторы иконок статус-эффектов и синхронизирует их с ID Модели:
static public function getIconID(statusID: String, genderID: uint) : String
{
if (_iconsSync[statusID + genderID as String]) return _iconsSync[statusID + genderID as String];
else if (_iconsSync[statusID]) return _iconsSync[statusID];
}
В общем, думаю, суть вопроса понятна. Как этот бардак организовывать!?
По поводу он/она, вот, буквально на днях написал простой, текстовый интерпретатор. Суть его работы в том, что он обрабатывает скриптовые вставки в тексте. Наподобие: "Сегодня {%sex|он поехал|она поехала%} на работу." (Жирным выделена скриптовая вставка) После обработки, на её место подставляется "он поехал" или "она поехала".
Если интересно, могу скинуть. Там всего один класс, правда, написан на haxe.
А мне 16x числа напоминают дизайнеров. Они цвета в нём обычно хранят.
Ну да, программисты-то хранят цвета в виде "Lite Pale Veronese Green Earth"..
"начинай с 0, потом 1.."
Освежу в памяти, как кодируется цвет в HEX:
E2F0AE это E2.F0.AE, то есть R.G.B. Хотя вцелом это какое-то астрономическое число в десятиричной системе, здесь используется именно кодирование, то есть значение знака зависит от его позиции. В каждой из трех позиций находится число "всего лишь" от 0 до 255, то есть 256 значений.
Итак, у нас есть реестровые номера вида 00.11.22.
256 разделов по 256 классов по 256 подклассов.
Например, так: Оружие.Мечи.Эльфийский меч. Или: Броня.Кирасы.Мифриловая кираса.
А если мало трех разделов, то флэш поддерживает и 32 бита (ARGB для цветов), так что HEX-ID может содержать 4 указателя разделов.
А то навыдумывали тут, от ноля и до столба, генератор случайных чисел и т.п.
Не вводите людей в заблуждение. Упорядочить можно все, было бы желание. Ну, и кучу можно создать из всего, а як же шь.
Я изначально был за то, что-бы организовать реляционную модель данных, что-бы все данные приложения и их связи были в одном месте, в едином виде, разложены по таблицам. А не так, часть по классам в виде наследования, часть в виде огромных стеков условий, часть ещё каким нибудь чудным образом захардкодена. Это потом плохо заканчивается.
Ну как бы я тоже в самом начале рекомендовал такой подход, объясняя тем, что по числовым идентификаторам можно легко создавать таблицы (массивы), а не строковые списки (по алфавиту чтоли будешь искать?). Если использовать раздельный HEX, то можно организовать все в массив 256 ячеек, в кождой ячейке которого массив 256 ячеек, в каждой ячейке которого.. и тд. И сущность с ID 0xE2F0AE будет доступна как ITEMS[0xE2][0xF0][0xAE]. При этом сами вложенные массивы можно расписывать отдельно и собрать конечную библиотеку "в конце", типа
const SWORDS:Array = [ElvenSword, GlassSword, IronSword, RustIronSword, ImperialSword ..];
const WEAPONS:Array = [SWORDS, ARROWS, BOWS, KNIFES, MACES ..];
const ITEMS:Array = [ARMORS, WEAPONS, CLOTHS, FOODS, JEWERLY, TOOLS, MATERIALS, DRINKS ..];
(ну, более упорядоченно по смыслу конечно)))
Но тогда не было понятно, нужно ли такое в данной игре. Да и сейчас непонятно))
Appleman
31.05.2018, 23:13
Wolsh, не ну это круто конечно! Я за уже почти 15 лет плотного занятия 3D-графикой никогда даже не пытался в таком ключе интерпретировать систему записи цветов RGB. Вон он - образ мыслей программиста.
Уточни, пожалуйста, другое. В какой-то теме ты уже приводил как раз такую запись значения и все уже обсуждали цвета. Но оно было введена "от руки", т.е. напрямую что-то типа 0x604181. И это не было результатом работы какого-то кода. Значит ли это, что подобный подход - использовать вложенные массивы-справочники - реализуется не непосредственно в создаваемой программе, а где-то "на стороне"?
И ещё за общими рассуждениями замылился мой второй вопрос. Что думаете на счёт использования справочников синхронизации между Моделью и Вью?
Добавлено через 13 часов 3 минуты
Друзья, я с позволения конкретизирую вопрос. Давайте посмотрим под углом любимой всеми нами MVC на конкретном примере :)
Вот смотрите. У меня есть такая штука как варианты действия. Например, если игрок выбрал "ударить", то следом игра его спрашивает, как: "слабо", "сильно", "со всей дури". Это экземпляры отдельного класса. Содержат модификаторы к значениям действия (если "сильно", то точность падает, а усталость возрастает и т.п.). Чтобы выводить их в диалог, предусмотрены строковые ID, которые передаются во Вью в метод формирования меню. Он лезет в класс LanguagePack и вытаскивает по ID конкретные фразы на нужном языке.
Чтобы не утонуть в многочисленных фразах, языковой файл иерархически разбит на секции. ID секции принимается первым обязательным параметром метода подбора фразы. Таким образом, для подбора конкретного лэйбла кнопки с вариацией запрос выглядит следующим образом:
var label: String = LanguagePack.getSinglePhrase(LanguageIDs.SECTION_AV_BUTTONS, variation.variationID);
Теперь я добавил игровые предметы. И потребовалось сделать принципиально новые вариации действий. Например для действия "лечиться" предстоит выбрать, чем: боярышником или коньяком. В Модели всё получилось прекрасно: унаследовался от VariationEntity и переписал геттер, чтобы вместо фиксированного перечня он подбирал вариации по предметам нужного типа из наличия. В общем, всё "срослось". А вот во Вью затык! Ведь лэйбл для фразы теперь нужно подбирать не из секции наименований вариаций (SECTION_AV_BUTTONS), а из секции названий предметов (SECTION_ITEM_NAMES). Вью "не знает" и "не может знать" этого.
Альтернативы мне видятся такие:
1. Инкапсулировать подбор лэйбла прямо в классе вариации. Ведь каждый наследник точно "знает", с чем он работает, и может сам обратиться к языковому файлу, чтобы приготовить и записать для себя лэйбл. А метод подготовки меню - просто его вытаскивать и лепить на кнопочку, не приходя в сознание. Но мне этот подход почему-то кажется каким-то "неMVC-шным". Я старался, чтобы на уровне Модели (а создание и подбор вариаций действия - прерогатива Модели, без сомнения) вообще не фигурировали никакие конечные выводимые объекты, будь то тексты или картинки.
2. Добавлять логику в класс подбора фраз. Собственно то, о чём я раньше спрашивал в этой теме. Чтобы некий отдельный метод (или целый Класс) получал ID фразы из Модели (вот тут как раз будет неважно, String или 16х uint или что-то ещё) и по нему выдавал нужную фразу. Здесь главная проблема - это контекст. Как видно из примера (я для этого его так подробно и описывал), может быть много контекстов. Их формализация и передача в метод-посредник - отдельный геморрой с непонятными перспективами.
Застрял я конкретно. Пока не решу, боюсь дальше двигаться, ибо по мере добавления функционала проблема усугубляется. Просьба прокомментировать мои варианты. Спасибо.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.