Добавлен DarkDes,
опубликован
Извиняюсь за не столь содержательный заголовок
ТЕМА: КОД
Генерация предметов
Весьма странно начинать лог разработки не рассказав об игре хотя бы двух слов, да ещё и издалека — предметы и инвентарь.
Будет затронута только программная часть т.е. без графики, а всю информацию будем выводить в консоль. В конце лог-статьи будет приведён код на языке С++.
Будет затронута только программная часть т.е. без графики, а всю информацию будем выводить в консоль. В конце лог-статьи будет приведён код на языке С++.
А теперь приступим :)
Характеристики
Для начала определить структуру предмета необходимо… или же нет?
На самом деле, следует знать зачем эти всякие предметы нужны и на что они влияют, но тут ответ более-менее ясен — характеристики персонажа, но вот что это за характеристики? Это и следует обозначить.
На самом деле, следует знать зачем эти всякие предметы нужны и на что они влияют, но тут ответ более-менее ясен — характеристики персонажа, но вот что это за характеристики? Это и следует обозначить.
// Характеристики
struct sAttributes
{
short health; // Здоровье
short shield; // Щит
short defence; // Оборона (глушитель урона)
short damage; // Урон
};
Если Вам знаком синтаксис языка Cи, то вопросов возникнуть не должно, а для тех кто «не в теме», следует пояснить кое-что, но не углубляться в подробности: (лучше найти информацию в интернете, а то я плохо объясняю)
struct название_структуры
{
тип переменная; // комментарий
};
Теперь у нас есть структура определяющая характеристики.
Можно завести структуру и для персонажа, затем для предмета, но лучше не спешить и немного подумать.
Можно завести структуру и для персонажа, затем для предмета, но лучше не спешить и немного подумать.
Описание предмета
Каждый предмет в игре лучше «зарегистрировать» т.е. записать их в особый список, который будет хранить всю «статичную» информацию о предметах ( характеристики, например ).
А оперировать в инвентаре будем с более простой структурой предмета, которая будет ссылаться на информацию предмета в списке.
А оперировать в инвентаре будем с более простой структурой предмета, которая будет ссылаться на информацию предмета в списке.
// Качество
enum eQuality
{
EQ_COMMON =0, // Обычный
EQ_STANDARD =1, // Стандартный (в чём отличие от обычного?)
EQ_HANDMADE, // Самопальный
EQ_LEGENDARY, // Легендарный
EQ_EPIC, // Эпичный
Count_Quiality // так узнаем кол-во
};
// Тип предмета, если установлен в OTHER, то может быть произвольный
enum eKind // TYPE
{
Kind_WEAPON = 0, // Оружие
Kind_ARMOR, // Броня
//Kind_POTION,
Kind_OTHER
};
// Бит-флаги предмета
enum eItemFlag
{
IF_CLEAR = 0x0000,
IF_EQUIP = 0x0001, // Можно экипировать
IF_COLLECTABLE = 0x0002, // Занимает один слот, записывая кол-во
IF_USABLE = 0x0004, // Можно использовать
IF_QUEST = 0x0008 // Предмет, необходимый по сюжету\квесту (нельзя выбросить, слот не учитывается)
};
// Описание предмета для глобального списка
struct sItemDescription
{
// Уникальный ID
unsigned long ID;
string name; // название предмета для отображения
string desc; // описание
sAttributes attrib;
eQuality qual; // качество
eKind kind; // тип
long falgs; // бит-флаги
// Визуальная информация
int modelID; // номер 3Д модели
int textureID; // номер текстуры для 3Д модели
int pictureID; // номер картинки\текстуры\иконки для отображения в инвентаре
// Цена предмета, можно задать вручную или же воспользоваться специальной функцией
int cost;
};
- Эй! Что такое unsigned long, string и eQuality ?
unsigned означает, что наша переменная имеет исключительно положительное значение (для целочисленных типов).
long - аналогично как и short, однако, занимает больше памяти и следовательно может иметь больше значений.
string - тип описывающий строку текста (из стандартной C++ библиотеки).
eQuality и eKind - перечисления.
unsigned означает, что наша переменная имеет исключительно положительное значение (для целочисленных типов).
long - аналогично как и short, однако, занимает больше памяти и следовательно может иметь больше значений.
string - тип описывающий строку текста (из стандартной C++ библиотеки).
eQuality и eKind - перечисления.
Код, возможно, кого-то испугает, но на самом деле всё очень просто.
Мы имеем структуру описания предмета - это означает, что используя этот "бланк" можно будет обозначить любой предмет в игре.
Вот пример такого определения:
Мы имеем структуру описания предмета - это означает, что используя этот "бланк" можно будет обозначить любой предмет в игре.
Вот пример такого определения:
sItemDescription SuperSword;
SuperSword.ID = CurID++; // Для каждого предмета считается свой ID
SuperSword.name = "Супер меч";
SuperSword.desc = "Лишь избранный может нести его";
SuperSword.attrib.health = 0;
SuperSword.attrib.shield = 0;
SuperSword.attrib.defence = 0;
SuperSword.attrib.damage = 20;
SuperSword.kind = Kind_WEAPON; // Тип "оружие"
SuperSword.qual = EQ_LEGENDARY; // Качество предмета как "Легендарный"
SuperSword.falgs = IF_EQUIP; // можно экипировать
SuperSword.cost = ItemCost( SuperSword ); // Вычислим стоимость предмета
И это очень простой предмет, а представьте если их, скажем, 20 .. это же жуть их так все описывать, поэтому напрашивается идея генерации этих самых предметов. Разумеется представленный мой способ не очень, но надо же начать с чего-то :)
Генератор
Это функция, принимающая в качестве аргумента требования к процедурному предмету (смотри ниже).
sItemDescription GenerateItem( const sItemGenerationDesc &gendesc )
{
sItemDescription desc;
desc.ID = CurID++;
desc.kind = gendesc.kind;
desc.qual = gendesc.quality;
desc.attrib.health = 0;
desc.attrib.defence = 0;
desc.attrib.damage = 0;
desc.attrib.shield = 0;
if( desc.kind == Kind_WEAPON )
{
desc.name = QualityToString(desc.qual) + " " + weapons_names[ RandomRange(0,weapons_names_count) ];
// Лихо рассчитываем параметр используя качество, начальное значение и великий рандом
desc.attrib.damage = gendesc.attribs_ranges.damage + ((int)desc.qual) * RandomRange( 0, 4 );
desc.falgs = IF_EQUIP;
}else
if( desc.kind == Kind_ARMOR )
{
desc.name = QualityToString(desc.qual) + " " + armor_names[ RandomRange(0,armor_names_count) ];
desc.attrib.shield = gendesc.attribs_ranges.shield + ((int)desc.qual) * RandomRange( 0, 2 );
desc.attrib.defence = gendesc.attribs_ranges.defence + RandomRange( 0, 2 );
desc.falgs = IF_EQUIP;
}
desc.cost = ItemCost( desc ); // Вычисляем цену
desc.desc = "Этот предмет сгенерирован программой"; // описание описания, извините за тавтологию
return desc;
}
А что-то за структура sItemGenerationDesc ?
struct sItemGenerationDesc
{
eQuality quality; // Качество, которое мы хотим дать предмету
eKind kind; // Тип предмета - оружие, броня или может ещё что
sAttributes attribs_ranges; // Разброс по атрибутам или их начальное значение
};
Таким образом, можно манипулируя тремя параметрами получить различные предметы.
Должен заметить, что с названием предметов есть неприятный момент, например, такой - "ЭПИЧНЫЙ труба" ... такое можно исправить, но это уже на будущее :)
Должен заметить, что с названием предметов есть неприятный момент, например, такой - "ЭПИЧНЫЙ труба" ... такое можно исправить, но это уже на будущее :)
Вот скриншот с консоли программы, демонстрирующие генератор предметов:
Можно скачать код или посмотреть.
Безусловно этот код изменится, ведь данная программа больше написана для тестирования.
Это первая статья из цикла, поэтому принимаю различные предложения по улучшению подачи контента )
Хотелось бы разрабатывать игру не просто для себя, а совместно с сообществом.
Хотелось бы разрабатывать игру не просто для себя, а совместно с сообществом.
Что дальше?
На радаре концепт арты врагов! Если не терпится посмотреть на них, то можете разыскать их на сайте стопгейм.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Я больше про что-то вроде pygame или slick2d говорил. Я на первом за 8 часов написал топдаун игру, из них 4 часа на освоение языка и движка
Просто не привык к готовым библиотекам ) Это конечно хорошо, когда есть какие-то основа, а не голый ЯП. Кто знает, возможно, возьму какое-нибудь готовое решение.
но на счёт юнити ты прав