[Лог #1] Немного кода.

Добавлен , опубликован
Извиняюсь за не столь содержательный заголовок

ТЕМА: КОД

Генерация предметов

Весьма странно начинать лог разработки не рассказав об игре хотя бы двух слов, да ещё и издалека — предметы и инвентарь.
Будет затронута только программная часть т.е. без графики, а всю информацию будем выводить в консоль. В конце лог-статьи будет приведён код на языке С++.
А теперь приступим :)

Характеристики

Для начала определить структуру предмета необходимо… или же нет?
На самом деле, следует знать зачем эти всякие предметы нужны и на что они влияют, но тут ответ более-менее ясен — характеристики персонажа, но вот что это за характеристики? Это и следует обозначить.
// Характеристики
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 - перечисления.
Код, возможно, кого-то испугает, но на самом деле всё очень просто.
Мы имеем структуру описания предмета - это означает, что используя этот "бланк" можно будет обозначить любой предмет в игре.
Вот пример такого определения:
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; 	// Разброс по атрибутам или их начальное значение
};
Таким образом, можно манипулируя тремя параметрами получить различные предметы.
Должен заметить, что с названием предметов есть неприятный момент, например, такой - "ЭПИЧНЫЙ труба" ... такое можно исправить, но это уже на будущее :)
Вот скриншот с консоли программы, демонстрирующие генератор предметов:
Можно скачать код или посмотреть.
Безусловно этот код изменится, ведь данная программа больше написана для тестирования.
Это первая статья из цикла, поэтому принимаю различные предложения по улучшению подачи контента )
Хотелось бы разрабатывать игру не просто для себя, а совместно с сообществом.

Что дальше?

На радаре концепт арты врагов! Если не терпится посмотреть на них, то можете разыскать их на сайте стопгейм.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
15
9 лет назад
0
PhysCraft:
Генератор будет меняться, спасибо за некоторые идеи )
Да, вся игра будет на Си++.
Doc:
Писать игры на с++ канеш смело (и глупо имхо), движок для графона уже подобрал?
Ну это кому как) Графон? Не не гонюсь за супер графикой, всё что будет необходимо проекту можно написать самому - это же весело! Эксперименты и всякое такое )
lentinant:
Интересно, надо будет это запомнить)
nvc123:
Я старался показать более простой код. Решил попробовать метод "сделай проще", зачем мне вся мощь ООП, если я её использовать не буду?
Порядок функций, как заметил Praytic , решается прототипами функций в заголовочном файле.
Слабоумие и отвага - двигатель прогресса!
А то! :)
0
29
9 лет назад
Отредактирован Doc
0
Не, я наверное неправильно выразился частично, в голове одно, а пишу слегка другое. Писать МАЛЕНЬКИЕ/инди игры на С++ - глупо, как я считаю. Это просто не нужно, больше борьбы с инструментом, чем собственно делания игры. И я уверен, те кто пишут на С++ игры, даже не представляют, что это совсем не то, что делают большие компании. Посмотрите видео, где человек из Ubisoft объясняет, как они используют С++ в продакшне. Никаких эксцепшнов, шаблонов, буста и прочего. Вот эти ребята гонятся за производительностью. А зачем другие люди пишут на С++ мне не понятно :3 Очень забавно, что меня минусанул Denj, который тут вроде с 2012 года или вроде и все это время разрабатывал свой крутой модный очередной движок на С++ и в итоге где-то к 2015 подобрался все-таки к написанию игры на нем. Об этом я и говорил, no offense. Другое дело Kozinaka, у него по-крайней мере есть игра, первый раз такое вижу, хотя вроде тоже много времени прошло.
0
14
9 лет назад
0
Doc, для разработчика с нулевым опытом, безусловно, С++ не лучший выбор. Но бэкграунд сильно меняет дело - мне юнити осваивать дольше, чем накидать прототип игрухи пользуясь своими старыми велосипедами. Каждый делает свой выбор исходя из своих условий.
0
29
9 лет назад
Отредактирован Doc
0
Kozinaka, с этим никак не поспорить, квалифицированный разработчик, прекрасно знающий свой инструмент, использует его как угодно и где угодно лучше, чем что-то незнакомое, пусть и более подходящее для конкретной задачи.
4
14
9 лет назад
4
Мне кажется С++ уже так разросся, то используют его только те, кто начал его изучать, когда он был ещё маленький, остальных он отпугивает. Впрочем, буду рад ошибаться.
2
15
9 лет назад
2
Писать МАЛЕНЬКИЕ/инди игры на С++ - глупо
Возможно ты прав. Я хоть этот язык знаю не на 100%, но я привык к нему и предпочту использовать его :)
Согласен с Kozinaka осваивать сторонний движок - долго, да ещё начинаешь зависеть от него( ограничения ), а вот когда своё написал, то и принципы работы принял, получил опыт, и можешь крутить-вертеть свой двиг\фреймворк\игру как хочешь )
Имхо, готовые движки вроде Юнити подходят для прототипирования игр т.к. эти самые движки накладывают ограничения.
0
29
9 лет назад
0
Ну ты загнул прям, юнити.
Я больше про что-то вроде pygame или slick2d говорил. Я на первом за 8 часов написал топдаун игру, из них 4 часа на освоение языка и движка
0
15
9 лет назад
0
Doc:
Просто не привык к готовым библиотекам ) Это конечно хорошо, когда есть какие-то основа, а не голый ЯП. Кто знает, возможно, возьму какое-нибудь готовое решение.
0
14
9 лет назад
0
DarkDes, правда обычно где-то посередине. Любое готовое решение диктует свои правила и ограничивает тебя, но при этом экономит силы и время. Важно найти баланс между велосипедированием и проклинанием чужих кривых рук. Я использую движок Lua для скриптов, библиотеку TinyXml для работы с Xml, BASS для работы со звуком и т.д. - при контроле за главным (графический движок самопальный, я его часто кручу под свои нужды), тонкости реализации вещей, в которых я плохо разбираюсь, я перекладываю на сторонние библиотечки. Мне нравится. :)
0
26
9 лет назад
0
Имхо, готовые движки вроде Юнити подходят для прототипирования игр т.к. эти самые движки накладывают ограничения.
А можно мне послушать, какие ограничения накладывает Юнити?
0
15
9 лет назад
0
какие ограничения накладывает Юнити?
Рендер в текстуру, и следовательно различные пост-процессы. Больше ограничений назовут те, кто дольше с юнити работал.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.